这是在VC下编译的,也是利用VC中调试工具DEBUG查看到源程序的汇编代码.

如果是反汇编,结构和此处的几乎一样,就没有了源代码(粗体)。

文件从00401001处开始
从main函数开始分析(main函数位于内存00401090处)

00401001   int         3
00401002   int         3
00401003   int         3
00401004   int         3

@ILT+0(?verify_password@@YAHPAD@Z):
00401005   jmp         verify_password (00401020)
@ILT+5(_main):
0040100A   jmp         main (00401090)
0040100F   int         3
00401010   int         3
00401011   int         3
00401012   int         3
00401013   int         3
00401014   int         3
00401015   int         3
00401016   int         3
00401017   int         3
00401018   int         3
00401019   int         3
0040101A   int         3
0040101B   int         3
0040101C   int         3
0040101D   int         3
0040101E   int         3
0040101F   int         3

--- C:/Documents and Settings/Administrator/桌面/overflow/overflow.cpp  ----------------------------------
1:    #include<stdio.h>
2:    #include<stdlib.h>
3:    #include<string.h>
4:
5:    #define PASSWORD "1234567"
6:
7:    int verify_password(char *password){

00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,4Ch
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-4Ch]
0040102C   mov         ecx,13h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]

           //以上部分同main函数的前段代码,申请4ch的栈空间,其中authenticated和buffer【8】共占12个空间
8:        int authenticated=0;
00401038   mov         dword ptr [ebp-4],0

          //设置authenticated为0
9:        char buffer[8]; // add local buff to be overflowed
10:       authenticated=strcmp(password,PASSWORD);

0040103F   push        offset string "1234567" (0042201c)
00401044   mov         eax,dword ptr [ebp+8]
00401047   push        eax

          //把正确密码和输入密码分别压栈,输入密码存于password中,位于 [ebp+8]处
00401048   call        strcmp (00401210)

         //比较,对于cmp函数,如果正确密码大于输入密码则返回1,小于返回-1,等于返回0
0040104D   add         esp,8
00401050   mov         dword ptr [ebp-4],eax

         返回结果存于eax中,转到authenticated中
11:       strcpy(buffer,password); //overflow is here !
00401053   mov         ecx,dword ptr [ebp+8]
00401056   push        ecx
00401057   lea         edx,[ebp-0Ch]
0040105A   push        edx
0040105B   call        strcpy (00401120)

        //此处把password拷贝到buffer数组,由于在栈中buffer数组下面是authenticated,

        //然后就是main函数的ebp压栈处,再下面就是verify_password函数的返回地址

        //所以只要传入的password大于buffer数组的大小,即8字节,

        //就可以覆盖后面的authenticated和main函数的ebp以及verify_password函数的返回地址

        //现在要使输入一个错误密码是也会pass----输入8位密码(要大于正确密码,这样cmp函数返回的就是00000001,否则就是FFFFFFFF(-1),不方便)

        //比如qqqqqqqq,这样字符串后的结束符“0x00”就会覆盖authenticated中最后的"01”(Big-Indian),这样错误密码就会被认为是这正确的(cmp返回值被改为0)

        //下面是那部分栈的内容:

          0012FB10  CC CC CC CC  烫烫
          0012FB14  CC CC CC CC  烫烫
          0012FB18  71 71 71 71  qqqq
          0012FB1C  71 71 71 71  qqqq
          0012FB20  00 00 00 00  ....(此处原来是01 00 00 00,被覆盖成00)
          0012FB24  80 FF 12 00  ....  这里是main函数的ebp保存于此
          0012FB28  E2 10 40 00  ..@.这里是verify_password函数的返回地址

 

          //在这里也可以覆盖返回地址从而使程序跳转到自己想执行的地方,也可插入自己的代码...

00401060   add         esp,8
12:       return authenticated;
00401063   mov         eax,dword ptr [ebp-4]
13:   }
00401066   pop         edi
00401067   pop         esi
00401068   pop         ebx
00401069   add         esp,4Ch
0040106C   cmp         ebp,esp
0040106E   call        __chkesp (004012a0)
00401073   mov         esp,ebp
00401075   pop         ebp
00401076   ret

..........

15:   void main(){
00401090   push        ebp
00401091   mov         ebp,esp
       //把调用main函数的函数栈帧的ebp压栈保存(当main函数结束时出栈恢复),
       //现在栈是main的栈帧,把main函数的ebp设置在此处
00401093   sub         esp,444h
       //在栈中为变量保留444h的空间(其中4h是valid_flag的大小)
       //而400h,1024B为password[1024]准备
       //40h是VC对Debug版本的保护机制,设置对于堆栈操作溢出,故申请了40h空间
00401099   push        ebx
0040109A   push        esi
0040109B   push        edi
       //寄存器压栈,保存现场
0040109C   lea         edi,[ebp-444h]
       //ebp-444h是战中变量部分顶部
004010A2   mov         ecx,111h
       //ecx计数,共111个栈单元(一个栈单元是4个内存单元)
004010A7   mov         eax,0CCCCCCCCh
004010AC   rep stos    dword ptr [edi]
       //循环ecx次数对变量部分填充cccccccch,即int 3
16:
17:       int valid_flag=0;
004010AE   mov         dword ptr [ebp-4],0
18:       char password[1024];
19:
20:       printf("input the password :  ");
004010B5   push        offset string "input the password :  " (0042300c)
        //调用printf函数之前把输出内容的地址压栈传实参
004010BA   call        printf (004012e0)
        //调用printf函数
004010BF   add         esp,4
        //这个栈单元是调用printf函数时参数压栈,函数返回参数就没用了,直接跳过
21:       scanf("%s",password);
004010C2   lea         eax,[ebp-404h]
        //把password数组的存储位置首地址压栈
004010C8   push        eax
004010C9   push        offset string "%s" (004228a0)
        //再把另一个参数"%s"压栈(从右向左压参数)
004010CE   call        scanf (0040fa20)
004010D3   add         esp,8
        //此处同printf函数
22:
23:       valid_flag=verify_password(password);
004010D6   lea         ecx,[ebp-404h]
004010DC   push        ecx
        //调用verify_password函数之前把参数首地址压栈,即数组password首地址
004010DD   call        @ILT+0(verify_password) (00401005)
004010E2   add         esp,4
004010E5   mov         dword ptr [ebp-4],eax
        //函数返回时返回值保存在eax中,再把返回值保存在main函数中的变量valid_flag中
        //ebp就是起到栈基址的作用
24:
25:       if(valid_flag){
004010E8   cmp         dword ptr [ebp-4],0
004010EC   je          main+6Dh (004010fd)
         //比较valid_flag和0,如果相等(说明密码正确)
         //则跳转到输出"Congratulations ! you have passed"
26:           printf("incorrect passwprd !/n");
004010EE   push        offset string "incorrect passwprd !/n" (0042206c)
004010F3   call        printf (004012e0)
004010F8   add         esp,4
27:       }
28:       else{
004010FB   jmp         main+7Ah (0040110a)
29:           printf("Congratulations ! you have passed the verification !/n/n");
004010FD   push        offset string "Congratulations ! you have passe"... (00422028)
00401102   call        printf (004012e0)
00401107   add         esp,4
30:       }
31:
32:   }

       //下面是main函数返回时的恢复现场,寄存器出栈
0040110A   pop         edi
0040110B   pop         esi
0040110C   pop         ebx
0040110D   add         esp,444h
00401113   cmp         ebp,esp
00401115   call        __chkesp (004012a0)
0040111A   mov         esp,ebp
0040111C   pop         ebp

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐