【學習逆向工程,分析機器代碼】(二)(C++篇)

【學習逆向工程,分析機器代碼】(二)(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、總結


   懶得寫了,哥們看註釋吧!:)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章