您的位置:首页 > 其它

病毒常用方法之回到起点---PE文件

2018-03-12 10:30 435 查看
一般的可执行恶意样本的INT(导入名称表)在一定程度上就暴露了自己的行为,所以又来保护自己了。下面是一个样本中的实际应用,从PE文件结构入手。为了可以调用相关的API (由kernel32.dll ,ntdll.dll等导出,它先找到目标dll在内存中加载的地址(这些系统dll已经有系统加载到内存中),然后就是根据PE文件结构一顿操作,主要是通过导出名称字符生成一个DWORD数去比对,在找到FuncAddr。下面是相关操作的反汇编代码:

GetModuleAddr   proc near
push ebp
mov  ebp,esp
mov  eax,large fs:30h ;fs 寄存器指向当前线程环境块,是内核的结构,可以通过WinDbg去详细查看。在偏移为30h 的地方是Teb->ProcessEnvironmentBlock 进程环境块
mov  eax,[eax+0ch] ; Peb->Ldr
mov  eax,[eax+1ch];Ldr->InitializationOrderModuleList
mov  eax,[eax+8] ;由于系统的版本不一样,同一个dll加载的顺序可能不一样
pop  ebp
retn
GetModuleAddr   endp

;通过名称在ENT中找到该函数的导出序号,再去EAT得到地址就可以调用了
GetFuncAddr     proc near
var_24          = dword ptr -24h
var_20          = dword ptr -20h
var_1C          = dword ptr -1Ch
var_18          = dword ptr -18h
var_14          = dword ptr -14h
var_10          = dword ptr -10h ;该函数用的变量
var_C           = dword ptr -0Ch
var_8           = dword ptr -8
ExportDirectory = dword ptr -4
arg_0           = dword ptr  8
arg_4           = dword ptr  0Ch;3个参数
Addr            = dword ptr  10h
;可以对照PE结构文档看
push    ebp
mov     ebp, esp
sub     esp, 24h
mov     eax, [ebp+arg_0];模块地址
mov     eax, [eax+3Ch] ;3c---ImageDosHeader->e_lfanew PE文件头的偏移
mov     ecx, [ebp+arg_0]
lea     eax, [ecx+eax+18h];[eax+ecx]是PE文件头的地址,再加上18h 是扩展头的地址
mov     [ebp+var_10], eax
mov     eax, [ebp+var_10] ; OptionalHeader
mov     ecx, [ebp+arg_0]
add     ecx, [eax+60h]  ;IMAGE_DATA_DIRECTORY
mov     [ebp+ExportDirectory], ecx
mov     eax, [ebp+arg_4]
shr     eax, 10h ;右移10h位
movzx   eax, ax  ;去低16位
test    eax, eax
jnz     short loc_402672;是否使用原可执行文件中得到地址
mov     eax, [ebp+arg_4]
loc_40265F:
and     eax, 0FFFFh
movzx   eax, ax
mov     ecx, [ebp+ExportDirectory]
sub     eax, [ecx+10h]  ; Base
mov     [ebp+var_C], eax

4000
jmp     short loc_4026E9
loc_402672:
mov     eax, [ebp+ExportDirectory]
mov     ecx, [ebp+arg_0]
add     ecx, [eax+20h]  ; AddressOfNames
mov     [ebp+var_1C], ecx
mov     eax, [ebp+ExportDirectory]
mov     ecx, [ebp+arg_0]
add     ecx, [eax+24h]  ; AddressOfNameOrdinals
mov     [ebp+var_24], ecx
and     [ebp+var_20], 0
jmp     short loc_4026A8
loc_402690:
mov     eax, [ebp+var_20]
inc     eax
mov     [ebp+var_20], eax
mov     eax, [ebp+var_1C]
add     eax, 4
mov     [ebp+var_1C], eax
mov     eax, [ebp+var_24]
inc     eax
inc     eax
mov     [ebp+var_24], eax
loc_4026A8:
mov     eax, [ebp+ExportDirectory]
mov     ecx, [ebp+var_20]
cmp     ecx, [eax+18h];NumberOfNames
jnb     short loc_4026DA  ;是否超过了导出名称数
push    [ebp+arg_4]
mov     eax, [ebp+var_1C]
mov     ecx, [ebp+arg_0]
add     ecx, [eax]
push    ecx
call    CompareStr ;匹配成功返回1
pop     ecx
pop     ecx
movzx   eax, al
test    eax, eax
jz      short loc_4026D8
mov     eax, [ebp+var_24]
movzx   eax, word ptr [eax]
mov     [ebp+var_C], eax;var_c目标序号
jmp     short loc_4026DA
loc_4026D8:
jmp     short loc_402690 ;匹配失败,往回走
loc_4026DA:
mov     eax, [ebp+ExportDirectory]
mov     ecx, [ebp+var_20]
cmp     ecx, [eax+18h]
jnz     short loc_4026E9
xor     eax, eax
jmp     short  locret_402715
loc_4026E9:
mov     eax, [ebp+ExportDirectory]
mov     ecx, [ebp+arg_0]
add     ecx, [eax+1Ch]  ; AddressOfFunctions
mov     [ebp+var_8], ecx
mov     eax, [ebp+var_C]
mov     ecx, [ebp+var_8]
mov     eax, [ecx+eax*4] ;最后从EAT中取出地址
mov     [ebp+var_18], eax
mov     eax, [ebp+arg_0]
add     eax, [ebp+var_18]
mov     [ebp+var_14], eax
mov     eax, [ebp+Addr]
mov     ecx, [ebp+var_14]
mov     [eax], ecx
xor     eax, eax
inc     eax             ; succeed
locret_402715:
leave
retn
GetFuncAddr     endp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  病毒 api 内存