手動確定IAT的地址與大小

from:[url]http://bbs.chinapyg.com/viewthread.php?tid=24623[/url]

 

當我們找到OEP後,用ImportREC的“IATAutoSearch”按鈕,一般情況下ImportREC可以自動識別出IAT地址與大小。但如果不能自動識別,就必須手動確定IAT地址與大小,然後將IAT的RVA與Size填進ImportREC,點擊“GetImport”按鈕就可得到輸入表。

  比如我們用OD打開一個notepad.upx.exe文件,來到OEP處:

  oep

  隨便找一個API函數調用語句,如:

  
004010D3  FF15E4634000 call  [4063E4]     ;kernel32.GetCommandLineA

  其中地址4063E4就是IAT中的一部分,在數據窗口下命令:D4063E4,顯示如下:

  

  上圖每一組數據都是指向一個API函數,如8D2C817C就是地址:7C812C8D,在OD裏按Ctrl+G,輸入7C812C8D跳到這個地址就會發現是kernel32.GetCommandLineA函數:

 




  IAT是一塊連續排列的數據,因此在數據窗口向上翻屏,直到出現00數據,尋找IAT起始地址:

 
然後向下翻屏,尋找IAT結束地址:


 
爲了直觀些,你也可以這樣讓數據窗口直接顯示這些API函數,以確定IAT是否正確,在數據窗口點擊鼠標右鍵:

 

 
調整顯示格式後的數據窗口:


這樣就直觀了,IAT中每組數據指向一個API函數,各DLL之間是以000000分開的。

  因此IAT範圍:0x4062E4~0x406524,大小爲0x406524-0x4062E4=0x240

  如果IAT加密了,此時IAT中的地址不是指向系統DLL中的API函數了,可能指向外殼。這就十分有必要找到外殼處理IAT的代碼了,前面己說過,外殼加載時,會模擬Windows加載器,向IAT裏填充當前操作系統API函數的實際地址。所以,在IAT裏設個內存寫斷點,就可中斷到這段代碼處。

  重新加載notepad.upx.exe,在IAT某個地址下內存寫斷點,這裏選擇0x4062E4這個地址設內存寫斷點,先在數據窗口下命令:D4062E4


 然後選擇一個地址,點擊鼠標右鍵,下“內存寫斷點”。



此時只要有數據寫入4062E4地址處,OD就會中斷,按F9運行OD,會中斷這裏:

0040E96D  >/8A02     mov  al,[edx]
0040E96F  .|42      inc  edx
0040E970  .|8807     mov  [edi],al
0040E972  .|47      inc  edi
0040E973  .|49      dec  ecx
0040E974  .^75F7    jnz  short0040E96D


這段還不是處理IAT,按F9繼續執行程序,會中斷這裏:


0040E9E9  >/8A07     mov  al,[edi]
0040E9EB  .|47      inc  edi
0040E9EC  .|08C0     or   al,al
0040E9EE  .^|74DC    je   short0040E9CC
0040E9F0  .|89F9     mov  ecx,edi
0040E9F2  .|57      push  edi            //函數名字符串 
0040E9F3  .|48      dec  eax
0040E9F4  . F2:AE    repne scasbyteptres:[edi]
0040E9F6  .|55      push  ebp            //DLL模塊句柄
0040E9F7  . FF96A4EC0000call  [esi+ECA4]        ; kernel32.GetProcAddress
0040E9FD  .|09C0     or   eax,eax
0040E9FF  .|7407    je   short0040EA08
0040EA01  .|8903     mov  [ebx],eax        //EBX指向IAT,將取得的API地址填充進IAT
0040EA03  .|83C304   add  ebx,4          //指向下一個地址
0040EA06  .^EBE1    jmp  short0040E9E9
0040EA08  > FF96A8EC0000call  [esi+ECA8]



上面這段就是UPX外殼填充IAT的全過程,感興趣的,動態跟蹤一下就明白了。這裏用GetProcAddress函數獲得函數地址:


FARPROCGetProcAddress(
  HMODULEhModule,  //DLL模塊句柄
  LPCSTRlpProcName //函數名
);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章