最近在分析C++ dump 文件的时候觉得有必要将一些必要的反汇编东西总结一下以备别人参考,自己有时间的时候也可以进行更多的改进。下面通过一个简单的C++代码转成汇编代码后的详细解释说明一下C++和汇编的对应关系,以及如何识别汇编代码中进行的一些操作的意义。代码的调用关系如下图所示:

完整C++代码下:


int InternalFunctionA(int nSizeA1, int nSizeA2)
{
    int localnSizeA1 = nSizeA1;
    int localnSizeA2 = nSizeA2;     int nFunctionA = localnSizeA1 + localnSizeA2;     return nFunctionA;
} int InternalFunctionB(int nSizeB1, int nSizeB2)
{     int nFunctionA = InternalFunctionA(nSizeB1, nSizeB2);
    return 0;
} int _tmain(int argc, _TCHAR* argv[])
{
    
    int nFunctionVal = InternalFunctionB(36, 64);
    cout<<"Hello SolidMango!"<<endl;
    return 0; }

那么这段简单的C++代码在转换成汇编代码之后是什么样子的呢?让我们拭目以待,首先让我们看看main函数转换后的代码(debug版), 如下,我们逐条来进行分析,


int _tmain(int argc, _TCHAR* argv[])
{
00411570  push        ebp  //栈底压栈
00411571  mov         ebp,esp //栈底下移,更详细的请参考我关于ebp,esp的解释
00411573  sub         esp,0CCh //局部变量预留空间
00411579  push        ebx  //保存ebx  
0041157A  push        esi  //保存esi  
0041157B  push        edi  //保存edi  
0041157C  lea         edi,[ebp-0CCh] //下移edi到栈顶
00411582  mov         ecx,33h //0CCh/4 = 33h
00411587  mov         eax,0CCCCCCCCh //eax赋值
0041158C  rep stos    dword ptr es:[edi] //从edi开始做33h次赋值0CCCCCCCCh ,初始化栈内存
    
    int nFunctionVal = InternalFunctionB(36, 64);
0041158E  push        40h  //参数64入栈,
00411590  push        24h  //参数36入栈
00411592  call        InternalFunctionB (41101Eh) );//到41101Eh处函数调用
00411597  add         esp,8 //函数调用后将参数弹出,清理栈
0041159A  mov         dword ptr [nFunctionVal],eax 
    cout<<"Hello SolidMango!"<<endl;
0041159D  mov         esi,esp 
0041159F  mov         eax,dword ptr [__imp_std::endl (41A338h)] 
004115A4  push        eax  
004115A5  push        offset string "Hello SolidMango!" (417800h) 
004115AA  mov         ecx,dword ptr [__imp_std::cout (41A33Ch)] 
004115B0  push        ecx  
004115B1  call        std::operator<<<std::char_traits<char> > (411163h) 
004115B6  add         esp,8 
004115B9  mov         ecx,eax 
004115BB  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A320h)] 
004115C1  cmp         esi,esp 
004115C3  call        @ILT+430(__RTC_CheckEsp) (4111B3h) 
    return 0;
004115C8  xor         eax,eax  }
004115CA  pop         edi  //恢复edi
004115CB  pop         esi  //恢复esi
004115CC  pop         ebx  //恢复ebx
004115CD  add         esp,0CCh //栈顶上移
004115D3  cmp         ebp,esp //检查栈平衡
004115D5  call        @ILT+430(__RTC_CheckEsp) (4111B3h) 
004115DA  mov         esp,ebp //恢复上一个栈帧的ebp,esp
004115DC  pop         ebp  
004115DD  ret//函数返回

另外两层函数调用的汇编代码如下,感兴趣的读者可以对比一下,和main函数的过程相似,


int InternalFunctionA(int nSizeA1, int nSizeA2)
{
004114C0  push        ebp  
004114C1  mov         ebp,esp 
004114C3  sub         esp,0E4h 
004114C9  push        ebx  
004114CA  push        esi  
004114CB  push        edi  
004114CC  lea         edi,[ebp-0E4h] 
004114D2  mov         ecx,39h 
004114D7  mov         eax,0CCCCCCCCh 
004114DC  rep stos    dword ptr es:[edi] 
    int localnSizeA1 = nSizeA1;
004114DE  mov         eax,dword ptr [nSizeA1] 
004114E1  mov         dword ptr [localnSizeA1],eax 
    int localnSizeA2 = nSizeA2;
004114E4  mov         eax,dword ptr [nSizeA2] 
004114E7  mov         dword ptr [localnSizeA2],eax      int nFunctionA = localnSizeA1 + localnSizeA2;
004114EA  mov         eax,dword ptr [localnSizeA1] 
004114ED  add         eax,dword ptr [localnSizeA2] 
004114F0  mov         dword ptr [nFunctionA],eax      return nFunctionA;
004114F3  mov         eax,dword ptr [nFunctionA] 
}
004114F6  pop         edi  
004114F7  pop         esi  
004114F8  pop         ebx  
004114F9  mov         esp,ebp 
004114FB  pop         ebp  
004114FC  ret   
int InternalFunctionB(int nSizeB1, int nSizeB2)
{
00411510  push        ebp  
00411511  mov         ebp,esp 
00411513  sub         esp,0CCh 
00411519  push        ebx  
0041151A  push        esi  
0041151B  push        edi  
0041151C  lea         edi,[ebp-0CCh] 
00411522  mov         ecx,33h 
00411527  mov         eax,0CCCCCCCCh 
0041152C  rep stos    dword ptr es:[edi]      int nFunctionA = InternalFunctionA(nSizeB1, nSizeB2);
0041152E  mov         eax,dword ptr [nSizeB2] 
00411531  push        eax  
00411532  mov         ecx,dword ptr [nSizeB1] 
00411535  push        ecx  
00411536  call        InternalFunctionA (411140h) 
0041153B  add         esp,8 
0041153E  mov         dword ptr [nFunctionA],eax 
    return 0;
00411541  xor         eax,eax 
}
00411543  pop         edi  
00411544  pop         esi  
00411545  pop         ebx  
00411546  add         esp,0CCh 
0041154C  cmp         ebp,esp 
0041154E  call        @ILT+430(__RTC_CheckEsp) (4111B3h) 
00411553  mov         esp,ebp 
00411555  pop         ebp  
00411556  ret

总结:通过这几篇文章的总结,相信大家已经可以看懂一些常规的C++反汇编代码,应该可以对付一般的应用,如果大家还有什么问题,或者建议欢迎讨论。

逆向分析一个完整的C++程序包含寄存器与参数传递详解的更多相关文章

  1. 一个完整的WSDL文档及各标签详解

    <?xml version="1.0" encoding="UTF8" ?> <wsdl:definitions targetNamespac ...

  2. java程序运行时内存分配详解

    java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下   一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...

  3. Java程序在内存中运行详解

    目录 Java程序在内存中运行详解 一.JVM的内存分布 二.程序执行的过程 三.只有一个对象时的内存图 四.两个对象使用同一个方法的内存图 五.两个引用指向同一个对象的内存图 六.使用对象类型作为方 ...

  4. Myeclipse程序调试快捷键及步骤详解

    Myeclipse程序调试快捷键及步骤详解: 调试快捷键    Eclipse中有如下一些和运行调试相关的快捷键.    1. [Ctrl+Shift+B]:在当前行设置断点或取消设置的断点.    ...

  5. 一个完整的hadoop程序开发过程

    目的 说明hadoop程序开发过程 前提条件 ubuntu或同类OS java1.6.0_45 eclipse-indigo hadoop-0.20.2 hadoop-0.20.2-eclipse-p ...

  6. Android核心分析之十五Android输入系统之输入路径详解

       Android用户事件输入路径 1 输入路径的一般原理 按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题.按键,鼠标等用户消息 ...

  7. 安卓程序代写 网上程序代写[原]BluetoothDevice详解

    一. BluetoothDevice简介 1. 继承关系 public static Class BluetoothDevice extends Object implement Parcelable ...

  8. Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解

    一.前言 在之前已经介绍过了Android中一款hook神器Xposed,那个框架使用非常简单,方法也就那几个,其实最主要的是我们如何找到一个想要hook的应用的那个突破点.需要逆向分析app即可.不 ...

  9. 安卓程序代写 网上程序代写[原]BluetoothSocket详解

    一. BluetoothSocket简介 1. 简介 客户端与服务端 : BluetoothSocket 和 BluetoothServerSocket 类似于Java中的套接字的 Socket 和 ...

随机推荐

  1. nginx1.6.3

    Nginx1.6.3安装配置 安装时关闭防火墙和selinuxservice iptables stopsed -i "s/selinux=enabled/selinux=disable/g ...

  2. [vijos1246]文科生的悲哀(二)

    [vijos1246]文科生的悲哀(二) 试题描述 化学不及格的Matrix67无奈选择了文科.他必须硬着头皮艰难地进行着文科的学习. 这学期的政治.历史和地理课本各有n章.每一科的教学必须按章节从前 ...

  3. 在Ignite中使用线性回归算法

    在本系列前面的文章中,简单介绍了一下Ignite的机器学习网格,下面会趁热打铁,结合一些示例,深入介绍Ignite支持的一些机器学习算法. 如果要找合适的数据集,会发现可用的有很多,但是对于线性回归来 ...

  4. 洛谷P1077 摆花

    题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时 ...

  5. noj 2033 一页书的书 [ dp + 组合数 ]

    传送门 一页书的书 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 53            测试通过 : 1 ...

  6. Markdown编辑器及语法

    dillinger 漂亮强大,支持md, html, pdf 文件导出.支持dropbox, onedrive,google drive, github. 来自国外,可能不够稳定. MaHua 小众软 ...

  7. 前端学习之--html

    html 文件就是充当模板使用,包含head头和body身体,body包含众多的标签,每个标签都使用尖括号包裹,内部由标签名和标签属性构成.其中标签分为2类: 1:块级标签,特点:占用一行,如:< ...

  8. java基础 4 继承(3)this 与 super关键字

    this用来指向当前实例对象,用来区别成员变量与方法的形参 super可以用来访问父类的方法或成员变量,当子类构造函数需要显示的调用父类的构造函数时,super()必须为构造函数中的第一条语句.

  9. oracle 用户账户被锁处理

    一.以管理员身份登录 SQL> conn sys/sys as sysdba; (分号是必须的但是我是以system登录的所在这不应该写conn sys/sys as sysdba应该写conn ...

  10. Jinja2如何默认将None 值显示为空字符串?

    在Jinja模板中 {% if User %} {{ User.name }} {% endif %} 可以简化为下面的写法,同时,保证返回值为空,而不是显示为“None” {{ User.name ...