最近在分析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;
那麼這段簡單的C++代碼在轉換成彙編代碼之後是什麼樣子的呢?讓我們拭目以待,首先讓我們看看main函數轉換後的代碼(debug版), 如下,我們逐條來進行分析,
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//函數傳回
另外兩層函數調用的彙編代碼如下,感興趣的讀者可以對比一下,和main函數的過程相似,
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++反彙編代碼,應該可以對付一般的應用,如果大家還有什麼問題,或者建議歡迎讨論。