天天看點

逆向分析一個完整的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++反彙編代碼,應該可以對付一般的應用,如果大家還有什麼問題,或者建議歡迎讨論。

繼續閱讀