main函数的识别

来源:互联网 发布:base64 c语言 编辑:程序博客网 时间:2024/04/30 06:52

一般来说,用IDA反汇编程序时,IDA会自动识别出main函数。如果我们不是用IDA反汇编,那又怎么识别main函数呢?

1、WinMain函数的识别

先来看看WinMain函数的原型: 

int WINAPI WinMain(  HINSTANCE hInstance,  // handle to current instance  HINSTANCE hPrevInstance,  // handle to previous instance  LPSTR lpCmdLine,      // pointer to command line  int nCmdShow          // show state of window);

1)首先在大多数情况下下,WinMain看起来是启动代码中参数最丰富的函数;

2)其次,放在堆栈中的最后一个变量hInstance是最可能即时能过调用GetModuleHandleA函数进行获取的。例如,在启动代码中,在遇到一个CALL GetMoudleHandleA类型的语句以后,就可以十分自信地断言,接在函数后面的一定是WinMain函数;

3)最后,对WinMain的调用通常放在启动函数代码结尾部分附近,它后面通常跟有诸如exit或者XcptFilter之类的两到三个函数。

我们来看看实例:

00401921  |> \6A 0A         push    0A00401923  |.  58            pop     eax00401924  |>  50            push    eax00401925  |.  56            push    esi00401926  |.  53            push    ebx00401927  |.  53            push    ebx                              ; /pModule00401928  |.  FF15 00204000 call    dword ptr [<&KERNEL32.GetModuleH>; \GetModuleHandleA0040192E  |.  50            push    eax0040192F  |.  E8 5E000000   call    0040199200401934  |.  8945 98       mov     dword ptr [ebp-68], eax00401937  |.  50            push    eax                              ; /status00401938  |.  FF15 B0214000 call    dword ptr [<&MSVCRT.exit>]       ; \exit0040193E  |.  8B45 EC       mov     eax, dword ptr [ebp-14]00401941  |.  8B08          mov     ecx, dword ptr [eax]00401943  |.  8B09          mov     ecx, dword ptr [ecx]00401945  |.  894D 88       mov     dword ptr [ebp-78], ecx00401948  |.  50            push    eax00401949  |.  51            push    ecx0040194A  |.  E8 15000000   call    <jmp.&MSVCRT._XcptFilter>0040194F  |.  59            pop     ecx00401950  |.  59            pop     ecx00401951  \.  C3            retn

再来看看call      00401992处的代码:

00401992  /$  FF7424 10     push    dword ptr [esp+10]00401996  |.  FF7424 10     push    dword ptr [esp+10]0040199A  |.  FF7424 10     push    dword ptr [esp+10]0040199E  |.  FF7424 10     push    dword ptr [esp+10]004019A2  |.  E8 43000000   call    <jmp.&MFC42.#1576_AfxWinMain>004019A7  \.  C2 1000       retn    10


2、DllMain函数的识别:

识别DllMain比WinMain困难得多,首先,DllMain的原型相对来说不那么复杂,并且不包含任何特别的内容:

BOOL WINAPI DllMain(  HINSTANCE hinstDLL,  // handle to DLL module  DWORD fdwReason,     // reason for calling function  LPVOID lpvReserved   // reserved);

其次,对它的调用来自一个令人十分难忘的函数__DllMainCRTStartup的深处,并且没有办法容易地确定这就是我们需要的调用。

不过,调用里面还是存在一些蛛丝马迹。当初始化失败时,DllMain会返回FALSE。__DllMainCRTStartup的代码会对该值班进行检查,并且跳转到函数的发问也是可能的。在启动函数的函数体内包含的这类跳转分支非常少,而且其中仅有一个分支通常会连接到接受三个参数的那个函数。

我们来看看实例:

1003DEDF    57              push    edi1003DEE0    56              push    esi1003DEE1    53              push    ebx1003DEE2    E8 D9C8FCFF     call    1000A7C01003DEE7    8945 E4         mov     dword ptr [ebp-1C], eax1003DEEA    83FE 01         cmp     esi, 11003DEED    75 24           jnz     short 1003DF131003DEEF    85C0            test    eax, eax1003DEF1    75 20           jnz     short 1003DF13


3、main函数的识别:

main函数是在mainCRTStartup函数中调用的。main函数仅仅接受两个参数:

int main (int argc, char **argv)

这并不足以将它与别的函数区分开。然而,命令的关键字不仅能够通过参数进行访问,而且能够通过全局变量__argc与__argv进行存取。(全局变量通过直接对内存进行寻址而即刻使自己暴露无遗。换句话说,对全局变量的引用是以诸如MOV  EAX,[401066]的形式完成的,其中,0x401066是全局变量的地址)。由此可知,针对main进行的调用通常是如下形式的:

00403BF8  |.  A1 B4014100   mov     eax, dword ptr [4101B4]00403BFD  |.  A3 B8014100   mov     dword ptr [4101B8], eax00403C02  |.  50            push    eax00403C03  |.  FF35 AC014100 push    dword ptr [4101AC]  ;-->全局变量00403C09  |.  FF35 A8014100 push    dword ptr [4101A8]  ;-->全局变量00403C0F  |.  E8 ECD3FFFF   call    0040100000403C14  |.  83C4 0C       add     esp, 0C00403C17  |.  8945 E4       mov     dword ptr [ebp-1C], eax00403C1A  |.  50            push    eax00403C1B  |.  E8 39160000   call    00405259

main函数返回的结果被传递给紧接在它之后的那个函数(通常,这就是结束程序的函数)。我们进入到call  00405259内部,一步步步进,可进入到退出的程序:

0040527B  /$  57            push    edi0040527C  |.  6A 01         push    10040527E  |.  5F            pop     edi0040527F  |.  393D D4014100 cmp     dword ptr [4101D4], edi00405285  |.  75 11         jnz     short 0040529800405287  |.  FF7424 08     push    dword ptr [esp+8]                ; /ExitCode0040528B  |.  FF15 20B04000 call    dword ptr [<&KERNEL32.GetCurrent>; |[GetCurrentProcess00405291  |.  50            push    eax                              ; |hProcess00405292  |.  FF15 1CB04000 call    dword ptr [<&KERNEL32.TerminateP>; \TerminateProcess00405298  |>  837C24 0C 00  cmp     dword ptr [esp+C], 00040529D  |.  53            push    ebx0040529E  |.  8B5C24 14     mov     ebx, dword ptr [esp+14]004052A2  |.  893D D0014100 mov     dword ptr [4101D0], edi004052A8  |.  881D CC014100 mov     byte ptr [4101CC], bl004052AE  |.  75 3C         jnz     short 004052EC004052B0  |.  A1 F0064100   mov     eax, dword ptr [4106F0]004052B5  |.  85C0          test    eax, eax004052B7  |.  74 22         je      short 004052DB004052B9  |.  8B0D EC064100 mov     ecx, dword ptr [4106EC]004052BF  |.  56            push    esi004052C0  |.  8D71 FC       lea     esi, dword ptr [ecx-4]004052C3  |.  3BF0          cmp     esi, eax004052C5  |.  72 13         jb      short 004052DA004052C7  |>  8B06          /mov     eax, dword ptr [esi]004052C9  |.  85C0          |test    eax, eax004052CB  |.  74 02         |je      short 004052CF004052CD  |.  FFD0          |call    eax004052CF  |>  83EE 04       |sub     esi, 4004052D2  |.  3B35 F0064100 |cmp     esi, dword ptr [4106F0]004052D8  |.^ 73 ED         \jnb     short 004052C7004052DA  |>  5E            pop     esi004052DB  |>  68 88D04000   push    0040D088004052E0  |.  68 80D04000   push    0040D080004052E5  |.  E8 2A000000   call    00405314004052EA  |.  59            pop     ecx004052EB  |.  59            pop     ecx004052EC  |>  68 94D04000   push    0040D094004052F1  |.  68 8CD04000   push    0040D08C004052F6  |.  E8 19000000   call    00405314004052FB  |.  59            pop     ecx004052FC  |.  59            pop     ecx004052FD  |.  85DB          test    ebx, ebx004052FF  |.  5B            pop     ebx00405300  |.  75 10         jnz     short 0040531200405302  |.  FF7424 08     push    dword ptr [esp+8]                ; /ExitCode00405306  |.  893D D4014100 mov     dword ptr [4101D4], edi          ; |0040530C  |.  FF15 0CB04000 call    dword ptr [<&KERNEL32.ExitProces>; \ExitProcess00405312  |>  5F            pop     edi00405313  \.  C3            retn



 

原创粉丝点击