逆向分析一个完整的C++程序包含寄存器与参数传递详解
最近在分析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++程序包含寄存器与参数传递详解的更多相关文章
- 一个完整的WSDL文档及各标签详解
<?xml version="1.0" encoding="UTF8" ?> <wsdl:definitions targetNamespac ...
- java程序运行时内存分配详解
java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下 一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...
- Java程序在内存中运行详解
目录 Java程序在内存中运行详解 一.JVM的内存分布 二.程序执行的过程 三.只有一个对象时的内存图 四.两个对象使用同一个方法的内存图 五.两个引用指向同一个对象的内存图 六.使用对象类型作为方 ...
- Myeclipse程序调试快捷键及步骤详解
Myeclipse程序调试快捷键及步骤详解: 调试快捷键 Eclipse中有如下一些和运行调试相关的快捷键. 1. [Ctrl+Shift+B]:在当前行设置断点或取消设置的断点. ...
- 一个完整的hadoop程序开发过程
目的 说明hadoop程序开发过程 前提条件 ubuntu或同类OS java1.6.0_45 eclipse-indigo hadoop-0.20.2 hadoop-0.20.2-eclipse-p ...
- Android核心分析之十五Android输入系统之输入路径详解
Android用户事件输入路径 1 输入路径的一般原理 按键,鼠标消息从收集到最终将发送到焦点窗口,要经历怎样的路径,是Android GWES设计方案中需要详细考虑的问题.按键,鼠标等用户消息 ...
- 安卓程序代写 网上程序代写[原]BluetoothDevice详解
一. BluetoothDevice简介 1. 继承关系 public static Class BluetoothDevice extends Object implement Parcelable ...
- Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解
一.前言 在之前已经介绍过了Android中一款hook神器Xposed,那个框架使用非常简单,方法也就那几个,其实最主要的是我们如何找到一个想要hook的应用的那个突破点.需要逆向分析app即可.不 ...
- 安卓程序代写 网上程序代写[原]BluetoothSocket详解
一. BluetoothSocket简介 1. 简介 客户端与服务端 : BluetoothSocket 和 BluetoothServerSocket 类似于Java中的套接字的 Socket 和 ...
随机推荐
- [POJ3041] Asteroids(最小点覆盖-匈牙利算法)
传送门 题意: 给一个N*N的矩阵,有些格子有障碍,要求我们消除这些障碍,问每次消除一行或一列的障碍,最少要几次. 解析: 把每一行与每一列当做二分图两边的点. 某格子有障碍,则对应行与列连边. ...
- BZOJ:[JSOI2009]游戏Game【二分图匹配乱搞】
题目大意:n*m的棋盘,其中有些区域是禁区,两个人在棋盘上进行博弈,后手选择棋子的初始位置,然后先后手轮流将棋子往上下左右移动,走过的区域不能再走,问能否有一个位置使得后手必胜 Input 输入数据首 ...
- 【POJ1743】Musical Theme(后缀数组,二分)
题意:求一个字符串的不重叠最长相同变化的子串 n<=20000 思路:这是一道论文题 我们将原串两两之间作差,可以发现所求的相同变化的子串作出的差相同 问题就转化成了不重叠的最长重复子串 显然答 ...
- HDU 4651 (生成函数)
HDU 4651 Partition Problem : n的整数划分方案数.(n <= 100008) Solution : 参考资料: 五角数 欧拉函数 五边形数定理 整数划分 一份详细的题 ...
- as3corelib Tutorial:How to Use ArrayUtil Class in Flex
ArrayUtil class contains static utility methods for manipulating and working with Arrays. Note that ...
- Python高级进阶(二)Python框架之Django写图书管理系统(LMS)
正式写项目准备前的工作 Django是一个Web框架,我们使用它就是因为它能够把前后端解耦合而且能够与数据库建立ORM,这样,一个Python开发工程师只需要干自己开发的事情就可以了,而在使用之前就我 ...
- POJ 1724 【存在附加约束的最短路问题】【优先队列】
题意:给K个权值.给含有N个点,R条单向边的图. 每条边都有两个权值,其中一个路长,另外一个是附加权值. 要求路的附加权值之和不超过K的情况下求最短路. 思路: 自己的思路太狭隘,这题还是看了大牛的思 ...
- Wannafly挑战赛4
A(枚举) =w= B(枚举) 分析: 枚举每一位,考虑每位贡献,就是相当于在一段区间内找有多少1在奇数位上,有多少个1在偶数位上,维护一下各自前缀和就行了 时间复杂度O(32n) C(签到) D(d ...
- 转:SIP相关的RFC文档索引
索引来源于http://www.packetizer.com/ipmc/sip/standards.html SIP Standards Core SIP Documents RFC Document ...
- 使用datatables实现后台分页功能,减轻前端渲染压力
注意不同版本,参数名字及参数内容存在差异,具体可以参考https://datatables.net/upgrade/1.10-convert#Options 控制页面显示的参数:https://dat ...