如果随便问一个windows程序员程序的执行是从哪里开始的,最可能听到的答案是WinMain,其实这是错误的,首先接收控制的是启动代码,它是编译器在不知不觉中插入到程
序之中的,在执行了必须的初始进程以后,启动代码才在某个时刻调用_wMain,现在来说,IDA可以识别出大部分的Main函数,但是,程序的执行可能不是从WInMain开始的,启动
代码可能有一个对理解算法至关重要的操作。因此,浏览器东代码可以确定它是否含有不一般的很有必要的。现在已win32控制台程序为例
.text:00401111 ; int __cdecl _tmainCRTStartup()
.text:00401111 __tmainCRTStartup proc near ; CODE XREF: _wmainCRTStartup+5j
.text:00401111
.text:00401111 Code = dword ptr -20h
.text:00401111 nested = dword ptr -1Ch
.text:00401111 ms_exc = CPPEH_RECORD ptr -18h
.text:00401111
.text:00401111 push 10h
.text:00401113 push offset unk_4021A8
.text:00401118 call __SEH_prolog4
.text:0040111D xor ebx, ebx
.text:0040111F cmp __NoHeapEnableTerminationOnCorruption, ebx
.text:00401125 jnz short loc_401132
.text:00401127 push ebx ; HeapInformationLength
.text:00401128 push ebx ; HeapInformation
.text:00401129 push 1 ; HeapInformationClass
.text:0040112B push ebx ; HeapHandle
.text:0040112C call ds:__imp__HeapSetInformation@16 ; HeapSetInformation(x,x,x,x)该函数的作用是启用堆被破坏的情况下可以被通知
.text:00401132
.text:00401132 loc_401132: ; CODE XREF: __tmainCRTStartup+14j
.text:00401132 mov [ebp+ms_exc.disabled], ebx
.text:00401135 mov eax, large fs:18h
.text:0040113B mov esi, [eax+4]
.text:0040113E mov [ebp+nested], ebx
.text:00401141 mov edi, offset ___native_startup_lock
.text:00401146
.text:00401146 loc_401146: ; CODE XREF: __tmainCRTStartup+59j
.text:00401146 push ebx ; Comperand在.text:00401128是程序管理器为该进程自行分配的堆的信息
.text:00401147 push esi ; Exchange
.text:00401148 push edi ; Destination;锁定的内存信息,它应该和堆信息是相等的
.text:00401149 call ds:__imp__InterlockedCompareExchange@12 ; InterlockedCompareExchange(x,x,x)将Destination和Compare相比如果相等就将Destination和Exchange交换
.text:00401149 ;该过程锁定内存操作,执行过程中不允许其他程序访问这是函数描述,其真实意义在于检测随机取得的内存地 ;址是否可用如果可用,则将esi置1作为该进程的起始地址1,如果该地址即[ebp+nested]不可用,则等待使用进程结束直到地址可用
.text:0040114F cmp eax, ebx
.text:00401151 jz short loc_40116C
.text:00401153 cmp eax, esi
.text:00401155 jnz short loc_40115F;//Destination 和Comprand不相等,则等待时机等待使用该内存的进程释放内存
.text:00401157 xor esi, esi
.text:00401159 inc esi
.text:0040115A mov [ebp+nested], esi
.text:0040115D jmp short loc_40116F
.text:0040115F ; ---------------------------------------------------------------------------
.text:0040115F
.text:0040115F loc_40115F: ; CODE XREF: __tmainCRTStartup+44j
.text:0040115F push 3E8h ; dwMilliseconds
.text:00401164 call ds:__imp__Sleep@4 ; Sleep(x) ;程序等待一会儿再执行
.text:0040116A jmp short loc_401146
.text:0040116C ; ---------------------------------------------------------------------------
.text:0040116C
.text:0040116C loc_40116C: ; CODE XREF: __tmainCRTStartup+40j
.text:0040116C xor esi, esi
.text:0040116E inc esi
.text:0040116F
.text:0040116F loc_40116F: ; CODE XREF: __tmainCRTStartup+4Cj
.text:0040116F mov eax, ___native_startup_state;表示进程起始状态,为1 则表示已经准备好
.text:00401174 cmp eax, esi
.text:00401176 jnz short loc_401182;//则表示进程还未准备好
.text:00401178 push 1Fh
.text:0040117A call __amsg_exit ;在InterlockedCompareExchange中的Destination和Comprand不相等的情况下退出
.text:0040117F pop ecx
.text:00401180 jmp short loc_4011BD
.text:00401182 ; ---------------------------------------------------------------------------
.text:00401182
.text:00401182 loc_401182: ; CODE XREF: __tmainCRTStartup+65j
.text:00401182 mov eax, ___native_startup_state
.text:00401187 test eax, eax
.text:00401189 jnz short loc_4011B7
.text:0040118B mov ___native_startup_state, esi
.text:00401191 push offset ___xi_z
.text:00401196 push offset ___xi_a
.text:0040119B call __initterm_e
.text:004011A0 pop ecx
.text:004011A1 pop ecx
.text:004011A2 test eax, eax
.text:004011A4 jz short loc_4011BD
.text:004011A6 mov [ebp+ms_exc.disabled], 0FFFFFFFEh
.text:004011AD mov eax, 0FFh
.text:004011B2 jmp loc_401294 ;表示程序未开始便已结束,遇到错误
.text:004011B7 ; ---------------------------------------------------------------------------
.text:004011B7
.text:004011B7 loc_4011B7: ; CODE XREF: __tmainCRTStartup+78j
.text:004011B7 mov has_cctor, esi
.text:004011BD
.text:004011BD loc_4011BD: ; CODE XREF: __tmainCRTStartup+6Fj
.text:004011BD ; __tmainCRTStartup+93j
.text:004011BD mov eax, ___native_startup_state
.text:004011C2 cmp eax, esi
.text:004011C4 jnz short loc_4011E1
.text:004011C6 push offset ___xc_z
.text:004011CB push offset ___xc_a
.text:004011D0 call __initterm
.text:004011D5 pop ecx
.text:004011D6 pop ecx
.text:004011D7 mov ___native_startup_state, 2
.text:004011E1
.text:004011E1 loc_4011E1: ; CODE XREF: __tmainCRTStartup+B3j
.text:004011E1 cmp [ebp+nested], ebx
.text:004011E4 jnz short loc_4011EE
.text:004011E6 push ebx ; Value
.text:004011E7 push edi ; Target
.text:004011E8 call ds:__imp__InterlockedExchange@8 ; InterlockedExchange(x,x)
.text:004011EE
.text:004011EE loc_4011EE: ; CODE XREF: __tmainCRTStartup+D3j
.text:004011EE cmp ___dyn_tls_init_callback, ebx
.text:004011F4 jz short loc_40120F
.text:004011F6 push offset ___dyn_tls_init_callback ; pTarget
.text:004011FB call __IsNonwritableInCurrentImage
.text:00401200 pop ecx
.text:00401201 test eax, eax
.text:00401203 jz short loc_40120F
.text:00401205 push ebx
.text:00401206 push 2
.text:00401208 push ebx
.text:00401209 call ___dyn_tls_init_callback
.text:0040120F
.text:0040120F loc_40120F: ; CODE XREF: __tmainCRTStartup+E3j
.text:0040120F ; __tmainCRTStartup+F2j
.text:0040120F mov eax, envp
.text:00401214 mov ecx, ds:__imp____winitenv
.text:0040121A mov [ecx], eax
.text:0040121C push envp
.text:00401222 push argv ; argv
.text:00401228 push argc ; argc
.text:0040122E call _wmain ;准备工作完成,调用主函数
.text:00401233 add esp, 0Ch
.text:00401236 mov mainret, eax
.text:0040123B cmp managedapp, ebx
.text:00401241 jnz short $LN37
.text:00401243 push eax ; Code
.text:00401244 call ds:__imp__exit
.text:0040124A ; ---------------------------------------------------------------------------
.text:0040124A
.text:0040124A $LN36: ; DATA XREF: .rdata:004021BCo
.text:0040124A mov eax, [ebp+ms_exc.exc_ptr]
.text:0040124D mov ecx, [eax]
.text:0040124F mov ecx, [ecx]
.text:00401251 mov [ebp+Code], ecx
.text:00401254 push eax
.text:00401255 push ecx
.text:00401256 call __XcptFilter
.text:0040125B pop ecx
.text:0040125C pop ecx
.text:0040125D
.text:0040125D $LN32:
.text:0040125D retn
.text:0040125E ; ---------------------------------------------------------------------------
.text:0040125E
.text:0040125E $LN22: ; DATA XREF: .rdata:004021C0o
.text:0040125E mov esp, [ebp+ms_exc.old_esp]
.text:00401261 mov eax, [ebp+Code]
.text:00401264 mov mainret, eax
.text:00401269 xor ebx, ebx
.text:0040126B cmp managedapp, ebx
.text:00401271 jnz short $LN37
.text:00401273 push eax ; Code
.text:00401274 call ds:__imp___exit
.text:0040127A ; ---------------------------------------------------------------------------
.text:0040127A
.text:0040127A $LN37: ; CODE XREF: __tmainCRTStartup+130j
.text:0040127A ; __tmainCRTStartup+160j
.text:0040127A cmp has_cctor, ebx
.text:00401280 jnz short loc_401288
.text:00401282 call ds:__imp___cexit
.text:00401288
.text:00401288 loc_401288: ; CODE XREF: __tmainCRTStartup+16Fj
.text:00401288 mov [ebp+ms_exc.disabled], 0FFFFFFFEh
.text:0040128F mov eax, mainret
.text:00401294
.text:00401294 loc_401294: ; CODE XREF: __tmainCRTStartup+A1j
.text:00401294 call __SEH_epilog4
.text:00401299 retn
.text:00401299 __tmainCRTStartup endp
.text:00401299
检测__native_startup_state流程图
if(___native_startup_state!=1)
{
loc_401182:
{
if(___native_startup_state!=0)
{
loc_4011B7: jmp loc_4011BD:
}
else
{
loc_401294;进程结束,未完成初始化
}
}
}
else
{
loc_4011BD:
}