10

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.

result on X86 with openSuse 12.1

##> 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)

result on x86_64 with openSuse 11.3

##> 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

mattjgalloway
  • 34,792
  • 12
  • 100
  • 110
Jorn De Pril
  • 191
  • 1
  • 1
  • 7
  • I think x86_64 uses %rip, also gcc adds padding to the stack to prevent this, try using -fno-stack-protector. –  Dec 08 '11 at 15:12
  • 1
    there's no overflow on eip/rip. The registers have fixed size and you cannot copy anything to eip/rip so you can't "overflow" it. What was overflowed is memory – phuclv Dec 28 '13 at 00:57

2 Answers2

18

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.

Jason
  • 31,834
  • 7
  • 59
  • 78
  • 1
    If you want to compile it as 32-bit, you need to have `libc6-dev-i386` installed. Otherwise you get `fatal error: sys/cdefs.h: No such file or directory` – Jemshit Oct 10 '15 at 19:18
1
  1. 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.

  2. Again, you'd have different a different message on 64bit code only.

  3. 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.

  4. 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.

JosephH
  • 8,465
  • 4
  • 34
  • 62