您的位置:首页 > 编程语言 > C语言/C++

【学习逆向工程,分析机器代码】(二)(C++篇)

2007-04-27 16:16 911 查看
【学习逆向工程,分析机器代码】(二)(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、总结

懒得写了,哥们看注释吧!:)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: