天天看点

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

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

逆向分析一个完整的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;

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

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

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

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 ,初始化栈内存

0041158E  push        40h  //参数64入栈,

00411590  push        24h  //参数36入栈

00411592  call        InternalFunctionB (41101Eh) );//到41101Eh处函数调用

00411597  add         esp,8 //函数调用后将参数弹出,清理栈

0041159A  mov         dword ptr [nFunctionVal],eax 

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) 

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//函数返回

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

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

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

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] 

004114DE  mov         eax,dword ptr [nSizeA1] 

004114E1  mov         dword ptr [localnSizeA1],eax 

004114E4  mov         eax,dword ptr [nSizeA2] 

004114E7  mov         dword ptr [localnSizeA2],eax 

004114EA  mov         eax,dword ptr [localnSizeA1] 

004114ED  add         eax,dword ptr [localnSizeA2] 

004114F0  mov         dword ptr [nFunctionA],eax 

004114F3  mov         eax,dword ptr [nFunctionA] 

004114F6  pop         edi  

004114F7  pop         esi  

004114F8  pop         ebx  

004114F9  mov         esp,ebp 

004114FB  pop         ebp  

004114FC  ret   

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] 

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 

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++反汇编代码,应该可以对付一般的应用,如果大家还有什么问题,或者建议欢迎讨论。

继续阅读