【學習逆向工程,分析機器代碼】(二)(C++篇)
by dreamerate
1、序
大家好!再一次和大家見面了!我這次要告訴大家的是,一個C++程序產生的機器代碼到底長什麼樣?通過這些代碼及註釋加以分析,您應該能瞭解C++程序的一些底層機制及CRT內幕!^_^
本篇算是根據ATField大俠的文章所衍生的續集!大家可訪問ATField大俠的blog: http://blog.csdn.net/atfield/archive/2006/11/14/1382694.aspx,他可是一個很全面的高手哦!
切入主題,由ATField大俠提供的簡單C++小程序原代碼,本人略作小許修改並重新進行了一次編譯,然後再用OllyDbg進行了跟蹤分析。發現在反彙編這些代碼出入很大哦!終究其原因:編譯器的差別(我用VC++6.0E,他用的是VC++8.0)。
例如像D8H的這個分配過程換來的而是8H,就兩個MACHINE WORD(32位CPU的機器字。一個機器字佔4個字節):
第一個是指向本對象地址,第二個搞不清楚是用來做什麼用的(鬱悶……),有誰知道嗎?
2、一個具體而微的C++小程序
包括內容:一個C++ entry point函數main及一個class。本文的中心思想是分析C++類機制。
------------------------------------------------------------------------
源程序如下:
#include <windows.h> #include <stdio.h>
class my_class { public: my_class() { m_member = 1; }
void method( int n ) { m_member = n; }
~my_class() { m_member = 0; } private: int m_member; };
int main( int argc, char** argv ) { my_class a_class; printf( "I'm testor!" ); a_class.method( 0x111 ); return 0; }
------------------------------------------------------------------------
3、編譯
在XP SP2環境下,開一個cmd.exe,鍵入VC6,進入我們的test.cpp目錄,鍵入bcpp test,完成編譯。 以下是vc6.bat及bcpp.bat的內容:
VC6.bat ----------------------------------------------------------------------- @echo off set VC6DIR=I:/Program Files/Microsoft Visual Studio/VC98 set include=I:/DXSDK/Include;%VC6DIR%/Include;%VC6DIR%/atl/include;%VC6DIR%/mfc/include set lib=I:/DXSDK/Lib;%VC6DIR%/lib;%VC6DIR%/mfc/lib set path=c:/;I:/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin;%VC6DIR%/Bin set %VC6DIR%= echo on -----------------------------------------------------------------------
bcpp.bat ----------------------------------------------------------------------- @echo off if exist %1.obj del %1.obj if exist %1.exe del %1.exe cl /c /Gz /GX %1.cpp if not exist %1.obj goto EXITFLAG link /machine:x86 /subsystem:console %1.obj user32.lib kernel32.lib gdi32.lib if not exist %1.exe goto EXITFLAG %1.exe :EXITFLAG -----------------------------------------------------------------------
4、逆向過程
打開OllyDBG,加載test.exe,然後在00401000地址設置斷點。按下F9後我們來到斷點處,接着便是F8一路逐行分析代碼:
-------- ---- ------------ ------------------------------------- ---------------------------------------------------- 地址 流程 機器代碼 彙編代碼 註釋 -------- ---- ------------ ------------------------------------- ----------------------------------------------------
00401000 /$ 55 push ebp ; 保存舊的ebp 00401001 |. 8BEC mov ebp, esp ; ebp保存當前棧的位置
00401003 |. 6A FF push -1 ; 建立SEH鏈. ERR結構第三成員 00401005 |. 68 69684000 push test.00406869 ; Structured Exception處理程序. ERR結構第二成員 0040100A |. 64:A1 0000000>mov eax, dword ptr fs:[0] ; fs:0指向當前線程的TEB 00401010 |. 50 push eax ; 我們將它備份起來並且設爲ERR結構第一成員 00401011 |. 64:8925 00000>mov dword ptr fs:[0], esp ; 建立當前的SEH的ERR結構(利用棧)
00401018 |. 83EC 08 sub esp, 8 ; my_class a_class; 0040101B |. 8D4D F0 lea ecx, dword ptr ss:[ebp-10] ; a_class對象指針ECX ; 它指向值第一個private成員int m_member 0040101E |. E8 4D000000 call test.00401070 ; 呼叫構造函數
00401023 |. C745 FC 00000>mov dword ptr ss:[ebp-4], 0 ; 進入__try塊,在Main中有一個隱式的__try/__except塊
0040102A |. 68 40804000 push test.00408040 ; ASCII "I'm testor!" 0040102F |. E8 90000000 call test.004010C4 ; printf 00401034 |. 83C4 04 add esp, 4 ; 釋放前一個CALL的push
00401037 |. 68 11010000 push 111 ; /Arg1 = 00000111 0040103C |. 8D4D F0 lea ecx, dword ptr ss:[ebp-10] ; | <- a_class對象指針ECX 0040103F |. E8 4C000000 call test.00401090 ; /a_class.method
00401044 |. C745 EC 00000>mov dword ptr ss:[ebp-14], 0 ; 有誰知道這個DWORD是用來幹什麼的嗎?
0040104B |. C745 FC FFFFF>mov dword ptr ss:[ebp-4], -1 ; 標記TRY的正常結束
00401052 |. 8D4D F0 lea ecx, dword ptr ss:[ebp-10] ; a_class對象指針ECX 00401055 |. E8 56000000 call test.004010B0 ; 析構函數
0040105A |. 8B45 EC mov eax, dword ptr ss:[ebp-14] ; ?奇怪哦!最接近ret的eax應該是本函數的返回值! ; 直接在最尾test eax, eax不就行了嗎? 爲什麼要這樣... 0040105D |. 8B4D F4 mov ecx, dword ptr ss:[ebp-C] ; 恢復之前保存的TEB 00401060 |. 64:890D 00000>mov dword ptr fs:[0], ecx
00401067 |. 8BE5 mov esp, ebp ; 你知道... 00401069 |. 5D pop ebp
0040106A /. C3 retn ; 恢復CALL影響的STACK及定位EIP
--------------------------------------------------------------------------------------------------
00401070 /$ 55 push ebp ; my_class類構造函數 00401071 |. 8BEC mov ebp, esp 00401073 |. 51 push ecx 00401074 |. 894D FC mov dword ptr ss:[ebp-4], ecx 00401077 |. 8B45 FC mov eax, dword ptr ss:[ebp-4] 0040107A |. C700 01000000 mov dword ptr ds:[eax], 1 00401080 |. 8B45 FC mov eax, dword ptr ss:[ebp-4] 00401083 |. 8BE5 mov esp, ebp 00401085 |. 5D pop ebp 00401086 /. C3 retn
--------------------------------------------------------------------------------------------------
00401090 /$ 55 push ebp ; void my_class::method(int n) 00401091 |. 8BEC mov ebp, esp 00401093 |. 51 push ecx 00401094 |. 894D FC mov dword ptr ss:[ebp-4], ecx 00401097 |. 8B45 FC mov eax, dword ptr ss:[ebp-4] 0040109A |. 8B4D 08 mov ecx, dword ptr ss:[ebp+8] ; 參數int n 0040109D |. 8908 mov dword ptr ds:[eax], ecx 0040109F |. 8BE5 mov esp, ebp 004010A1 |. 5D pop ebp 004010A2 /. C2 0400 retn 4
--------------------------------------------------------------------------------------------------
004010B0 /$ 55 push ebp ; my_class類析構函數 004010B1 |. 8BEC mov ebp, esp 004010B3 |. 51 push ecx 004010B4 |. 894D FC mov dword ptr ss:[ebp-4], ecx 004010B7 |. 8B45 FC mov eax, dword ptr ss:[ebp-4] 004010BA |. C700 00000000 mov dword ptr ds:[eax], 0 004010C0 |. 8BE5 mov esp, ebp 004010C2 |. 5D pop ebp 004010C3 /. C3 retn
--------------------------------------------------------------------------------------------------
004010C4 /$ 53 push ebx ; CRT函數printf 004010C5 |. 56 push esi 004010C6 |. BE 90804000 mov esi, test.00408090 004010CB |. 57 push edi 004010CC |. 56 push esi 004010CD |. E8 20050000 call test.004015F2 004010D2 |. 8BF8 mov edi, eax 004010D4 |. 8D4424 18 lea eax, dword ptr ss:[esp+18] 004010D8 |. 50 push eax 004010D9 |. FF7424 18 push dword ptr ss:[esp+18] 004010DD |. 56 push esi 004010DE |. E8 D9050000 call test.004016BC 004010E3 |. 56 push esi 004010E4 |. 57 push edi 004010E5 |. 8BD8 mov ebx, eax 004010E7 |. E8 93050000 call test.0040167F 004010EC |. 83C4 18 add esp, 18 004010EF |. 8BC3 mov eax, ebx 004010F1 |. 5F pop edi 004010F2 |. 5E pop esi 004010F3 |. 5B pop ebx 004010F4 /. C3 retn -------------------------------------------------------------------------------------------------------------------
5、總結
懶得寫了,哥們看註釋吧!:)
|