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的全部调用的函数也就一清二楚了
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!