PE檔案詳解六
前面兩篇講到了輸出表的內容以及涉及如何在hexWorkShop中找到輸出表及輸入DLL,感覺有幾個地方還是沒有理解好,比如由資料目錄表DataDirectory[16]找到輸出表表後以為找到輸入DLL就完了,其實這一流程的最終功能是通過輸入DLL找到輸入DLL呼叫的函式,這一步驟是通過輸出表結構中的OriginalFristThunk或者OriginalFristThunk所指向的INT或者IAT結構來找到的。這裡要說明的是,雖然一般情況通過OriginalFristThunk也行,但是有些情況下它的值被設定為0了,這樣就無法利用了,最委託的的方式是通過FristThunk所指向的IAT表來找尋。下面來通過例項實踐這一過程。
0x01 找尋輸入DLL以及輸入DLL呼叫的函式
材料及工具:名為PE.exe的可執行檔案,工具hexWrokshop,LordPE
思路:找到PE檔案頭——》找到資料目錄表第二項——》通過地址轉換找到輸出表陣列——》逐個讀出輸出表陣列的OriginalFristThunk,FristThunk值——》通過INT或者IAT逐個讀出被呼叫函式的名字地址——》通過名字地址找到函式名。
1)將目標檔案拖入hexWrokShop,快捷鍵ctrl+g跳往載入地址的3ch處,這裡即PE檔案頭地址,如下圖:
2)跳往40h處,該處即為檔案頭,如下圖:
3)跳往PE檔案頭+80h處,該處儲存了輸入資料表的地址如下圖:
4)將RVA=2040h轉化位FileOffset地址,這裡我們利用lordpe協助轉化,轉化後值為440h。
5)跳轉至440h處,該處即為輸出表IID陣列的資料所在,每項為五對雙字組成,結尾以五對雙字0。我這個例項一共兩組,如下圖:
將以上根據欄位資料統計如下表(PS:由於hex中是由低位到高位的故統計時應該注意高低位的換位):
OriginalFristThunk |
TimeStamp |
ForwardChain |
Name |
FristThunk |
0000208C |
00000000 |
00000000 |
00002174 |
00002010 |
0000207C |
00000000 |
00000000 |
000021B4 |
00002000 |
利用表中的Name欄位我們可以直接推出輸入DLL的名字,第一項Name的RVA為2174h,轉化為FileOffset值為:574h,跳往574h,我們可以看到第一個DLL為USER32.DLL,如下圖:
第二項的Name值為RVA值為21B4h,轉化位FileOffset值為5B4h,跳往574h,我們知道第二項DLL為KERNEL32.DLL,如下圖:
6)知道了輸入DLL不是我們目的終點,我們還要知道DLL所呼叫的所有函式名字地址,這裡有兩個欄位可用,第一個是OriginalFristThunk,它所指向的是一個名為輸入名稱表(INT)的結構,這個結構是由多個IMAGE_THUNK_DATA結構所組成的陣列。第二個是FristThunk,它所指向的是一個名稱為輸入地址表的(IAT)的結構,這個結構也是有多個IMAGE_THUNK_DATA結構所組成的陣列。IMAGE_THUNK_DATA雙字陣列的每項指向另一個結構——IMAGE_IMPORT_BY_NAME。最終通過IMAGE_IMPORT_BY_NAME找到被DLL呼叫的函式。一般而言,這兩個被指向的陣列值是相等的。我們接下來分別用兩個欄位來查詢。我們先用第一項的OriginalFristThunk來試試,將208C轉化為FileOffset得48ch。掉跳往48ch,的如下圖結果,共十一項,以雙字0結尾。
我們用FristThunk來試試,將2010h轉化為FileOffset得410h,跳往410h,可得下圖:
它們的值都為:
102100001C210000F4200000E0200000502100006421000002210000CE200000BC2000002E21000042210000,將資料按八個位元組拆分與翻轉的下表:
第一項指向的IAMGE_THUNK_DATA陣列
00002110 |
0000211C |
000020F4 |
000020E0 |
00002150 |
00002164 |
00002102 |
000020CE |
000020BC |
0000212E |
00002142 |
|
|
|
|
|
接下來進行地址轉換,的下表:
510 |
51c |
4f4 |
4e0 |
550 |
564 |
502 |
4ce |
4bc |
52e |
542 |
|
7)由上表逐個查詢出被呼叫函式名,如下圖:
重複以上操作的下表:
RVA |
FileOffset |
Hint |
函式名 |
00002110 |
510 |
019B |
LoadIconA |
0000211C |
51c |
01DD |
PostQuitMessage |
000020F4 |
4f4 |
0128 |
GetMessageA |
000020E0 |
4e0 |
0094 |
DispatchMessageA |
00002150 |
550 |
027D |
TranslateMessage |
00002164 |
564 |
028B |
UpdateWindow |
00002102 |
502 |
0197 |
LoadCursorA |
000020CE |
4ce |
0083 |
DefWindowProcA |
000020BC |
4bc |
0058 |
CreateWindowExA |
0000212E |
52e |
01EF |
RegisterClassExA |
00002142 |
542 |
0265 |
ShowWindow |
|
|
|
|
8)當然你可能會覺得這樣找輸入表實在太麻煩了,確實是,但是隻有經過這樣找你才能弄明白輸出表到底是如何存放的轉換的,從而對PE檔案格式有更為透徹理解。接下來我們通過強大的lordPE來輕鬆查詢到輸入表和輸入函式。如下圖: