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

一般的可执行恶意样本的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
                  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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值