VC生成的汇编代码

本文通过分析VC6编译的C程序汇编代码,展示了如何利用`getline()`函数可能导致的缓冲区溢出问题,并探讨了如何在堆栈中填充`int 3`中断指令以增强程序安全性。通过对汇编代码的解读,揭示了内存分配、函数调用等细节,为理解C程序执行和调试提供了深入见解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

VC6中新建工程,输入代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


char *getline()
{
    char buf[8];
    char *result;
    gets(buf);
    result = (char *) malloc(strlen(buf));
    strcpy(result, buf);
   
 return result;

}

int main(void)
{
    getline();
    return 0;
}



这个程序存在缓冲区溢出的问题,当 gets函数中输入的字符数大于7个字节,那么就会覆盖堆栈中的返回地址。

 

注意:

VC下并不包含alloc.h头文件,可以加上stdlib.h或malloc.h头文件,这两个头文件里面都有malloc函数的声明,以及free、realloc函数的声明。

 

按F10进入单步调试

 

 

 

 

然后右键,Go To Disassembly 转到汇编代码

 

 

汇编代码

 

-- c:/program files/microsoft visual studio/myprojects/asm/tt.c  ---------------------------------------------------------
1:    #include <stdio.h>
2:    #include <stdlib.h>
3:    #include <string.h>
4:
5:
6:    char *getline()
7:    {
00401020 55                   push        ebp
00401021 8B EC                mov         ebp,esp
00401023 83 EC 4C             sub         esp,4Ch    ; Allocate 19*4  bytes on stack
00401026 53                   push        ebx
00401027 56                   push        esi
00401028 57                   push        edi
00401029 8D 7D B4             lea         edi,[ebp-4Ch]
0040102C B9 13 00 00 00       mov         ecx,13h
00401031 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
00401036 F3 AB                rep stos    dword ptr [edi]
8:        char buf[8];
9:        char *result;
10:       gets(buf);
00401038 8D 45 F8             lea         eax,[ebp-8]
0040103B 50                   push        eax
0040103C E8 8F 21 00 00       call        gets (004031d0)
00401041 83 C4 04             add         esp,4
11:       result = (char *) malloc(strlen(buf));
00401044 8D 4D F8             lea         ecx,[ebp-8]
00401047 51                   push        ecx
00401048 E8 03 21 00 00       call        strlen (00403150)
0040104D 83 C4 04             add         esp,4
00401050 50                   push        eax
00401051 E8 7A 01 00 00       call        malloc (004011d0)
00401056 83 C4 04             add         esp,4
00401059 89 45 F4             mov         dword ptr [ebp-0Ch],eax
12:       strcpy(result, buf);
0040105C 8D 55 F8             lea         edx,[ebp-8]
0040105F 52                   push        edx
00401060 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]
00401063 50                   push        eax
00401064 E8 77 00 00 00       call        strcpy (004010e0)
00401069 83 C4 08             add         esp,8
13:
14:       return result;
0040106C 8B 45 F4             mov         eax,dword ptr [ebp-0Ch]
15:
16:   }
0040106F 5F                   pop         edi
00401070 5E                   pop         esi
00401071 5B                   pop         ebx
00401072 83 C4 4C             add         esp,4Ch
00401075 3B EC                cmp         ebp,esp
00401077 E8 24 22 00 00       call        __chkesp (004032a0)
0040107C 8B E5                mov         esp,ebp
0040107E 5D                   pop         ebp
0040107F C3                   ret
--- No source file  -------------------------------------------------------------------------------------------------------

 Main函数:

--- C:/Program Files/Microsoft Visual Studio/MyProjects/asm/tt.c  --------------------------------
12:
13:   int main(void)
14:   {
004010A0 55                   push        ebp                                            ; Save old ebp
004010A1 8B EC            mov         ebp,esp                                     ; Set ebp as frame pointer
004010A3 83 EC 40       sub         esp,40h                                     ; Allocate 16*4  bytes on stack
004010A6 53                   push        ebx                                             ; Save ebx
004010A7 56                   push        esi                                              ; Save esi
004010A8 57                   push        edi                                              ; Save edi
004010A9 8D 7D C0             lea         edi,[ebp-40h]                       ; Set edi to (ebp - 40h)
004010AC B9 10 00 00 00       mov         ecx,10h                           
004010B1 B8 CC CC CC CC       mov         eax,0CCCCCCCCh    ; cc = int 3 中断
004010B6 F3 AB                rep stos    dword ptr [edi]              ; 上面分配的16 *4字节填上int3指令
15:       getline();
004010B8 E8 48 FF FF FF       call        @ILT+0(_getline) (00401005)      ; Debug的时侯才会出现@ILT (Incremental Link Table)
16:       return 0;
004010BD 33 C0                xor         eax,eax
17:   }
004010BF 5F                   pop         edi
004010C0 5E                   pop         esi
004010C1 5B                   pop         ebx
004010C2 83 C4 40             add         esp,40h
004010C5 3B EC                cmp         ebp,esp                                    ; 检查 esp 是否正确
004010C7 E8 D4 21 00 00       call        __chkesp (004032a0)      ; 同样是 Debug only
004010CC 8B E5                mov         esp,ebp
004010CE 5D                   pop         ebp
004010CF C3                   ret
--- No source file  ------------------------------------------------------------------------------

 

  将分配的局部变量空间全部初始化成 int 3中断指令的目的在于,这些数据是不能当成指令来执行的,如果程序意

外的当成指令执行,那么int 3会造成中断。这样,我们就有机会了解到发生了不好的事情了。

 

 用 Debug 选项编译程序才会出现这个 call        @ILT+0(_getline) (00401005) 

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值