Windows安全之PE結構(四) 之 導入表(IAT)與導入函數

來到這一章 , 開始進入人們熟悉的IAT, 一般從事安全的程序員都一定聽過IAT HOOK , EAT HOOK等等, 這些其實都是把PE文件中的一些表格的函數表,透過各類的形式給監聽了

可是我們要去HOOK一個表的函數, 我們一定要懂得他是什麼 我們才可以動手 , 不然很容易就崩潰了.





---------------------------------------------------------------------------------------

很多人認為 學PE結構十分費時, 可是假設你很想深入了解windows系統的編程,內核等知識,你一定需要

了解PE結構, 很多人問我 學這沒有結果,卻不是的, 很多病毒或防毒程序 也完全建基於PE結構的流程上

例如分頁內存注入病毒代碼 把之前說過的pe頭指向 分頁內存的00000000 隙中

廢話不多說

說第四章的重點 - 輸入表 又稱導入表

首先把之前的知識重新來一下總結, 然後再繼續下去講
PE文件被載入內存後 ,會把不同屬性的內存放在同一個區塊中,
例如輸入表 這是唯讀的屬性 可讀不可寫的屬性 這是可能會把只讀的常量放在同一個段 因為相同的屬性

我們的PE文件頭裡有一個IMAGE_OPTIONAL_HEADER32 裡有有一個DataDirectory的數組, 裡面有很多表的位置(PS這不是區塊表/節表),這數組他是用來查一些 已經定義好的表的地址, 例如輸入表 輸出表 重定位表等等......

要了解輸入表,我們必需知道什麼是 輸入函數(Import Function), 也稱導入函數, 輸入函數就是被程序

調用但其執行代碼又不在程序中的函數中,這些函數的代碼位於相關的DLL文件中

我們要用W32Dasm 這是一個靜態反匯編工具, 下面可以下載, 有些人不懂什麼是靜態和動態, 意思就是

把程序本來的代碼給反匯編,可不包外部檔如DLL檔, 可是動態是一直去挖所有地方也會去一次由調試器帶領.

這是一個簡單的只調用了MessageBox函數的程序 超簡單 是為了方便學習調試.
代碼:






透過w32dasm程序 反匯編他






得出了以上結果 , 我在看紅線的那個數值 是導入表的數值 可是我們現在沒有學習導入表的運作,不知怎麼去看這個地址,

由於現在我們不知道輸入表是什麼東西,

那我嘗試查一下MessageBox究竟在哪裡, 利用查找功能 去查找MessageBox的位置

如圖:









在紅框裡可以看到函通調用是通過push(入棧)進行函數傳遞, 不懂的可要看一下匯編語言(assembly language)的基礎 由其是函數調用約定, 這裡主要講一下PE結構.. 遲些可能會開一些章節有關匯編的


看到這個call dword ptr [0x00418350];

這個CALL應該是在這個地址裡頭我們去看看













我們發現了00418350H , 這是因為dll不在程序的代碼範圍內, 其實他是一個虛擬地址RVA, 我們可以透過一個RVA轉為上一章教的 把虛擬地址換算為物理地址

找到了區塊的虛擬地址首地址 還記得一般加載起的Image是在0x00400000h?
這個地址是0x00418350 - 0x00400000 就是18350H










得到了偏移 我們透過該偏移地址 定位他究竟在哪一個區塊當中, 如圖 18000H 是.idata段 , 這符合了我們的函數是導入的,因為.idata段是靜態只讀的區塊, 我們再計算 18000h 與 18350h 相差多少, 350H

那這時 獲取 RawDataOffset , 物理偏移地址, 00005A00 加上偏移 350 = 0x00005D50H










我們用UltraEdit 把整個PE文件 再搜索一下, 這裡像是一個沒用的數據, 可是我們嘗試一下 把他取出地址, 這個數據一定是一個雙字(4byte)的數據因為地址吧32位的地址, 0x00018380 這個值在.idata的所成 (這裡要注意, little-endian的制印,讀取字節方式都要倒轉來讀的,這是Intel CPU的讀取方式 18380H這個我們估計是虛擬偏移地址(跟區塊首地節相約), 把他轉到物理偏移地址看看.

虛擬偏移 = 18380H - 18000H = 380H
物理偏移 = 5A00H + 380H = 5D80H
取得物理偏移我們來查一下 他在硬盤裡頭到底存放在哪呢 , 好 如上圖所示 5d80h 的位置 猜中了, 其實在沒有導入表的情況下
我們可以透過這樣跟蹤的方式去查看一下 目標函數名稱放在哪....

簡單總結一下:

1. 首先取得目標函數地址的偏移 如 0x000418350H , 預設程序首加載地址 因此 地址為 0x000418350 - 0x00040000 = 18350H

2. 取得18350H這個值後 我們可以去定位,0x00018350這個虛擬偏移到底在哪個區塊呢? 透過LoadPE這個程序 我們可以知道 0x00018350這個地址是在.idata區塊中

3. 把區塊的首地址與目標地址相減 得出偏移地址 , 18350h-18000h = 350h

4. 350h 這個是個偏移地址 在win系統下,物理和虛擬內存也是一樣的,因此350H(偏移) + 0x00005A00(物理首地址) = 0x00005D50這個地址

5. 然後裡面存放著一個像是虛擬地址的值, 0x00018380, 我們照做一次 地址轉換, 偏移為380H ,物理偏移為 0x00005A00 + 380h = 0x00005D80;

6. 到此我們找到了實際messagebox的函數名的存放位置 可是這代表什麼呢? 下一章再分析 這一章主要講解沒有理解導入表的情況下, 怎麼利用靜態逆向分析找出導入函數(import function)的物理地址。

Comments

Popular posts from this blog

Android Kernel Development - Kernel compilation and Hello World

How does Nested-Virtualization works?

Understanding ACPI and Device Tree