zl程序教程

您现在的位置是:首页 >  其他

当前栏目

二进制代码逆向——如何寻找main入口,先找mainCRTStartup,common_main,common_main_seh,invoke_main,main然后就是main函数

二进制代码 如何 函数 逆向 就是 寻找 main
2023-09-14 09:11:45 时间
第二节 2.3找程序的入口
原文:https://www.showdoc.com.cn/fengxin1225/7054696489361869,加入了自己的理解

控制台应用程序的main函数入口

 

 


在OD中找到以上其他中的函数,然后跟着3个参数的CALL就是main

例:

———————————————————-

我在vs2022里编译一个程序,看下和c的区别,如下:

#include <stdio.h>

int add(int x, int y) 
{
	return x + y;
}

int main(int argc, char* argv[])
{
	int (*sub)(int, int);
	int x = add(3, 4);
	printf("%d\n", x);
	return 0;
}

 

 

反汇编的代码:

 --- D:\source\test27\Conso\Conso\Conso.cpp -------------------------------------
Conso.exe!main(int, char * *):
001218A0 55                   push        ebp  
001218A1 8B EC                mov         ebp,esp  
001218A3 81 EC D8 00 00 00    sub         esp,0D8h  
001218A9 53                   push        ebx  
001218AA 56                   push        esi  
001218AB 57                   push        edi  
001218AC 8D 7D E8             lea         edi,[ebp-18h]  
001218AF B9 06 00 00 00       mov         ecx,6  
001218B4 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
001218B9 F3 AB                rep stos    dword ptr es:[edi]  
001218BB B9 08 C0 12 00       mov         ecx,offset _F4F12A98_Conso@cpp (012C008h)  
001218C0 E8 56 FA FF FF       call        @__CheckForDebuggerJustMyCode@4 (012131Bh)  
001218C5 6A 04                push        4  
001218C7 6A 03                push        3  
001218C9 E8 EE F9 FF FF       call        add (01212BCh)  
001218CE 83 C4 08             add         esp,8  
001218D1 89 45 EC             mov         dword ptr [x],eax  
001218D4 8B 45 EC             mov         eax,dword ptr [x]  
001218D7 50                   push        eax  
001218D8 68 30 7B 12 00       push        offset string "%d\n" (0127B30h)  
001218DD E8 EB F7 FF FF       call        _printf (01210CDh)  
001218E2 83 C4 08             add         esp,8  
001218E5 33 C0                xor         eax,eax  
001218E7 5F                   pop         edi  
001218E8 5E                   pop         esi  
001218E9 5B                   pop         ebx  
001218EA 81 C4 D8 00 00 00    add         esp,0D8h  
001218F0 3B EC                cmp         ebp,esp  
001218F2 E8 48 F9 FF FF       call        __RTC_CheckEsp (012123Fh)  
001218F7 8B E5                mov         esp,ebp  
001218F9 5D                   pop         ebp  
001218FA C3                   ret 

看下调用stack:

 

 

 

--- D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl --------
Conso.exe!invoke_main(void):
001221B0 55                   push        ebp  
001221B1 8B EC                mov         ebp,esp  
001221B3 83 EC 0C             sub         esp,0Ch  
001221B6 E8 D9 F0 FF FF       call        __get_initial_narrow_environment (0121294h)  
001221BB 89 45 FC             mov         dword ptr [ebp-4],eax  
001221BE E8 DB F0 FF FF       call        ___p___argv (012129Eh)  
001221C3 8B 00                mov         eax,dword ptr [eax]  
001221C5 89 45 F8             mov         dword ptr [ebp-8],eax  
001221C8 E8 97 EE FF FF       call        ___p___argc (0121064h)  
001221CD 8B 08                mov         ecx,dword ptr [eax]  
001221CF 89 4D F4             mov         dword ptr [ebp-0Ch],ecx  
001221D2 8B 55 FC             mov         edx,dword ptr [ebp-4]  
001221D5 52                   push        edx  
001221D6 8B 45 F8             mov         eax,dword ptr [ebp-8]  
001221D9 50                   push        eax  
001221DA 8B 4D F4             mov         ecx,dword ptr [ebp-0Ch]  
001221DD 51                   push        ecx  
001221DE E8 ED F0 FF FF       call        _main (01212D0h)  
001221E3 83 C4 0C             add         esp,0Ch  
001221E6 8B E5                mov         esp,ebp  
001221E8 5D                   pop         ebp  
001221E9 C3                   ret 



--- D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl --------
Conso.exe!__scrt_common_main_seh(void):
00121EE0 55                   push        ebp  
00121EE1 8B EC                mov         ebp,esp  
00121EE3 6A FE                push        0FFFFFFFEh  
00121EE5 68 88 91 12 00       push        129188h  
00121EEA 68 50 3A 12 00       push        offset _except_handler4 (0123A50h)  
00121EEF 64 A1 00 00 00 00    mov         eax,dword ptr fs:[00000000h]  
00121EF5 50                   push        eax  
00121EF6 83 C4 CC             add         esp,0FFFFFFCCh  
00121EF9 53                   push        ebx  
00121EFA 56                   push        esi  
00121EFB 57                   push        edi  
00121EFC A1 20 A0 12 00       mov         eax,dword ptr [__security_cookie (012A020h)]  
00121F01 31 45 F8             xor         dword ptr [ebp-8],eax  
00121F04 33 C5                xor         eax,ebp  
00121F06 50                   push        eax  
00121F07 8D 45 F0             lea         eax,[ebp-10h]  
00121F0A 64 A3 00 00 00 00    mov         dword ptr fs:[00000000h],eax  
00121F10 89 65 E8             mov         dword ptr [ebp-18h],esp  
00121F13 6A 01                push        1  
00121F15 E8 89 F3 FF FF       call        ___scrt_initialize_crt (01212A3h)  
00121F1A 83 C4 04             add         esp,4  
00121F1D 0F B6 C0             movzx       eax,al  
00121F20 85 C0                test        eax,eax  
00121F22 75 07                jne         __scrt_common_main_seh+4Bh (0121F2Bh)  
00121F24 6A 07                push        7  
00121F26 E8 A6 F2 FF FF       call        ___scrt_fastfail (01211D1h)  
00121F2B C6 45 E7 00          mov         byte ptr [has_cctor],0  
00121F2F C7 45 FC 00 00 00 00 mov         dword ptr [ebp-4],0  
00121F36 E8 9F F3 FF FF       call        ___scrt_acquire_startup_lock (01212DAh)  
00121F3B 88 45 E6             mov         byte ptr [ebp-1Ah],al  
00121F3E 83 3D 50 A1 12 00 01 cmp         dword ptr [__scrt_current_native_startup_state (012A150h)],1  
00121F45 75 09                jne         __scrt_common_main_seh+70h (0121F50h)  
00121F47 6A 07                push        7  
00121F49 E8 83 F2 FF FF       call        ___scrt_fastfail (01211D1h)  
00121F4E EB 61                jmp         __scrt_common_main_seh+0D1h (0121FB1h)  
00121F50 83 3D 50 A1 12 00 00 cmp         dword ptr [__scrt_current_native_startup_state (012A150h)],0  
00121F57 75 54                jne         __scrt_common_main_seh+0CDh (0121FADh)  
00121F59 C7 05 50 A1 12 00 01 00 00 00 mov         dword ptr [__scrt_current_native_startup_state (012A150h)],1  
00121F63 68 18 76 12 00       push        offset __xi_z (0127618h)  
00121F68 68 0C 73 12 00       push        offset __xi_a (012730Ch)  
00121F6D E8 01 F1 FF FF       call        __initterm_e (0121073h)  
00121F72 83 C4 08             add         esp,8  
00121F75 85 C0                test        eax,eax  
00121F77 74 16                je          __scrt_common_main_seh+0AFh (0121F8Fh)  
00121F79 C7 45 C8 FF 00 00 00 mov         dword ptr [ebp-38h],0FFh  
00121F80 C7 45 FC FE FF FF FF mov         dword ptr [ebp-4],0FFFFFFFEh  
00121F87 8B 45 C8             mov         eax,dword ptr [ebp-38h]  
00121F8A E9 53 01 00 00       jmp         $LN18+44h (01220E2h)  
00121F8F 68 08 72 12 00       push        offset __xc_z (0127208h)  
00121F94 68 00 70 12 00       push        offset __xc_a (0127000h)  
00121F99 E8 BE F3 FF FF       call        __initterm (012135Ch)  
00121F9E 83 C4 08             add         esp,8  
00121FA1 C7 05 50 A1 12 00 02 00 00 00 mov         dword ptr [__scrt_current_native_startup_state (012A150h)],2  
00121FAB EB 04                jmp         __scrt_common_main_seh+0D1h (0121FB1h)  
00121FAD C6 45 E7 01          mov         byte ptr [has_cctor],1  
00121FB1 0F B6 4D E6          movzx       ecx,byte ptr [ebp-1Ah]  
00121FB5 51                   push        ecx  
00121FB6 E8 B2 F1 FF FF       call        ___scrt_release_startup_lock (012116Dh)  
00121FBB 83 C4 04             add         esp,4  
00121FBE E8 88 F0 FF FF       call        ___scrt_get_dyn_tls_init_callback (012104Bh)  
00121FC3 89 45 E0             mov         dword ptr [ebp-20h],eax  
00121FC6 8B 55 E0             mov         edx,dword ptr [ebp-20h]  
00121FC9 83 3A 00             cmp         dword ptr [edx],0  
00121FCC 74 33                je          __scrt_common_main_seh+121h (0122001h)  
00121FCE 8B 45 E0             mov         eax,dword ptr [ebp-20h]  
00121FD1 50                   push        eax  
00121FD2 E8 4B F1 FF FF       call        ___scrt_is_nonwritable_in_current_image (0121122h)  
00121FD7 83 C4 04             add         esp,4  
00121FDA 0F B6 C8             movzx       ecx,al  
00121FDD 85 C9                test        ecx,ecx  
00121FDF 74 20                je          __scrt_common_main_seh+121h (0122001h)  
00121FE1 8B 55 E0             mov         edx,dword ptr [ebp-20h]  
00121FE4 8B 02                mov         eax,dword ptr [edx]  
00121FE6 89 45 C4             mov         dword ptr [ebp-3Ch],eax  
00121FE9 6A 00                push        0  
00121FEB 6A 02                push        2  
00121FED 6A 00                push        0  
00121FEF 8B 4D C4             mov         ecx,dword ptr [ebp-3Ch]  
00121FF2 89 4D D8             mov         dword ptr [ebp-28h],ecx  
00121FF5 8B 4D D8             mov         ecx,dword ptr [ebp-28h]  
00121FF8 FF 15 00 D0 12 00    call        dword ptr [__guard_check_icall_fptr (012D000h)]  
00121FFE FF 55 D8             call        dword ptr [ebp-28h]  
00122001 E8 31 F0 FF FF       call        ___scrt_get_dyn_tls_dtor_callback (0121037h)  
00122006 89 45 DC             mov         dword ptr [ebp-24h],eax  
00122009 8B 55 DC             mov         edx,dword ptr [ebp-24h]  
0012200C 83 3A 00             cmp         dword ptr [edx],0  
0012200F 74 21                je          __scrt_common_main_seh+152h (0122032h)  
00122011 8B 45 DC             mov         eax,dword ptr [ebp-24h]  
00122014 50                   push        eax  
00122015 E8 08 F1 FF FF       call        ___scrt_is_nonwritable_in_current_image (0121122h)  
0012201A 83 C4 04             add         esp,4  
0012201D 0F B6 C8             movzx       ecx,al  
00122020 85 C9                test        ecx,ecx  
00122022 74 0E                je          __scrt_common_main_seh+152h (0122032h)  
00122024 8B 55 DC             mov         edx,dword ptr [ebp-24h]  
00122027 8B 02                mov         eax,dword ptr [edx]  
00122029 50                   push        eax  
0012202A E8 D0 F0 FF FF       call        __register_thread_local_exe_atexit_callback (01210FFh)  
0012202F 83 C4 04             add         esp,4  
00122032 E8 79 01 00 00       call        invoke_main (01221B0h)  
00122037 89 45 D4             mov         dword ptr [ebp-2Ch],eax  
0012203A E8 AF F2 FF FF       call        ___scrt_is_managed_app (01212EEh)  
0012203F 0F B6 C8             movzx       ecx,al  
00122042 85 C9                test        ecx,ecx  
00122044 75 09                jne         __scrt_common_main_seh+16Fh (012204Fh)  
00122046 8B 55 D4             mov         edx,dword ptr [ebp-2Ch]  
00122049 52                   push        edx  
0012204A E8 AF F1 FF FF       call        _exit (01211FEh) 

...

 

结合C++反汇编逆向分析这本书里提到的:

 

 

 

总结下来就是找mainCRTStartup,common_main,common_main_seh,invoke_main,main然后就是main函数了!

 

上面vs2022的代码,我们再来使用odb分析下:

打开ODB,一开始看到的是:

 也就是odb一开始就是给你找到mainCRTStartup,然后进入:

 

 就到了common_main,继续走进去:

 

 就到了common_main_seh,这个代码比较多,我们直接找invoke_main,翻了大概1-2页的ODB汇编代码,看到invoke_main

 

 跟进去,然后如下,终于看到了三个push的main函数了!!!

 

紫色行进入,就只最终的main函数了:

 

 其他补充:

 

 

 说的应该就是invoke_main了!

 

 

第四课 如何判断参数的个数

1、如何判断参数个数

 

 

2、可能通过使用寄存器

 

 

3、下面的 mov ecx,12h 不可能参数,因为参数是从函数外面传进来,而不是在函数内部直接赋值

 

 


4、找参数个数的公式

 

 

第四课 逆向函数的步骤

逆向函数的步骤

1、分析参数

2、分析局部变量

3、分析全局变量

4、功能分析

5、返回值分析

 

第六课 如何得到返回值

如何得到返回值:

1、通过EAX得到返回值

2、通过定义指针得到返回值

3、通过全局变量得到返回值

返回值是怎么返回数据的

返回值是怎么返回数据的

1、8位返回值,使用AL寄存器返回数据

2、16位返回值,使用AX寄存器返回数据

3、32位返回值,使用EAX寄存器返回数据

4、64位返回值,使用EAX存低32位数据,使用EDX存高32位数据

因EAX通常用作返回值寄存器,逆向操作时,可以在CALL指令下断点,执行后看EAX的值有没发生变化。

返回复杂的结构体,todo

 

第二节 2.4.1逆向并还原为C代码(网上解答)

逆向CallingConvention.exe,还原为C代码,记录过程。该程序可以自己去生成一个:

#include <iostream>
#include<Windows.h>
#include<stdio.h>

int functionC(int a, int b)
{
    return a + b;
}

int functionB(int a,int b,int c)
{
    return a + b + c;
}

int functionA(int a, int b, int c, int d, int e)
{
    int x, y;
    x = functionB(a, b, c);
    y = functionC(a, b);
    return y = functionC(x, y);
}

int main()
{
    int result = functionA(1, 3, 4, 6, 7);
    printf("结果是:%d\n", result);
    system("pause");
return 0; }

 


程序入口

 

 


main函数

 

 


通过Main函数识别出来程序大致框架如下:

函数3为编译器自动添加的堆栈平衡检查函数


void __fastcall func1(int a,int b,int c,int d,int e){

}
void  __cdecl func2(int x,int y){

}
void main(int argc,char *argv[])
{
    func1(1,3,4,6,7);
    func2(m,n);
}

func1函数

 

 

从以上汇编代码识别出func1的框架如下:

void __fastcall func1(int a,int b,int c,int d,int e){
    int x=1;
    int y=3;
    func3(x,y,c);
    func4();
    func4();
}

func3函数

 

 

func3函数大致框架如下:

int __cdecl func3(int x,int y,it z)
{
    return x+y+z;
}

func1函数补充如下:

void __fastcall func1(int a,int b,int c,int d,int e){
    int x=1;
    int y=3;
    int z=func3(x,y,c);
    func4(x,y);
    func4();
}

func4函数

 

 

func4的函数框架如下:

int cdecl func4(int x.int y)
{
    return x+y;
}

func1函数补充如下:

void __fastcall func1(int a,int b,int c,int d,int e){
    int x=1;
    int y=3;
    int z=func3(x,y,c);
    int p=func4(x,y);
    func4(p,z); //运算后eax=0C
}

到此,func1基本逆向完成,回到main函数,继续func2的逆向,如下:

func2函数==》注意:这个是printf函数的汇编!

 

 

进到func2函数内部,发现其应该是printf函数,那么回到main函数,继续完善,如下:

Main函数


int cdecl func4(int x,int y)
{
    return x+y;
}
void __fastcall func1(int a,int b,int c,int d,int e){
    int x=1;
    int y=3;
    int z=func3(x,y,c);
    int p=func4(x,y);
    func4(p,z); //运算后eax=0C
}
void main(int argc,char *argv[])
{
    printf("%d",func1(1,3,4,6,7));
}

上面的答案有瑕疵,比如函数返回值啥的void错误:

完善后代码如下:


#include <iostream>
#include<Windows.h>
#include<stdio.h>

int functionC(int a, int b)
{
    return a + b;
}

int functionB(int a,int b,int c)
{
    return a + b + c;
}

int functionA(int a, int b, int c, int d, int e)
{
    int x, y;
    x = functionB(a, b, c);
    y = functionC(a, b);
    return y = functionC(x, y);
}

int main()
{
    int result = functionA(1, 3, 4, 6, 7);
    printf("结果是:%d\n", result);
    system("pause");
}