I came across this piece of code (for the whole program see this page, see the program named "srop.c").
My question is regarding how func
is used in the main
method. I have only kept the code which I thought could be related.
It is the line *ret = (int)func +4;
that confuses me.
There are three questions I have regarding this:
func(void)
is a function, should it not be called withfunc()
(note the brackets)- Accepting that that might be some to me unknown way of calling a function, how can it be casted to an
int
when it should returnvoid
? - I understand that the author doesn't want to save the frame pointer nor update it (the prologue), as his comment indicates. How is this skipping-two-lines ahead achieved with casting the function to an
int
and adding four?
.
(gdb) disassemble func
Dump of assembler code for function func:
0x000000000040069b <+0>: push %rbp
0x000000000040069c <+1>: mov %rsp,%rbp
0x000000000040069f <+4>: mov $0xf,%rax
0x00000000004006a6 <+11>: retq
0x00000000004006a7 <+12>: pop %rbp
0x00000000004006a8 <+13>: retq
End of assembler dump.
Possibly relevant is that when compiled gcc tells me the following:
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
Please see below for the code.
void func(void)
{
asm("mov $0xf,%rax\n\t");
asm("retq\n\t");
}
int main(void)
{
unsigned long *ret;
/*...*/
/* overflowing */
ret = (unsigned long *)&ret + 2;
*ret = (int)func +4; //skip gadget's function prologue
/*...*/
return 0;
}
[Edit] Following the very helpful advice, here are some further information:
calling func returns a pointer to the start of the function: 0x400530
casting this to an int is dangerous (in hex) 400530
casting this to an int in decimal 4195632
safe cast to unsigned long 4195632
size of void pointer: 8
size of int: 4
size of unsigned long: 8
[Edit 2:] @cmaster: Could you please point me to some more information regarding how to put the assembler function in a separate file and link to it? The original program will not compile because it doesn’t know what the function prog
(when put in the assembler file) is, so it must be added either before or during compilation?
Additionally, the gcc -S
when ran on a C file only including the assembly commands seem to add a lot of extra information, could not func(void)
be represented by the following assembler code?
func:
mov $0xf,%rax
retq