反汇编调试简单程序笔记

来源:互联网 发布:网络语666 编辑:程序博客网 时间:2024/06/10 03:51
<< 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 mainDump of assembler code for function main://现在esp的值就是main()函数的返回地址//(gdb) x/x $esp//0xbff1ed1c:     0x009a53900x080483c4 <main+0>:    lea    0x4(%esp),%ecx                // 把 esp+4 -> ecx        esp: 0xbff1ed1c//(gdb) i reg $esp $ecx//esp            0xbff1ed1c       0xbff1ed1c//ecx            0xbff1ed20       -10746641600x080483c8 <main+4>:    and    $0xfffffff0,%esp                // ?? esp:  0xbf887680//(gdb) i reg $esp//esp            0xbff1ed10       0xbff1ed100x080483cb <main+7>:    pushl  0xfffffffc(%ecx)                // ecx-4,pushl压栈 ??//esp            0xbff1ed0c       0xbff1ed0c//ecx            0xbff1ed20       -10746641600x080483ce <main+10>:   push   %ebp    //esp            0xbff1ed08       0xbff1ed08//ebp            0xbff1ed78       0xbff1ed780x080483cf <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:     0xbff1ed780x080483d1 <main+13>:   push   %ecx                            // ecx:0xbff1ed20(这个值是main函数的返回地址+4)压栈   esp 0xbf887678//(gdb) i reg $esp $ecx//esp            0xbff1ed04       0xbff1ed04//ecx            0xbff1ed20       -10746641600x080483d2 <main+14>:   sub    $0x24,%esp                        //smallbuf[16]分配 32b 的空间前 esp 0xbff1ece0//(gdb) i reg $esp//esp            0xbff1ece0       0xbff1ece0//(gdb) x/x $esp//0xbff1ece0:     0x00ae3ff40x080483d5 <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      0x00ae3ff40x080483dd <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:     0xbff1edac0x080483e0 <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:     0xbff1edac0x080483e3 <main+31>:   call   0x80482dc <strcpy@plt>/*(gdb) i regeax            0xbff1ecf4       -1074664204ecx            0xb7ed56b4       -1209182540ebx            0xae3ff4 11419636esp            0xbff1ece0       0xbff1ece0ebp            0xbff1ed08       0xbff1ed08eip            0x80483e8        0x80483e8 <main+36>(gdb) x/x $esp0xbff1ece0:     0xbff1ecf4(gdb) x/20x $esp0xbff1ece0:     0xbff1ecf4      0x08049640      0xbff1ed18      0x08048429            //执行完call以后,esp指针还会做 add $0x24,%esp,now $esp is0xbff1ecf0:     0x009bb6c5      0x34333231      0x38373635      0x34333231            //0xbff1ece0,when it 做完加法后是 0xbff1ed04,这个地址相对于0xbff1ed00:     0x0097e900      0xbff1ed20      0xbff1ed78      0x009a5390            //&smallbuf 0xbff1ecf4偏移是16 ,所以只应该填充16字节。0xbff1ed10:     0x0098bca0      0x08048410      0xbff1ed78      0x009a53900xbff1ed20:     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      0x000000010x080483eb <main+39>:   pop    %ecx/*(gdb) i regeax            0xbff1ecf4       -1074664204ecx            0xbff1ed20       -1074664160esp            0xbff1ed08       0xbff1ed08ebp            0xbff1ed08       0xbff1ed08eip            0x80483ec        0x80483ec <main+40>(gdb) x/20x $esp0xbff1ed08:     0xbff1ed78      0x009a5390      0x0098bca0      0x080484100xbff1ed18:     0xbff1ed78      0x009a5390      0x00000001      0xbff1eda40xbff1ed28:     0xbff1edac      0x0098c810      0x00000000      0x000000010xbff1ed38:     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      0xbff1eda40x080483ed <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      0xbff1edac0x080483f0 <main+44>:   ret  /*(gdb) i regeax            0xbff1ecf4       -1074664204ecx            0xbff1ed20       -1074664160edx            0x804964d        134518349ebx            0xae3ff4 11419636esp            0xbff1ed1c       0xbff1ed1cebp            0xbff1ed78       0xbff1ed78esi            0x98bca0 10009760edi            0x0      0eip            0x80483f0        0x80483f0 <main+44>所以,这里我们覆盖不到main函数的返回地址了,但是我们能把0xbff1ed04这个地址的值给覆盖掉, 在这里注入我们的“流程”(shellcode)一样可以实现覆盖main函数返回地址一样的效果。*/