病毒常用方法之回到起點---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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章