对乐,修改导入表还有个问题,如下面的代码直接在内存中搜寻 GetProcAddress() API函数地址。
moveax, [esp]
andeax, 0FFFF0000h
@@chk:
cmpdword ptr [eax], 00905A4Dh; 比较一下…… 5A4D就是文件头'MZ'
je@@fnd; 找到了文件头基址了!
subeax, 1000h; faint,找不到,减少1000h作为跨度
jmp@@chk; Go on!
@@fnd:
push ebp
push ebx
push esi
push edi
movebp, eax ;eax中为文件头基址
addeax, [eax][IMAGE_DOS_HEADER.e_lfanew] ;现在eax=[eax+3Ch],也就是PE文件头处
movedi, [eax][IMAGE_NT_HEADERS.OptionalHeader.DataDirectory]
addedi, ebp
movesi, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNames]
addesi, ebp
;在 kernel32.dll 里面查找 GetProcAddress 这个 API 的线形地址:
xoredx, edx
@@name:
moveax, [esi]
addeax, ebp
@@chgp:; GetProcAddress()
cmpdword ptr [eax+00h], "PteG"; GetP
jne@@next
cmpdword ptr [eax+04h], "Acor"; rocA
jne@@next
cmpdword ptr [eax+08h], "erdd"; ddre
jne@@next
cmpword ptr [eax+0Ch], "ss"; ss
jne@@next
moveax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals]
addeax, ebp
movzx ebx, word ptr [edx*2+eax]
moveax, [edi][IMAGE_EXPORT_DIRECTORY.AddressOfFunctions]
addeax, ebp
moveax, [ebx*4+eax]
addeax, ebp
;找到了,储存起来:
mov[_GetProcAddress], eax
@@next:
addesi, 4
incedx
cmpedx, [edi][IMAGE_EXPORT_DIRECTORY.NumberOfNames]
jne@@name