Reputation: 191
Let me skip introduction and jump to the good part. I am reading 'Ethical Hackers Handbook' and trying some example code (around p175).
Goal : overflow the EIP in the stack
Example Code :
##> cat overflow.c
main(){
char str1[10]; // declare a 10byte string
// next, copy 35 bytes of 'A' to 'str1'
strcpy(str1,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}
If I compile & run it on my x86 Laptop, then the outcome is as expected.
##> uname -a
Linux linux-tzxm.site 3.1.0-1.2-desktop #1 SMP PREEMPT
Thu Nov 3 14:45:45 UTC 2011 (187dde0) i686 i686 i386 GNU/Linux
##> cat /proc/sys/kernel/randomize_va_space
1
##> gcc version 4.6.2 (SUSE Linux)
##> GNU gdb (GDB) SUSE (7.3-41.1.2)
##> gdb -q overflow
Reading symbols from /home/administrator/Programming/C/testProgs/overflow...done.
(gdb) run
Starting program: /home/administrator/Programming/C/testProgs/overflow
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg eip
eip 0x41414141 0x41414141
However, if i do the same on my x86_64 laptop, then the outcome is different and not as expected (from my little knowledge point of view)
##> uname -a
Linux linux-2mna.site 2.6.34.10-0.4-desktop #1 SMP PREEMPT 2011-10-19 22:16:41 +0200 x86_64 x86_64 x86_64 GNU/Linux
##> cat /proc/sys/kernel/randomize_va_space
1
##> gcc version 4.5.0 20100604
##> GNU gdb (GDB) SUSE (7.1-3.12)
##> gdb -q overflow2
Reading symbols from /home/jojojorn/Documents/Personal/HACKING/C_Prog/Tests/testProgs/overflow2...done.
(gdb) run
Starting program: /home/jojojorn/Documents/Personal/HACKING/C_Prog/Tests/testProgs/overflow2
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400553 in main () at overflow.c:11
11 }
(gdb) info reg eip
Invalid register `eip'
(gdb)
So here are my questions :
1) why I cannot overflow the EIP on my stack on my x86_64 ? Is there a difference in stack behaviour between x86_64 and x86 ?
2) when i run the x86 compiled binary on my x86_64 and check with gdb, then the outcome is again as expected. So I assume the difference is made using gcc 32 bit and gcc 64 bit ? For this easy code, what is and why is there a difference ?
3) If i want my code on x86_64 to behave as it was compiled on x86, is there a gcc parameter to set at compilation time ?
4) I ask this question, which means i do not yet have the proper knowledge to ask better questions. Is there something extra that comes into your genius minds that i have should asked (and which you would have answered) ?
Sincerely
Upvotes: 10
Views: 10645
Reputation: 8815
It's not that there's no overflow on x86_64, it's just a different way of presenting exception. Instead of actually telling you that it was unable to execute the code 0x4141414141414141 after it actually updated rip
, it's telling you that the destination address is invalid before updating. This is an architectural difference between x86 code and x86_64 code and whenever you're executing a 64bit code, that's how it is handled.
Again, you'd have different a different message on 64bit code only.
You'd have to compile it as 32bit code. There's no way to get the same message if you were to compile it as x86_64 code.
It's actually not difficult to notice this difference if you were to properly debug the code and see where rip
is pointing to and the values of other registers.
Upvotes: 1
Reputation: 32520
On x86_64, the instruction pointer is RIP
, not EIP
... thus if you query the EIP
register in gdb
with a 64-bit executable, you're not going to get any values since that's not a valid 64-bit register. If you are wanting to keep your executable as 32-bit on a native 64-bit platform, then pass gcc
the -m32
flag at compile-time.
If you are wanting to see how the x86_64 Unix stack behaves compared to the x86 Unix stack, then I suggest reading the x86_64 Unix ABI, sections 3.2 and 3.4.
Upvotes: 18