Don't like this style? Click here to change it! blue.css
Of course when you call a function you want to pass arguments too, right?
So let's look at how that works in the 2 different paradigms:
This is actually pretty easy.
If your function needs arguments it knows to find them in the registers
That's it. I don't even really memorize these, just remember that it's registers and google/wikipedia until I find the list. OK maybe I know the first 3 by memory, RDI, RSI, RDX isn't so hard to just know.
If you have more than 6 arguments then they are stored in the stack just like the 32-bit case (coming next).
Step through this 64-bit binary: addme
In the 32-bit case (or 64-bit for arguments over 6) it checks the stack:
So if you imagine the stack, the arguments live TO THE RIGHT OF the return address.
In practice that means that the calling convention looks like this:
Now to make 32-bit binaries you'll want to do some installing:
Make a 32-bit binary: install
apt-get install gcc-multilib
then add the -m32 flag to your compilation:
gcc -m32 -o bin_name source_code.c
OK let's make programs with parameters that call each other and trace what happens and make predictions and such.
Step through this 32-bit binary: addme32
I won't dive into these just yet but you should just be aware that a couple other calling conventions exist out there for other situations.
These are passed in the stack but offset by a little, so inspect and test. This is just for main.
I'm going to do a whole lecture or two on syscalls, but for now you can summarize it like this: anything that is operating system/kernel level you do through a syscall. That is, access to the filesystem, making new memory segments, starting/stopping processes, etc.
The syscall is it's own instruction that uses the
rax register to dictate what type of syscall you're doing and the other registers hold the other params.
In the 32-bit case it's the interrupt instruction
int 0x80 then a similar structure.
When there is an interrupt sometimes the entire register set is stored on the stack to let you resume after calling the error handler or what have you. We will exploit this later (it's called SROP).
Here are some calling convention and reversing examples: