vc++简单反汇编代码

<img src="https://img-blog.csdn.net/20150121213734953?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlodDU5NA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></pre><pre name="code" class="cpp">// consoleTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
struct _A
{
    int a;
    int b;   

    virtual void f()
    {
        this->a = 1;
        printf("%d, %d", a, b);
    }
};


class _B
{
public:
    virtual TCHAR* f(int x)
    {
        int c = x;
        b = 1;
        printf("%d, %d", a, b);
        TCHAR *p = _T("返回值");
        return p;
    }

    int a;
    int b;
};
int main()
{
    int  iVal = 25;
    TCHAR *p = _T("字符串变量");

    int* pInt = &iVal;
    int& iRef = iVal;
    printf("*pInt = %d, iRef = %d/n", *pInt, iVal);

    _A a;
    _B b;

    a.a = a.b = 25;
    b.a = b.b = a.a + a.b;

    a.f();
    p =  b.f(5);

    return 1;
}


对应的反汇编代码


    28: int main()
    29: {
013F1420  push        ebp  ;//这个ebp是调用main函数的函数的栈帧底部
;保存ebp,基址指针ebp指向一个(将要调用的)函数的栈帧的底部。栈帧保存返回地址和局部变量。

013F1421  mov         ebp,esp  
;将esp放入ebp中,此时ebp和esp相同.esp是栈顶
;此时:栈中以esp为界,本函数的参数已经在栈中,本函数的局部变量将要入栈

013F1423  sub         esp,114h  
;写把esp往上移动一个范围
;等于在栈中空出一片空间来存局部变量

013F1429  push        ebx  
013F142A  push        esi  
013F142B  push        edi  
;保存三个寄存器的值

013F142C  lea         edi,[ebp-114h]  ;lea取得偏移地址.  edi通常在内存操作指令中作为“目的地址指针”使用
;把ebp-114h加载到edi中,目的是保存局部变量的区域

013F1432  mov         ecx,45h  ;//CX:计数暂存器  45h次
013F1437  mov         eax,0CCCCCCCCh  ;//AX累积暂存器  初始化4个字节(一个cc就是一个int 3)
013F143C  rep stos    dword ptr es:[edi]  
;从ebp-114h开始的区域初始化成全部0CCCCCCCCh,就是int3断点,初始化局部变量空间

;rep指令的目的是重复其上面的指令. ECX的值是重复的次数.45h * 4 = 114h

;STOS指令的作用是将eax中的值拷贝到ES:EDI指向的地址.指令执行后edi会减小(df=1)或者增加(df=0)


    30:     int  iVal = 25;
013F143E  mov         dword ptr [iVal],19h 
;定义变量
 
 
    31:     TCHAR *p = _T("字符串变量");
013F1445  mov         dword ptr [p],offset string L"\x5b57\x7b26\x4e32\x53d8\x91cf" (13F5758h)  ;//offset获得偏移地址
;定义变量


    32: 
    33:     int* pInt = &iVal;
013F144C  lea         eax,[iVal]  
013F144F  mov         dword ptr [pInt],eax  
;定义变量


    34:     int& iRef = iVal;
013F1452  lea         eax,[iVal]  
013F1455  mov         dword ptr [iRef],eax  
;定义变量


    35:     printf("*pInt = %d, iRef = %d/n", *pInt, iRef);
013F1458  mov         esi,esp  //保存栈顶指针

;//下面的指针和引用做参数的反汇编代码是一样的
013F145A  mov         eax,dword ptr [iRef]  ;//这里把变量地址保存到eax, iRef是指针地址(如果不是指针变量,则没有这一行)
013F145D  mov         ecx,dword ptr [eax]    ;//这里把变量值保存到ecx,eax中是变量地址
013F145F  push        ecx                   ;//参数iRef入栈

013F1460  mov         edx,dword ptr [pInt]  ;//参考上面
013F1463  mov         eax,dword ptr [edx]   ; //参考上面
013F1465  push        eax                   ;//参考上面
;(如果iVal做参数,则应该是下面这样的
;0134145A  mov         eax,dword ptr [iVal]  //通过变量地址iVal,取值
;0134145D  push        eax                   //值入栈
;)


013F1466  push        offset string "*pInt = %d, iRef = %d/n" (13F573Ch)  
;第一个参数入栈,参数是倒续入栈的

013F146B  call        dword ptr [__imp__printf (13F82E4h)]  
;调用函数

013F1471  add         esp,0Ch  
;//平栈


013F1474  cmp         esi,esp  
;//平栈后的栈顶指针与保存的栈顶指针比较,看看是否出错
;//出错调用__RTC_CheckEsp
013F1476  call        @ILT+335(__RTC_CheckEsp) (13F1154h)  


    36: 
    37:     _A a;
    38:     _B b;
013F147B  lea         ecx,[b]  
013F147E  call        _B::_B (13F1177h)  
;调用类_B的构造函数._A是结构体,没有构造函数


    39: 
    40:     a.a = a.b = 25;
013F1483  mov         dword ptr [ebp-38h],19h  
013F148A  mov         eax,dword ptr [ebp-38h]  
013F148D  mov         dword ptr [a],eax  
    41:     b.a = b.b = a.a + a.b;
013F1490  mov         eax,dword ptr [a]  
013F1493  add         eax,dword ptr [ebp-38h]  
013F1496  mov         dword ptr [ebp-48h],eax  
013F1499  mov         ecx,dword ptr [ebp-48h]  
013F149C  mov         dword ptr [ebp-4Ch],ecx  
    42: 
    43:     a.f();
013F149F  lea         ecx,[a]  
013F14A2  call        _A::f (13F10FFh)  



    46:     p =  b.f();
    
009514A5  push        5  
;参数入栈    
001B14A7  lea         ecx,[b]  
;取对象地址,存入ecx-->这个就是this指针
001B14AA  call        _B::f (1B120Dh)  
;//有对象地址,才能调用类的成员函数B::f
001B14AF  mov         dword ptr [p],eax  
;p = 返回值



    45: 
    46:     return 0;
013F14AF  xor         eax,eax  
;相当于mov eax 0,eax作为返回值
    47: }
013F14B1  push        edx  
013F14B2  mov         ecx,ebp  
013F14B4  push        eax  
013F14B5  lea         edx,[ (13F14D8h)]  
013F14BB  call        @ILT+135(@_RTC_CheckStackVars@8) (13F108Ch)  
013F14C0  pop         eax  
013F14C1  pop         edx  
013F14C2  pop         edi  
013F14C3  pop         esi  
013F14C4  pop         ebx 
;恢复原来寄存器的值,怎么“吃”进去,怎么“吐”出来 

013F14C5  add         esp,114h  
;恢复ESP,对应上边的sub esp,44h

013F14CB  cmp         ebp,esp  
;检查esp是否正常,不正常就进入下边的call里面debug

013F14CD  call        @ILT+335(__RTC_CheckEsp) (13F1154h)  
;处理可能出现的堆栈异常,如果有的话,就会陷入debug

013F14D2  mov         esp,ebp  
013F14D4  pop         ebp
;恢复原来的esp和ebp,让上一个调用函数正常使用

002314D5  ret 
;将返回地址存入eip,转移流程

 

;如果函数有返回值,返回值将放在eax返回







    20:     virtual TCHAR* f(int x)//类_B的成员函数
    21:     {
001315D0  push        ebp  
001315D1  mov         ebp,esp  
001315D3  sub         esp,0D8h  
001315D9  push        ebx  
001315DA  push        esi  
001315DB  push        edi  
001315DC  push        ecx  
001315DD  lea         edi,[ebp-0D8h]  
001315E3  mov         ecx,36h  
001315E8  mov         eax,0CCCCCCCCh  
001315ED  rep stos    dword ptr es:[edi]
;上面是初始化局部变量区域
  
001315EF  pop         ecx  
001315F0  mov         dword ptr [ebp-8],ecx 
;保存this指针,ecx是调用成员函数之前保存的

    22:         int c = x;
011D15F3  mov         eax,dword ptr [x]  
011D15F6  mov         dword ptr [c],eax  


    24:         a = 1;
013E15F9  mov         eax,dword ptr [this]  ;//取this指针地址
013E15FC  mov         dword ptr [eax+4],1   ;//this指针+4 去得第一个成员变量地址


    22:         printf("%d, %d", a, b);
001315F3  mov         esi,esp  
001315F5  mov         eax,dword ptr [this]  
001315F8  mov         ecx,dword ptr [eax+8]  
001315FB  push        ecx  
001315FC  mov         edx,dword ptr [this]  
001315FF  mov         eax,dword ptr [edx+4]  
00131602  push        eax  
00131603  push        offset string "%d, %d" (135768h)  
00131608  call        dword ptr [__imp__printf (1382E4h)]  
0013160E  add         esp,0Ch  
00131611  cmp         esi,esp  
00131613  call        @ILT+335(__RTC_CheckEsp) (131154h)  
    23:         TCHAR *p = _T("返回值");
00131618  mov         dword ptr [p],offset string L"\x8fd4\x56de\x503c" (135770h)  
    24:         return p;
0013161F  mov         eax,dword ptr [p]  
;这里使用eax返回p指针
    25:     }
00131622  pop         edi  
00131623  pop         esi  
00131624  pop         ebx  

00131625  add         esp,0D8h  
;//平栈
0013162B  cmp         ebp,esp    
;//与保存的栈顶指针比较
0013162D  call        @ILT+335(__RTC_CheckEsp) (131154h)  
00131632  mov         esp,ebp  
00131634  pop         ebp  
00131635  ret  



<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">int main()</span>
{
    int test = 0;
    for (int i = 0; i < 100; ++i)
    {
        test += i;
    }

    if (test < 5000)
    {
        test = 5000;
    }
    else if (test < 6000)
    {
        test = 6000;
    }
    else
    {
        test *= 2;
    }
    return 0;
}
</pre><pre code_snippet_id="584914" snippet_file_name="blog_20150120_11_2334745" name="code" class="cpp">对应反汇编代码
</pre><p></p><pre code_snippet_id="584914" snippet_file_name="blog_20150120_13_4887210" name="code" class="plain">//下面是for和if,while和for基本一样
//比较简单

    33: int main()
    34: {
00CB1380  push        ebp  
00CB1381  mov         ebp,esp  
00CB1383  sub         esp,0D8h  
00CB1389  push        ebx  
00CB138A  push        esi  
00CB138B  push        edi  
00CB138C  lea         edi,[ebp-0D8h]  
00CB1392  mov         ecx,36h  
00CB1397  mov         eax,0CCCCCCCCh  
00CB139C  rep stos    dword ptr es:[edi]  
    35:     int test = 0;
00CB139E  mov         dword ptr [test],0  
    36:     for (int i = 0; i < 100; ++i)
00CB13A5  mov         dword ptr [i],0  
;//初始化i


00CB13AC  jmp         main+37h (0CB13B7h)  
;


00CB13AE  mov         eax,dword ptr [i]  
00CB13B1  add         eax,1  
00CB13B4  mov         dword ptr [i],eax  



00CB13B7  cmp         dword ptr [i],64h  
;与100比较


00CB13BB  jge         main+48h (0CB13C8h)  
;大于等于时,跳转到
    37:     {
    38:         test += i;
00CB13BD  mov         eax,dword ptr [test]  
00CB13C0  add         eax,dword ptr [i]  
00CB13C3  mov         dword ptr [test],eax  
    39:     }
00CB13C6  jmp         main+2Eh (0CB13AEh)  
    40: 
    41:     if (test < 5000)
00CB13C8  cmp         dword ptr [test],1388h  
00CB13CF  jge         main+5Ah (0CB13DAh)  
    42:     {
    43:         test = 5000;
00CB13D1  mov         dword ptr [test],1388h  
00CB13D8  jmp         main+74h (0CB13F4h)  
    44:     }
    45:     else if (test < 6000)
00CB13DA  cmp         dword ptr [test],1770h  
00CB13E1  jge         main+6Ch (0CB13ECh)  
    46:     {
    47:         test = 6000;
00CB13E3  mov         dword ptr [test],1770h  
    48:     }
    49:     else
00CB13EA  jmp         main+74h (0CB13F4h)  
    50:     {
    51:         test *= 2;
00CB13EC  mov         eax,dword ptr [test]  
00CB13EF  shl         eax,1  
00CB13F1  mov         dword ptr [test],eax  
    52:     }
    53: 
    54: 
    55:     return 0;
00CB13F4  xor         eax,eax  
    56: }






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值