首页
社区
课程
招聘
小白分析main函数入口之路
2017-11-30 21:10 6698

小白分析main函数入口之路

2017-11-30 21:10
6698
emm.首先看了一篇博客,找main函数的地址,那篇博客里的ida的start函数里直接是很多
初始化环境啊..GetCommandLine和和GetEnvironmentStringsA之类的
然后下面就直接调用main了,wa。。。。好容易啊可能是VC或者gcc编译出来的吧
代码如下
void __cdecl start()
{
  DWORD v0; // eax@1
  int v1; // eax@4

  v0 = GetVersion();
  dword_4101A4 = BYTE1(v0);
  dword_4101A0 = v0;
  dword_41019C = BYTE1(v0) + (v0 << 8);
  dword_410198 = v0 >> 16;
  if ( !sub_4068EE(0) )
    fast_error_exit(0x1Cu);
  _ioinit();
  dword_411704 = *GetCommandLineA*();
  dword_41017C = __crtGetEnvironmentStringsA();
  _setargv();
  _setenvp();
  _cinit();
  dword_4101B8 = envp;
  v1 = main(argc, argv, envp);
  exit(v1);
}
容易吧,都是显而易见的东西,然而我用的是vs2015...
光栈回溯就起码有5个函数之多
于是我把一个简单的helloworld程序放在ida里分析,是这样的
int start()
{
  return start_0();
}
天壤之别啊...然后我继续跟进
int start_0()
{
  return sub_411C20();
}
然后又调用了一个函数,接着跟
int sub_411C20()
{
  sub_4111F4();
  return sub_411C40();
}
出现了两个分支,首先点开第一个分支
unsigned int sub_4111F4(void)
{
  return sub_413230();
}
继续
unsigned int sub_413230()
{
  unsigned int result; // eax@2
  LARGE_INTEGER PerformanceCount; // [sp+0h] [bp-14h]@4
  struct _FILETIME SystemTimeAsFileTime; // [sp+8h] [bp-Ch]@1
  DWORD v3; // [sp+10h] [bp-4h]@4

  SystemTimeAsFileTime.dwLowDateTime = 0;
  SystemTimeAsFileTime.dwHighDateTime = 0;
  if ( __security_cookie != -1153374642 && (result = __security_cookie & 0xFFFF0000) != 0 )
  {
    dword_418024 = ~__security_cookie;
  }
  else
  {
    GetSystemTimeAsFileTime(&SystemTimeAsFileTime);
    v3 = SystemTimeAsFileTime.dwHighDateTime ^ SystemTimeAsFileTime.dwLowDateTime;
    v3 ^= GetCurrentThreadId();
    v3 ^= GetCurrentProcessId();
    QueryPerformanceCounter(&PerformanceCount);
    v3 ^= PerformanceCount.LowPart;
    v3 ^= PerformanceCount.HighPart;
    v3 ^= (unsigned int)&v3;
    if ( v3 == -1153374642 )
    {
      v3 = -1153374641;
    }
    else if ( !(v3 & 0xFFFF0000) )
    {
      v3 |= (v3 | 0x4711) << 16;
    }
    result = v3;
    __security_cookie = v3;
    dword_418024 = ~v3;
  }
  return result;
}
发现了这堆东西,大概和线程和编译器初始化还有文件时间security_cookie之类的东西有关,不管了,这里主要任务是寻找main
发现这里并没有出现main函数,和调用其他函数,那么main的调用一定在另一个函数里面了
sub_411C40
跟进却发现了一个问题
f5的时候出现sp-analysis failed 的错误...google一下。发现在ida官网有很多可能性导致这种情况的产生..
至少20种以上吧...
地址是https://www.hex-rays.com/products/decompiler/manual/failures.shtml
猜测可能是微软开发人员想增加逆向工作者的难度故意写了一些骚操作吧..
不能f5那么我们只能去看汇编指令寻找main了
首先找到那个sub_411C40这个函数的地址,ida自带有字符串搜索功能---在ida右上角
.text:00411C40
.text:00411C40 ; =============== S U B R O U T I N E =======================================
.text:00411C40
.text:00411C40 ; Attributes: bp-based frame
.text:00411C40
.text:00411C40 sub_411C40      proc near               ; CODE XREF: sub_411C20+8p
.text:00411C40
.text:00411C40 var_40          = dword ptr -40h
.text:00411C40 var_3C          = dword ptr -3Ch
.text:00411C40 var_38          = dword ptr -38h
.text:00411C40 var_34          = dword ptr -34h
.text:00411C40 var_30          = dword ptr -30h
.text:00411C40 Code            = dword ptr -2Ch
.text:00411C40 var_28          = dword ptr -28h
.text:00411C40 var_24          = dword ptr -24h
.text:00411C40 var_20          = dword ptr -20h
.text:00411C40 var_1A          = byte ptr -1Ah
.text:00411C40 var_19          = byte ptr -19h
.text:00411C40 ms_exc          = CPPEH_RECORD ptr -18h
.text:00411C40
.text:00411C40                 push    ebp             ; 这个函数做初始化工作,下面调用一个函数,得到环境变量和参数
.text:00411C41                 mov     ebp, esp
.text:00411C43                 push    0FFFFFFFEh
.text:00411C45                 push    offset stru_417E48
.text:00411C4A                 push    offset sub_413900
.text:00411C4F                 mov     eax, large fs:0
.text:00411C55                 push    eax
.text:00411C56                 add     esp, 0FFFFFFD0h
.text:00411C59                 push    ebx
.text:00411C5A                 push    esi
.text:00411C5B                 push    edi
.text:00411C5C                 mov     eax, ___security_cookie
.text:00411C61                 xor     [ebp+ms_exc.registration.ScopeTable], eax
.text:00411C64                 xor     eax, ebp
.text:00411C66                 push    eax
.text:00411C67                 lea     eax, [ebp+ms_exc.registration]
.text:00411C6A                 mov     large fs:0, eax
.text:00411C70                 mov     [ebp+ms_exc.old_esp], esp
.text:00411C73                 push    1
.text:00411C75                 call    sub_41127B
.text:00411C7A                 add     esp, 4
.text:00411C7D                 movzx   eax, al
.text:00411C80                 test    eax, eax
.text:00411C82                 jnz     short loc_411C8B
.text:00411C84                 push    7
.text:00411C86                 call    sub_41105A
.text:00411C8B
.text:00411C8B loc_411C8B:                             ; CODE XREF: sub_411C40+42j
.text:00411C8B                 mov     [ebp+var_19], 0
.text:00411C8F                 mov     [ebp+ms_exc.registration.TryLevel], 0
.text:00411C96                 call    sub_41130C
.text:00411C9B                 mov     [ebp+var_1A], al
.text:00411C9E                 cmp     dword_418160, 1
.text:00411CA5                 jnz     short loc_411CB0
.text:00411CA7                 push    7
.text:00411CA9                 call    sub_41105A
.text:00411CAE                 jmp     short loc_411D11
.text:00411CB0 ; ---------------------------------------------------------------------------
.text:00411CB0
.text:00411CB0 loc_411CB0:                             ; CODE XREF: sub_411C40+65j
.text:00411CB0                 cmp     dword_418160, 0
.text:00411CB7                 jnz     short loc_411D0D
.text:00411CB9                 mov     dword_418160, 1
.text:00411CC3                 push    offset unk_416618
.text:00411CC8                 push    offset unk_41630C
.text:00411CCD                 call    j__initterm_e
.text:00411CD2                 add     esp, 8
.text:00411CD5                 test    eax, eax
.text:00411CD7                 jz      short loc_411CEF
.text:00411CD9                 mov     [ebp+var_38], 0FFh
.text:00411CE0                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00411CE7                 mov     eax, [ebp+var_38]
.text:00411CEA                 jmp     loc_411E3B
.text:00411CEF ; ---------------------------------------------------------------------------
.text:00411CEF
.text:00411CEF loc_411CEF:                             ; CODE XREF: sub_411C40+97j
.text:00411CEF                 push    offset unk_416208
.text:00411CF4                 push    offset unk_416000
.text:00411CF9                 call    j__initterm
.text:00411CFE                 add     esp, 8
.text:00411D01                 mov     dword_418160, 2
.text:00411D0B                 jmp     short loc_411D11
.text:00411D0D ; ---------------------------------------------------------------------------
.text:00411D0D
.text:00411D0D loc_411D0D:                             ; CODE XREF: sub_411C40+77j
.text:00411D0D                 mov     [ebp+var_19], 1
.text:00411D11
.text:00411D11 loc_411D11:                             ; CODE XREF: sub_411C40+6Ej
.text:00411D11                                         ; sub_411C40+CBj
.text:00411D11                 movzx   ecx, [ebp+var_1A]
.text:00411D15                 push    ecx
.text:00411D16                 call    sub_411302
.text:00411D1B                 add     esp, 4
.text:00411D1E                 call    sub_411271
.text:00411D23                 mov     [ebp+var_20], eax
.text:00411D26                 mov     edx, [ebp+var_20]
.text:00411D29                 cmp     dword ptr [edx], 0
.text:00411D2C                 jz      short loc_411D5A
.text:00411D2E                 mov     eax, [ebp+var_20]
.text:00411D31                 push    eax
.text:00411D32                 call    sub_411348
.text:00411D37                 add     esp, 4
.text:00411D3A                 movzx   ecx, al
.text:00411D3D                 test    ecx, ecx
.text:00411D3F                 jz      short loc_411D5A
.text:00411D41                 push    0
.text:00411D43                 push    2
.text:00411D45                 push    0
.text:00411D47                 mov     edx, [ebp+var_20]
.text:00411D4A                 mov     eax, [edx]
.text:00411D4C                 mov     [ebp+var_28], eax
.text:00411D4F                 mov     ecx, [ebp+var_28]
.text:00411D52                 call    sub_4112BC
.text:00411D57                 call    [ebp+var_28]
.text:00411D5A
.text:00411D5A loc_411D5A:                             ; CODE XREF: sub_411C40+ECj
.text:00411D5A                                         ; sub_411C40+FFj
.text:00411D5A                 call    sub_4110C3
.text:00411D5F                 mov     [ebp+var_24], eax
.text:00411D62                 mov     ecx, [ebp+var_24]
.text:00411D65                 cmp     dword ptr [ecx], 0
.text:00411D68                 jz      short loc_411D8B
.text:00411D6A                 mov     edx, [ebp+var_24]
.text:00411D6D                 push    edx
.text:00411D6E                 call    sub_411348
.text:00411D73                 add     esp, 4
.text:00411D76                 movzx   eax, al
.text:00411D79                 test    eax, eax
.text:00411D7B                 jz      short loc_411D8B
.text:00411D7D                 mov     ecx, [ebp+var_24]
.text:00411D80                 mov     edx, [ecx]
.text:00411D82                 push    edx
.text:00411D83                 call    j__register_thread_local_exe_atexit_callback
.text:00411D88                 add     esp, 4
.text:00411D8B
.text:00411D8B loc_411D8B:                             ; CODE XREF: sub_411C40+128j
.text:00411D8B                                         ; sub_411C40+13Bj
.text:00411D8B                 call    sub_411F10      ; ************************************************************************************mark
.text:00411D90                 mov     [ebp+Code], eax
.text:00411D93                 call    sub_41111D
.text:00411D98                 movzx   eax, al
.text:00411D9B                 test    eax, eax
.text:00411D9D                 jnz     short loc_411DA8
.text:00411D9F                 mov     ecx, [ebp+Code]
.text:00411DA2                 push    ecx             ; Code
.text:00411DA3                 call    j_exit
.text:00411DA8 ; ---------------------------------------------------------------------------
.text:00411DA8
.text:00411DA8 loc_411DA8:                             ; CODE XREF: sub_411C40+15Dj
.text:00411DA8                 movzx   edx, [ebp+var_19]
.text:00411DAC                 test    edx, edx
.text:00411DAE                 jnz     short loc_411DB5
.text:00411DB0                 call    j__cexit
.text:00411DB5
.text:00411DB5 loc_411DB5:                             ; CODE XREF: sub_411C40+16Ej
.text:00411DB5                 push    0
.text:00411DB7                 push    1
.text:00411DB9                 call    sub_411159
.text:00411DBE                 add     esp, 8
.text:00411DC1                 mov     eax, [ebp+Code]
.text:00411DC4                 mov     [ebp+var_3C], eax
.text:00411DC7                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00411DCE                 mov     eax, [ebp+var_3C]
.text:00411DD1                 jmp     short loc_411E3B
.text:00411DD3 ; ---------------------------------------------------------------------------
.text:00411DD3                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00411DDA                 jmp     short loc_411E3B
.text:00411DDC ; ---------------------------------------------------------------------------
.text:00411DDC
.text:00411DDC loc_411DDC:                             ; DATA XREF: .rdata:stru_417E48o
.text:00411DDC                 mov     ecx, [ebp+ms_exc.exc_ptr] ; Exception filter 0 for function 411C40
.text:00411DDF                 mov     edx, [ecx]
.text:00411DE1                 mov     eax, [edx]
.text:00411DE3                 mov     [ebp+var_30], eax
.text:00411DE6                 mov     ecx, [ebp+ms_exc.exc_ptr]
.text:00411DE9                 push    ecx
.text:00411DEA                 mov     edx, [ebp+var_30]
.text:00411DED                 push    edx
.text:00411DEE                 call    j__seh_filter_exe
.text:00411DF3                 add     esp, 8
.text:00411DF6                 retn
.text:00411DF7 ; ---------------------------------------------------------------------------
.text:00411DF7
.text:00411DF7 loc_411DF7:                             ; DATA XREF: .rdata:stru_417E48o
.text:00411DF7                 mov     esp, [ebp+ms_exc.old_esp] ; Exception handler 0 for function 411C40
.text:00411DFA                 mov     eax, [ebp+var_30]
.text:00411DFD                 mov     [ebp+var_34], eax
.text:00411E00                 call    sub_41111D
.text:00411E05                 movzx   ecx, al
.text:00411E08                 test    ecx, ecx
.text:00411E0A                 jnz     short loc_411E15
.text:00411E0C                 mov     edx, [ebp+var_34]
.text:00411E0F                 push    edx             ; Code
.text:00411E10                 call    j__exit
.text:00411E15 ; ---------------------------------------------------------------------------
.text:00411E15
.text:00411E15 loc_411E15:                             ; CODE XREF: sub_411C40+1CAj
.text:00411E15                 movzx   eax, [ebp+var_19]
.text:00411E19                 test    eax, eax
.text:00411E1B                 jnz     short loc_411E22
.text:00411E1D                 call    j__c_exit
.text:00411E22
.text:00411E22 loc_411E22:                             ; CODE XREF: sub_411C40+1DBj
.text:00411E22                 mov     ecx, [ebp+var_34]
.text:00411E25                 mov     [ebp+var_40], ecx
.text:00411E28                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00411E2F                 mov     eax, [ebp+var_40]
.text:00411E32                 jmp     short loc_411E3B
.text:00411E34 ; ---------------------------------------------------------------------------
.text:00411E34                 mov     [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh
.text:00411E3B
.text:00411E3B loc_411E3B:                             ; CODE XREF: sub_411C40+AAj
.text:00411E3B                                         ; sub_411C40+191j ...
.text:00411E3B                 mov     ecx, [ebp+ms_exc.registration.Next]
.text:00411E3E                 mov     large fs:0, ecx
.text:00411E45                 pop     ecx
.text:00411E46                 pop     edi
.text:00411E47                 pop     esi
.text:00411E48                 pop     ebx
.text:00411E49                 mov     esp, ebp
.text:00411E4B                 pop     ebp
.text:00411E4C                 retn
.text:00411E4C sub_411C40      endp ; sp-analysis failed
emm大概就是这段,,有点长,
如果你想从上面一路往下找call也不是不可以
但是我是逆着来的。首先找到ida左边那一堆函数,找到和argc和argv有关的函数
我们可以双击到那个函数的地址
.text:00414BE2 __p___argc      proc near               ; CODE XREF: j___p___argcj
.text:00414BE2                 jmp     ds:__imp___p___argc
.text:00414BE2 __p___argc      endp
呐这是argc的,然后根据这个地址,也就是00414BE2
找到哪个函数调用过他--我用的是万能的搜索字符串大法
.text:00411F10 sub_411F10      proc near               ; CODE XREF: sub_411C40:loc_411D8Bp
.text:00411F10                 push    ebp
.text:00411F11                 mov     ebp, esp
.text:00411F13                 call    j__get_initial_narrow_environment
.text:00411F18                 push    eax
.text:00411F19                 call    j___p___argv
.text:00411F1E                 mov     eax, [eax]
.text:00411F20                 push    eax
.text:00411F21                 call    j___p___argc
.text:00411F26                 mov     ecx, [eax]
.text:00411F28                 push    ecx
.text:00411F29                 call    sub_411294
.text:00411F2E                 add     esp, 0Ch
.text:00411F31                 pop     ebp
.text:00411F32                 retn
.text:00411F32 sub_411F10      endp
发现这个函数调用了argv和argc还有j__get_initial_narrow_environment
这个类似与GetEnvironmentStringsA的函数
还有三个push,那么毋庸置疑,下面那个call sub_411294就是main了
我们继续,找到这个函数的地址
.text:00411294 sub_411294      proc near               ; CODE XREF: sub_411F10+19p
.text:00411294                 jmp     sub_411770      ; invoke_main ***************************************
.text:00411294 sub_411294      endp
发现他又调用了一个函数
我们继续这个函数就是main函数

.text:00411770
.text:00411770 ; =============== S U B R O U T I N E =======================================
.text:00411770
.text:00411770 ; Attributes: bp-based frame
.text:00411770
.text:00411770 sub_411770      proc near               ; CODE XREF: sub_411294j
.text:00411770
.text:00411770 var_C0          = byte ptr -0C0h
.text:00411770
.text:00411770                 push    ebp             ; main func************************************************************************finally i find you
.text:00411771                 mov     ebp, esp
.text:00411773                 sub     esp, 0C0h
.text:00411779                 push    ebx
.text:0041177A                 push    esi
.text:0041177B                 push    edi
.text:0041177C                 lea     edi, [ebp+var_C0]
.text:00411782                 mov     ecx, 30h
.text:00411787                 mov     eax, 0CCCCCCCCh
.text:0041178C                 rep stosd
.text:0041178E                 push    offset aHelloWorld ; "hello world"
.text:00411793                 call    sub_41131B
.text:00411798                 add     esp, 4
.text:0041179B                 mov     esi, esp
.text:0041179D                 push    offset Command  ; "pause"
.text:004117A2                 call    ds:system
.text:004117A8                 add     esp, 4
.text:004117AB                 cmp     esi, esp
.text:004117AD                 call    sub_411113
.text:004117B2                 xor     eax, eax
.text:004117B4                 pop     edi
.text:004117B5                 pop     esi
.text:004117B6                 pop     ebx
.text:004117B7                 add     esp, 0C0h
.text:004117BD                 cmp     ebp, esp
.text:004117BF                 call    sub_411113
.text:004117C4                 mov     esp, ebp
.text:004117C6                 pop     ebp
.text:004117C7                 retn
.text:004117C7 sub_411770      endp
哈哈,输出hello world
其实上面那个函数调用的是invoke_main
通过打印出vs2015的栈回溯就知道了

main   addr:  012FFB3C
main, d:\play\c++\c++\源.cp, line 111
invoke_main   addr:  012FFB40
invoke_main, f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl, line 64
__scrt_common_main_seh   addr:  012FFB44
__scrt_common_main_seh, f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl, line 253
__scrt_common_main   addr:  012FFB48
__scrt_common_main, f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl, line 296
mainCRTStartup   addr:  012FFB4C
mainCRTStartup, f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp, line 17
BaseThreadInitThunk   addr:  012FFB50

RtlGetAppContainerNamedObjectPath   addr:  012FFB54

RtlGetAppContainerNamedObjectPath   addr:  012FFB58
至于那个之前ida识别不出来的函数也就是
__scrt_common_main_seh了
那么现在来理一下
一开始的main也就是BaseThreadInitThunk
start_0就是mainCRTStartup
 sub_411C20就是__scrt_common_main
这么一来vs2015的全部调用的函数也就一清二楚了


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
打赏
分享
最新回复 (5)
雪    币: 1176
活跃值: (1219)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
Tennn 5 2017-11-30 21:20
2
0
不需要分析    有pdb  源码ide自带
雪    币: 83
活跃值: (1077)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
killpy 2 2017-11-30 21:24
3
0
其实  ida  不能f5分析  提示什么sp  错误  都是堆栈不对齐的原因  具体你可以百度一下 
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
holing 15 2017-11-30 21:53
4
1
有个最简单的方法,找exit函数,看传进去的参数,然后看看这个参数是哪个函数返回回来的,那个函数基本上就是main。然后sp分析失败你可以试试把函数undefine之后再重新新建函数
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
XzYxx 2017-12-1 00:02
5
0
6666666666  感谢分享
雪    币: 871
活跃值: (653)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
八岛 1 2017-12-1 10:42
6
0
太麻烦了,首先你得明白debug模式下的从入口点main函数的4个函数调用顺序,这样找invoke_main很方便,release就更简单了,3个push  一个call  ,其次记下特征码。。。直接搜就好了
游客
登录 | 注册 方可回帖
返回