<< Smashing The Stack For Fun And Profit >> http://www.cs.wright.edu/~tkprasad/courses/cs781/alephOne.html ---------------------------------------------------------------- //sample.c #include <stdio.h> #include <string.h> char largebuff[] = "12341234===ABCD"; int main (void) { char smallbuff[16]; strcpy (smallbuff, largebuff); } # gdb sample ------------------------------------------------- (gdb) disass main Dump of assembler code for function main: //现在esp的值就是main()函数的返回地址 //(gdb) x/x $esp //0xbff1ed1c: 0x009a5390 0x080483c4 <main+0>: lea 0x4(%esp),%ecx // 把 esp+4 -> ecx esp: 0xbff1ed1c //(gdb) i reg $esp $ecx //esp 0xbff1ed1c 0xbff1ed1c //ecx 0xbff1ed20 -1074664160 0x080483c8 <main+4>: and $0xfffffff0,%esp // ?? esp: 0xbf887680 //(gdb) i reg $esp //esp 0xbff1ed10 0xbff1ed10 0x080483cb <main+7>: pushl 0xfffffffc(%ecx) // ecx-4,pushl压栈 ?? //esp 0xbff1ed0c 0xbff1ed0c //ecx 0xbff1ed20 -1074664160 0x080483ce <main+10>: push %ebp //esp 0xbff1ed08 0xbff1ed08 //ebp 0xbff1ed78 0xbff1ed78 0x080483cf <main+11>: mov %esp,%ebp // (gdb) i reg $esp $ebp //esp 0xbff1ed08 0xbff1ed08 //ebp 0xbff1ed08 0xbff1ed08 //(gdb) x/x $esp //0xbff1ed08: 0xbff1ed78 //(gdb) x/x $ebp //0xbff1ed08: 0xbff1ed78 0x080483d1 <main+13>: push %ecx // ecx:0xbff1ed20(这个值是main函数的返回地址+4)压栈 esp 0xbf887678 //(gdb) i reg $esp $ecx //esp 0xbff1ed04 0xbff1ed04 //ecx 0xbff1ed20 -1074664160 0x080483d2 <main+14>: sub $0x24,%esp //smallbuf[16]分配 32b 的空间前 esp 0xbff1ece0 //(gdb) i reg $esp //esp 0xbff1ece0 0xbff1ece0 //(gdb) x/x $esp //0xbff1ece0: 0x00ae3ff4 0x080483d5 <main+17>: movl $0x8049660,0x4(%esp) // 把0x8049660(&largebuf地址)装入esp+4的地址中,替换esp+4里面的值 esp:0xbff1ece0 // (gdb) i reg $esp //esp 0xbff1ece0 0xbff1ece0 //(gdb) x/x $esp //0xbff1ece0: 0x00ae3ff4 //(gdb) x/8x $esp //0xbff1ece0: 0x00ae3ff4 0x08049640 0xbff1ed18 0x08048429 //0xbff1ecf0: 0x009bb6c5 0xbff1edac 0xbff1ed18 0x00ae3ff4 0x080483dd <main+25>: lea 0xffffffec(%ebp),%eax //(gdb) i reg $ebp $eax //ebp 0xbff1ed08 0xbff1ed08 //eax 0xbff1ecf4 -1074664204 //(gdb) x/x $ebp //0xbff1ed08: 0xbff1ed78 //(gdb) x/x $eax //0xbff1ecf4: 0xbff1edac 0x080483e0 <main+28>: mov %eax,(%esp) // 这里等于是将eax压栈 //(gdb) i reg $eax $esp //eax 0xbff1ecf4 -1074664204 //esp 0xbff1ece0 0xbff1ece0 //(gdb) x/x $esp //0xbff1ece0: 0xbff1ecf4 //(gdb) x/x $eax //0xbff1ecf4: 0xbff1edac 0x080483e3 <main+31>: call 0x80482dc <strcpy@plt> /* (gdb) i reg eax 0xbff1ecf4 -1074664204 ecx 0xb7ed56b4 -1209182540 ebx 0xae3ff4 11419636 esp 0xbff1ece0 0xbff1ece0 ebp 0xbff1ed08 0xbff1ed08 eip 0x80483e8 0x80483e8 <main+36> (gdb) x/x $esp 0xbff1ece0: 0xbff1ecf4 (gdb) x/20x $esp 0xbff1ece0: 0xbff1ecf4 0x08049640 0xbff1ed18 0x08048429 //执行完call以后,esp指针还会做 add $0x24,%esp,now $esp is 0xbff1ecf0: 0x009bb6c5 0x34333231 0x38373635 0x34333231 //0xbff1ece0,when it 做完加法后是 0xbff1ed04,这个地址相对于 0xbff1ed00: 0x0097e900 0xbff1ed20 0xbff1ed78 0x009a5390 //&smallbuf 0xbff1ecf4偏移是16 ,所以只应该填充16字节。 0xbff1ed10: 0x0098bca0 0x08048410 0xbff1ed78 0x009a5390 0xbff1ed20: 0x00000001 0xbff1eda4 0xbff1edac 0x0098c810 0x44434241之所以他会变成0x4443423d,因为在0xbff1ed04中的0xbff1ed20这个值在后面会减去4.我们填充16字节,正好能覆盖0xbff1ed04,这时(填充后)0xbff1ed04中的值是0x44434241.而0xbff1ed20-4(0xfffffffc(%ecx))正好能退回到0xbff1ed1c,main()函数的返回地址,而0xbff1ed04中的值是0x44434241减去4就变成了0x4443423d. */ 0x080483e8 <main+36>: add $0x24,%esp //(gdb) x/x $esp //0xbff1ed04: 0xbff1ed20 //(gdb) x/20x $esp //0xbff1ed04: 0xbff1ed20 0xbff1ed78 0x009a5390 0x0098bca0 //0xbff1ed14: 0x08048410 0xbff1ed78 0x009a5390 0x00000001 0x080483eb <main+39>: pop %ecx /*(gdb) i reg eax 0xbff1ecf4 -1074664204 ecx 0xbff1ed20 -1074664160 esp 0xbff1ed08 0xbff1ed08 ebp 0xbff1ed08 0xbff1ed08 eip 0x80483ec 0x80483ec <main+40> (gdb) x/20x $esp 0xbff1ed08: 0xbff1ed78 0x009a5390 0x0098bca0 0x08048410 0xbff1ed18: 0xbff1ed78 0x009a5390 0x00000001 0xbff1eda4 0xbff1ed28: 0xbff1edac 0x0098c810 0x00000000 0x00000001 0xbff1ed38: 0x00000001 0x00000000 0x00ae3ff4 0x0098bca0 */ 0x080483ec <main+40>: pop %ebp //(gdb) i reg $esp $ebp //esp 0xbff1ed08 0xbff1ed08 //ebp 0xbff1ed08 0xbff1ed08 //(gdb) x/x $esp //0xbff1ed08: 0xbff1ed78 //(gdb) x/x $ebp //0xbff1ed08: 0xbff1ed78 //(gdb) x/20x $esp //0xbff1ed08: 0xbff1ed78 0x009a5390 0x0098bca0 0x08048410 //0xbff1ed18: 0xbff1ed78 0x009a5390 0x00000001 0xbff1eda4 0x080483ed <main+41>: lea 0xfffffffc(%ecx),%esp $ecx里面的值减4,传递给esp //(gdb) i reg $ecx $esp //ecx 0xbff1ed20 -1074664160 //esp 0xbff1ed0c 0xbff1ed0c //(gdb) x/20x $esp //0xbff1ed0c: 0x009a5390 0x0098bca0 0x08048410 0xbff1ed78 //0xbff1ed1c: 0x009a5390 0x00000001 0xbff1eda4 0xbff1edac 0x080483f0 <main+44>: ret /* (gdb) i reg eax 0xbff1ecf4 -1074664204 ecx 0xbff1ed20 -1074664160 edx 0x804964d 134518349 ebx 0xae3ff4 11419636 esp 0xbff1ed1c 0xbff1ed1c ebp 0xbff1ed78 0xbff1ed78 esi 0x98bca0 10009760 edi 0x0 0 eip 0x80483f0 0x80483f0 <main+44> 所以,这里我们覆盖不到main函数的返回地址了,但是我们能把0xbff1ed04这个地址的值给覆盖掉, 在这里注入我们的“流程”(shellcode)一样可以实现覆盖main函数返回地址一样的效果。 */
反汇编调试简单程序笔记
最新推荐文章于 2023-01-20 00:04:12 发布