Win32 PE病毒和普通Win32 PE程序一样需要调用API函数,但是普通的Win32 PE程序里面有一个导入函数表,该导入函数表对应了代码段中所用到的api函数在动态连接库中的真实地址(由PE Loader去填充这个地址的)。这样,调用api函数时就可以通过该导入函数表找到相应api函数的真正执行地址。
但是对于Win32 PE病毒来说,他只有一个代码段,他并不存在引入函数段。既然如此,病毒就无法象普通PE程序那样直接调用相关API函数,而应该先找出这些API函数在相应动态链接库中的地址。
我们知道通过LoadLibrary和GetProcAddress可以很方便的得到函数的地址,从而方便的去Call,而这两个函数是在kernel32.dll中被导出的,所以我们必须先得到kernel32.dll的基地址,然后再去找
nStart:
pop ebp
sub ebp, offset nStart
;得到kernel32加载的地址
mov dword ptr [ebp+appBase],ebp
mov eax,[esp] ;返回地址
xor edx,edx
Get_K32Base:
dec eax ;逐字节比较验证,速度比较慢,不过功能一样
mov dx,word ptr [eax+IMAGE_DOS_HEADER.e_lfanew] ;就是ecx+3ch
test dx,0f000h ;Dos Header+stub不可能太大,超过4096byte
jnz Get_K32Base ;加速检验,下一个
cmp eax,dword ptr [eax+edx+IMAGE_NT_HEADERS.OptionalHeader.ImageBase]
jnz Get_K32Base ;看Image_Base值是否等于ecx即模块起始值
mov [ebp+k32Base],eax ;如果是,就认为找到kernel32的模块装入地址
//这个是通过逐字节比较验证,速度比较慢,我们可以知道通过一页一页去比较,这个暂且不讨论
注意这一句 mov eax,[esp] 为什么此时[Esp]是在Kernel32.dll中内??
也就是为什么我们进入EntryPoint时esp是指向kernel32.dll的呢?(OS2003中此时的ESP = 0x77EIF38C)
我们来看看进程创建的整个过程
1 CreateProcessA call CreateProcessInternalA
2 CreateProcessInternalA call CreateProcessInternalW
3 CreateProcessInternalW call BasepInitializeContext
4 BasepInitializeContext mov dword ptr [eax+0B8h], offsetBaseProcessStart;//这里其实类似一个回调
//其实BaseProcessStart是我们程序在内核中真正启动地址!
5 BaseProcessStart所做的动作是:建立SEH,NtSetInformationThread(启动线程), ebp+8其实是我们的EntryPoint
具体阅读汇编代码和ReactOS代码(或者Nt4.0代码)
======================================================================
.text:77E48939 CreateProcessA proc near ; CODE XREF: LoadModule+13Dp
.text:77E48939
.text:77E48939 lpApplicationName= dword ptr 8
.text:77E48939 lpCommandLine = dword ptr 0Ch
.text:77E48939 lpProcessAttributes= dword ptr 10h
.text:77E48939 lpThreadAttributes= dword ptr 14h
.text:77E48939 bInheritHandles = dword ptr 18h
.text:77E48939 dwCreationFlags = dword ptr 1Ch
.text:77E48939 lpEnvironment = dword ptr 20h
.text:77E48939 lpCurrentDirectory= dword ptr 24h
.text:77E48939 lpStartupInfo = dword ptr 28h
.text:77E48939 lpProcessInformation= dword ptr 2Ch
.text:77E48939
.text:77E48939 push ebp
.text:77E4893A mov ebp, esp
.text:77E4893C push 0
.text:77E4893E push [ebp+lpProcessInformation]
.text:77E48941 push [ebp+lpStartupInfo]
.text:77E48944 push [ebp+lpCurrentDirectory]
.text:77E48947 push [ebp+lpEnvironment]
.text:77E4894A push [ebp+dwCreationFlags]
.text:77E4894D push [ebp+bInheritHandles]
.text:77E48950 push [ebp+lpThreadAttributes]
.text:77E48953 push [ebp+lpProcessAttributes]
.text:77E48956 push [ebp+lpCommandLine]
.text:77E48959 push [ebp+lpApplicationName]
.text:77E4895C push 0
.text:77E4895E call CreateProcessInternalA
.text:77E48963 pop ebp
.text:77E48964 retn 28h
.text:77E48964 CreateProcessA endp
======================================================================
.text:77E48A6D CreateProcessInternalA proc near ; CODE XREF: WinExec+3Fp
.text:77E48A6D ; WinExec+A4p ...
.text:77E48A6D
.text:77E48A6D ; FUNCTION CHUNK AT .text:77E488A4 SIZE 00000023 BYTES
.text:77E48A6D ; FUNCTION CHUNK AT .text:77E488F6 SIZE 0000000B BYTES
.text:77E48A6D ; FUNCTION CHUNK AT .text:77E48967 SIZE 00000101 BYTES
.text:77E48A6D
.text:77E48A6D push 98h
.text:77E48A72 push offset dword_77E542F0
.text:77E48A77 call sub_77E116F6
.text:77E48A7C xor ebx, ebx
.text:77E48A7E cmp [ebp+10h], ebx
.text:77E48A81 jz loc_77E488A9
.text:77E48A87 push dword ptr [ebp+10h]
.text:77E48A8A lea eax, [ebp-44h]
.text:77E48A8D push eax
.text:77E48A8E call sub_77E19AA8
.text:77E48A93 test eax, eax
.text:77E48A95 jz loc_77E488A4
.text:77E48A9B
.text:77E48A9B loc_77E48A9B: ; CODE XREF: CreateProcessInternalA-1B8j
.text:77E48A9B mov [ebp-4Ch], ebx
.text:77E48A9E mov [ebp-34h], ebx
.text:77E48AA1 push 11h
.text:77E48AA3 pop ecx
.text:77E48AA4 mov esi, [ebp+2Ch]
.text:77E48AA7 lea edi, [ebp-0A8h]
.text:77E48AAD rep movsd
.text:77E48AAF mov [ebp-0A4h], ebx
.text:77E48AB5 mov [ebp-0A0h], ebx
.text:77E48ABB mov [ebp-9Ch], ebx
.text:77E48AC1 mov [ebp-4], ebx
.text:77E48AC4 xor esi, esi
.text:77E48AC6 inc esi
.text:77E48AC7 mov [ebp-4], esi
.text:77E48ACA cmp [ebp+0Ch], ebx
.text:77E48ACD jnz loc_77E48A4D
.text:77E48AD3
.text:77E48AD3 loc_77E48AD3: ; CODE XREF: CreateProcessInternalA-12j
.text:77E48AD3 cmp [ebp+28h], ebx
.text:77E48AD6 jnz short loc_77E48B4E
.text:77E48AD8
.text:77E48AD8 loc_77E48AD8: ; CODE XREF: CreateProcessInternalA+F5j
.text:77E48AD8 mov eax, [ebp+2Ch]
.text:77E48ADB mov eax, [eax+4]
.text:77E48ADE cmp eax, ebx
.text:77E48AE0 jnz loc_77E489E3
.text:77E48AE6
.text:77E48AE6 loc_77E48AE6: ; CODE XREF: CreateProcessInternalA+18Aj
.text:77E48AE6 mov eax, [ebp+2Ch]
.text:77E48AE9 mov eax, [eax+8]
.text:77E48AEC cmp eax, ebx
.text:77E48AEE jnz loc_77E48971
.text:77E48AF4
.text:77E48AF4 loc_77E48AF4: ; CODE XREF: CreateProcessInternalA-8Fj
.text:77E48AF4 mov eax, [ebp+2Ch]
.text:77E48AF7 mov eax, [eax+0Ch]
.text:77E48AFA cmp eax, ebx
.text:77E48AFC jnz short loc_77E48B71
.text:77E48AFE
.text:77E48AFE loc_77E48AFE: ; CODE XREF: CreateProcessInternalA+16Bj
.text:77E48AFE mov [ebp-4], ebx
.text:77E48B01 mov eax, [ebp-40h]
.text:77E48B04 cmp eax, ebx
.text:77E48B06 jz loc_77E488F6
.text:77E48B0C
.text:77E48B0C loc_77E48B0C: ; CODE XREF: CreateProcessInternalA-171j
.text:77E48B0C push dword ptr [ebp+34h]
.text:77E48B0F push dword ptr [ebp+30h]
.text:77E48B12 lea ecx, [ebp-0A8h]
.text:77E48B18 push ecx
.text:77E48B19 push dword ptr [ebp-34h]
.text:77E48B1C push dword ptr [ebp+24h]
.text:77E48B1F push dword ptr [ebp+20h]
.text:77E48B22 push dword ptr [ebp+1Ch]
.text:77E48B25 push dword ptr [ebp+18h]
.text:77E48B28 push dword ptr [ebp+14h]
.text:77E48B2B push eax
.text:77E48B2C push dword ptr [ebp-4Ch]
.text:77E48B2F push dword ptr [ebp+8]
.text:77E48B32 call CreateProcessInternalW//-------@*@*@*@*@*@*@*@*@*@*@*@*@*@-------
.text:77E48B37 mov [ebp-1Ch], eax
.text:77E48B3A
.text:77E48B3A loc_77E48B3A: ; CODE XREF: CreateProcessInternalA-Aj
.text:77E48B3A or dword ptr [ebp-4], 0FFFFFFFFh
.text:77E48B3E call sub_77E48C0F
.text:77E48B43 mov eax, [ebp-1Ch]
.text:77E48B46
.text:77E48B46 loc_77E48B46: ; CODE XREF: CreateProcessInternalA:loc_77E488A4j
.text:77E48B46 call sub_77E11736
.text:77E48B4B retn 30h
======================================================================
CreateProcessInternalW+A50:
.......(省略)
.text:77E22A5A lea ecx, [ebp-344h]
.text:77E22A60 push ecx
.text:77E22A61 push eax
.text:77E22A62 push dword ptr [ebp-1F0h]
.text:77E22A68 push dword ptr [ebp-28h]
.text:77E22A6B call sub_77E1AA15
.text:77E22A70 mov [ebp-250h], eax
.text:77E22A76 cmp eax, ebx
.text:77E22A78 jl loc_77E23707
.text:77E22A7E push ebx
.text:77E22A7F push dword ptr [ebp-33Ch]
.text:77E22A85 push dword ptr [ebp-1FCh]
.text:77E22A8B push edi
.text:77E22A8C lea eax, [ebp-9A0h]
.text:77E22A92 push eax
.text:77E22A93 call sub_77E1ABE7//-------@*@*@*@*@*@*@*@*@*@*@*@*@*@-------
.......(省略)
======================================================================
BasepInitializeContext://ReactOs代码上是这样命名的
.text:77E1ABE7 sub_77E1ABE7 proc near ; CODE XREF: CreateRemoteThread+63p
.text:77E1ABE7 ; CreateProcessInternalW+A50p ...
.text:77E1ABE7
.text:77E1ABE7 arg_0 = dword ptr 8
.text:77E1ABE7 arg_4 = dword ptr 0Ch
.text:77E1ABE7 arg_8 = dword ptr 10h
.text:77E1ABE7 arg_C = dword ptr 14h
.text:77E1ABE7 arg_10 = dword ptr 18h
.text:77E1ABE7
.text:77E1ABE7 ; FUNCTION CHUNK AT .text:77E1AB94 SIZE 0000004E BYTES
.text:77E1ABE7
.text:77E1ABE7 push ebp
.text:77E1ABE8 mov ebp, esp
.text:77E1ABEA mov eax, [ebp+arg_0]
.text:77E1ABED mov ecx, [ebp+arg_8]
.text:77E1ABF0 push ebx
.text:77E1ABF1 mov [eax+0B0h], ecx
.text:77E1ABF7 mov ecx, [ebp+arg_4]
.text:77E1ABFA push esi
.text:77E1ABFB mov esi, [eax]
.text:77E1ABFD mov [eax+0A4h], ecx
.text:77E1AC03 push 20h
.text:77E1AC05 pop ecx
.text:77E1AC06 mov [eax+94h], ecx
.text:77E1AC0C mov [eax+98h], ecx
.text:77E1AC12 mov [eax+0C8h], ecx
.text:77E1AC18 mov ecx, [ebp+arg_C]
.text:77E1AC1B xor ebx, ebx
.text:77E1AC1D add ecx, 0FFFFFFFCh
.text:77E1AC20 cmp [ebp+arg_10], 1
.text:77E1AC24 lea edx, [eax+0C4h]
.text:77E1AC2A mov [eax+8Ch], ebx
.text:77E1AC30 mov dword ptr [eax+90h], 38h
.text:77E1AC3A mov dword ptr [eax+0BCh], 18h
.text:77E1AC44 mov dword ptr [eax], 10007h
.text:77E1AC4A mov dword ptr [eax+0C0h], 3000h
.text:77E1AC54 mov [edx], ecx
.text:77E1AC56 jz short loc_77E1AC72
.text:77E1AC58 cmp [ebp+arg_10], 2
.text:77E1AC5C jz loc_77E1AB94
.text:77E1AC62 mov dword ptr [eax+0B8h], offset loc_77E1F35F//-------@*@*@*@*@*@*@*@*@*@*@*@*@*@-------
.text:77E1AC6C
.text:77E1AC6C loc_77E1AC6C: ; CODE XREF: sub_77E1ABE7-40j
.text:77E1AC6C ; sub_77E1ABE7-17j ...
.text:77E1AC6C pop esi
.text:77E1AC6D pop ebx
.text:77E1AC6E pop ebp
.text:77E1AC6F retn 14h
======================================================================
BaseProcessStart:
.text:77E1F35F loc_77E1F35F: ; DATA XREF: sub_77E1ABE7+7Bo
.text:77E1F35F xor ebp, ebp
.text:77E1F361 push eax
.text:77E1F362 push 0
.text:77E1F364 nop
.text:77E1F365 nop
.text:77E1F366 nop
.text:77E1F367 nop
.text:77E1F368 nop
.text:77E1F369 push 0Ch
.text:77E1F36B push offset dword_77E522E0
.text:77E1F370 call sub_77E116F6(SEH)
.text:77E1F375 and dword ptr [ebp-4], 0
.text:77E1F379 push 4
.text:77E1F37B lea eax, [ebp+8]
.text:77E1F37E push eax
.text:77E1F37F push 9
.text:77E1F381 push 0FFFFFFFEh
.text:77E1F383 call ds:NtSetInformationThread
.text:77E1F389 call dword ptr [ebp+8];//我们程序的入口,(push 0x77E1F38C; jmp dword ptr [ebp+8])
.text:77E1F38C push eax
call exitthread;//我们程序正常退出时还要调用ExitThread!
posted on 2007-04-17 16:53 垃圾一堆 阅读(2395)
评论(0) 编辑 收藏