1. Intel的X86系统是little-endian,
>> cat endian.c #include <stdio.h> int main() { int a = 'A'; printf("%s/n", &a); } >> ./a.out A
2. 代码如下:
>> cat stackdemo.c #include<stdio.h> void fun(){ printf(">_</n"); printf("/n"); } int main(int argc,char **argv){ char buf[10]; int *p; char *c; int i = 0; memset(buf, 0, 48); p = fun; c = (char*)&p; for ( i = 0; i < 8; i++) { buf[40+i] = c[i]; } printf("buf address is 0x%8x/n", &buf); printf("fun address is 0x%8x/n", fun); return 0; }
运行结果如下:
>> cc -g2 stackdemo.c stackdemo.c: In function `main': stackdemo.c:15: warning: assignment from incompatible pointer type >> ./a.out buf address is 0x4787bb30 fun address is 0x 4004c8 >_< buf address is 0x4787ba70 fun address is 0x 4004c8 >_< Memory fault(coredump)
在高的GCC版本,如果运行的时候报“*** stack smashing detected ***, 那是因为你的系统默认使用了GCC的“ -fstack-protector"参数导致的,我们只需要在编译的时候 export CFLAGS="-fno-stack-protector"就好。
>> gdb ./a.out GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu"... (gdb) list 2 void fun(){ 3 printf(">_</n"); 4 printf("/n"); 5 } 6 7 int main(int argc,char **argv){ 8 char buf[10]; 9 int *p; 10 char *c; 11 int i = 0; (gdb) 12 13 memset(buf, 0, 48); 14 15 p = fun; 16 c = (char*)&p; 17 for ( i = 0; i < 8; i++) 18 { 19 buf[40+i] = c[i]; 20 } 21 (gdb) 22 printf("buf address is 0x%8x/n", &buf); 23 printf("fun address is 0x%8x/n", fun); 24 return 0; 25 } (gdb) br 24 Breakpoint 1 at 0x40057c: file stackdemo.c, line 24. (gdb) r Starting program: /local/c/a.out buf address is 0x64fbb220 fun address is 0x 4004c8 Breakpoint 1, main (argc=0, argv=0x0) at stackdemo.c:24 24 return 0; (gdb) i r rax 0x1a 26 rbx 0x7fbf5cfbcc00 140459875486720 rcx 0x7fbf5cd99780 140459873245056 rdx 0x7fbf5cd9a9a0 140459873249696 rsi 0x7fbf5cfb6000 140459875459072 rdi 0x1 1 rbp 0x7fff64fbb240 0x7fff64fbb240 rsp 0x7fff64fbb200 0x7fff64fbb200 r8 0xffffffff 4294967295 r9 0x7fbf5cb5b5c0 140459870893504 r10 0x0 0 r11 0x246 582 r12 0x0 0 r13 0x7fff64fbb320 140734887605024 r14 0x0 0 r15 0x0 0 rip 0x40057c 0x40057c <main+144> eflags 0x202 [ IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 fctrl 0x37f 895 fstat 0x0 0 ftag 0xffff 65535 fiseg 0x0 0 fioff 0x0 0 foseg 0x0 0 fooff 0x0 0 fop 0x0 0 mxcsr 0x1f80 [ IM DM ZM OM UM PM ] (gdb) x/64 0x7fff64fbb200 0x7fff64fbb200: 0x5cd95778 0x00007fbf 0x004005e5 0x00000008 0x7fff64fbb210: 0x64fbb218 0x00007fff 0x004004c8 0x00000000 0x7fff64fbb220: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fff64fbb230: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fff64fbb240: 0x00000000 0x00000000 0x004004c8 0x00000000 0x7fff64fbb250: 0x00400410 0x00000000 0x64fbb328 0x00007fff 0x7fff64fbb260: 0x00000000 0x00000001 0x004004ec 0x00000000 0x7fff64fbb270: 0x5cfbcc00 0x00007fbf 0x834c91aa 0x4ada9af4 0x7fff64fbb280: 0x00000000 0x00000000 0x64fbb320 0x00007fff 0x7fff64fbb290: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fff64fbb2a0: 0xe7ec91aa 0xb5245303 0xe1b291aa 0xb5a423bf 0x7fff64fbb2b0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fff64fbb2c0: 0x00000000 0x00000000 0x004005a0 0x00000000 0x7fff64fbb2d0: 0x64fbb328 0x00007fff 0x00000001 0x00000000 0x7fff64fbb2e0: 0x00000000 0x00000000 0x00000000 0x00000000 0x7fff64fbb2f0: 0x00400410 0x00000000 0x64fbb320 0x00007fff
注意:
1. ESP的值总是对的
2. 0x7fff64fbb210: 0x64fbb218 0x00007fff 0x004004c8 0x00000000
地址为“0x00007fff64fbb218”,小端系统,高位在高地址。