[PE結構分析] 8.輸入表結構和輸入地址表(IAT)

来源:http://www.cnblogs.com/night-ride-depart/archive/2016/08/16/5776107.html
-Advertisement-
Play Games

在 PE文件頭的 IMAGE_OPTIONAL_HEADER 結構中的 DataDirectory(數據目錄表) 的第二個成員就是指向輸入表的。每個被鏈接進來的 DLL文件都分別對應一個 IMAGE_IMPORT_DESCRIPTOR (簡稱IID) 數組結構。 typedef struct _IM... ...


在 PE文件頭的 IMAGE_OPTIONAL_HEADER 結構中的 DataDirectory(數據目錄表) 的第二個成員就是指向輸入表的。每個被鏈接進來的 DLL文件都分別對應一個 IMAGE_IMPORT_DESCRIPTOR (簡稱IID) 數組結構。

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;                  // 0 if not bound,
                                            // -1 if bound, and real date\time stamp
                                            // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                            // O.W. date/time stamp of DLL bound to (Old BIND)

    DWORD   ForwarderChain;                 // -1 if no forwarders
    DWORD   Name;
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

在這個 IID數組中,並沒有指出有多少個項(就是沒有明確指明有多少個鏈接文件),但它最後是以一個全為NULL(0) 的 IID 作為結束的標誌。

下麵只摘錄比較重要的欄位:

OriginalFirstThunk

它指向first thunk,IMAGE_THUNK_DATA,該 thunk 擁有 Hint 和 Function name 的地址。

Name

它表示DLL 名稱的相對虛地址(譯註:相對一個用null作為結束符的ASCII字元串的一個RVA,該字元串是該導入DLL文件的名稱。如:KERNEL32.DLL)。

FirstThunk

它包含由IMAGE_THUNK_DATA定義的 first thunk數組的虛地址,通過loader用函數虛地址初始化thunk。

在Orignal First Thunk缺席下,它指向first thunk:Hints和The Function names的thunks。

 

下麵來解釋下OriginalFirstThunk和FirstThunk。就個人理解而言:

1. 在文件中時,他們都分別指向一個RVA地址。這個地址轉換到文件中,分別對應兩個以 IMAGE_THUNK_DATA 為元素的的數組,這兩個數組是以一個填充為 0 的IMAGE_THUNK_DATA作為結束標識符。雖然他們這兩個表位置不同,但實際內容是一模一樣的。此時,每個 IMAGE_THUNK_DATA 元素指向的是一個記錄了函數名和相對應的DLL文件名的 IMAGE_IMPORT_BY_NAME結構體。

2. 為什麼會有兩個一模一樣的數組呢?是有原因的:

OriginalFirstThunk 指向的數組通常叫做  hint-name table,即 HNT ,他在 PE 載入到記憶體中時被保留了下來且永遠不會被修改。但是在 Windows 載入過 PE 到記憶體之後,Windows 會重寫 FirstThunk 所指向的數組元素中的內容,使得數組中每個 IMAGE_THUNK_DATA 不再表示指向帶有函數描述的 IMAGE_THUNK_DATA 元素,而是直接指向了函數地址。此時,FirstThunk 所指向的數組就稱之為輸入地址表(Import Address Table ,即經常說的 IAT)。

 

typedef struct _IMAGE_THUNK_DATA32 {
    union {
        DWORD ForwarderString;      // PBYTE  指向一個轉向者字元串的RVA
        DWORD Function;             // PDWORD 被輸入的函數的記憶體地址
         DWORD Ordinal;              // 被輸入的 API 的序數值
         DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME   指向 IMAGE_IMPORT_BY_NAME
    } u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

根據 _IMAGE_THUNK_DATA32 所指虛擬地址轉到文件地址可以得到實際的 _IMAGE_IMPORT_BY_NAME 數據

typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD   Hint;     // 序號 
    CHAR   Name[1];  // 實際上是一個可變長的以0為結尾的字元串
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

 

例如有程式:

00 源代碼圖片

文字版:

#include <windows.h>
int WINAPI WinMain(_In_ HINSTANCE hInstance, 
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR lpCmdLine,
    _In_ int nShowCmd)
{
    MessageBoxA(0, "hello", "my message", MB_OK);
    SetWindowTextA(0, "Si Wang");
    
    return 0;
}

此程式使用了兩個 Windows API : MessageBoxA 和 SetWindowTextA

編譯得到程式(為簡化說明,區段位置由軟體計算出):

0001c

0001a

我們試著找出 MessageBoxA。首先分析 PE 頭文件,找到導出表在文件中的位置:

001 輸入表地址

輸入表位置在 .rdata 區段內, 0x2264 – 0x2000 = 0x0264 得到偏移量。加上文件地址 0x0E00 得到實際文件偏移量(0x0E00 + 0x264 = 0x1064):0x1064。

接下來查看 0x1064 處:

002 dll表

可以得到三個 DLL 的描述,最後一個_IMAGE_IMPORT_DESCRIPTOR 以0填充表示結束:

那麼只要一個個查看每個DLL對應的數據就能找到,不過之前我把所有的數據都看了下,在第一個DLL中

根據第一個DLL描述的 OriginalFirstThunk 的 0x2350 轉換可以知道,_IMAGE_THUNK_DATA32 在文件的 0x1150處,FirstThunk 指向的數據相同:

003 IMAGE_THUNK_DATA 表

於是就得到了文件中的 MessageBoxA 的信息。

最後,在記憶體中 FirstThunk 所指位置上的_IMAGE_THUNK_DATA32 數組被 Windows 載入後被重寫後就成了傳說中的 IAT ,Import Address Table,輸入地址表。使用 OllyDbg 查看運行時情況:

記憶體情況


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 查看今天新增的文章、計算本月新增的用戶數等。這種類似的需求會有很多,也會很常見,可以使用sql的技巧來完成這些工作。 ...
  • 包(package)是多個函數的集合,常作為分享代碼的基本單元,代碼封裝成包可以方便其他用戶使用。越來越多的R包正在由世界上不同的人所創建並分發,這些分發的R包,可以從CRAN 或 github 上獲取,由於向 CRAN 提交包審核非常嚴格,有些開發者並沒有將自己開發的R包提至CRAN的意向,通過 ...
  • 參考文章:微信公眾號文章 在sql中怎麼查看一個字元的ascii編碼,so easy !! 結果是這樣的 還有一點,Unicode編碼只編碼第一個 ...
  • 黎俊傑 | 2016-07-28 14:37 聲明:部分表名為了脫敏而用XX代替 1、故障現象 (1)一個業務系統輸入用戶名與密碼後無法進入首頁,表現為一直在運行等待,運行緩慢 (2)整個系統無法正常使用,接近停運狀態 2、故障解決方法 調整資料庫參數alter system setevent='1... ...
  • 原創 2016-07-05 熊軍 Oracle 編輯手記:在理解Oracle技術細節時,我們不僅應該讀懂概念,還要能夠通過測試驗證細節,理解那些『功夫在詩外』的部分,例如全表掃描和單塊讀。 開發人員在進行新系統上線前的數據校驗測試時,發現一條手工執行的 SQL 執行了超過1小時還沒有返回結果。SQL... ...
  • 跟蹤標記:3604 功能: 輸出DBCC命令返回結果到查詢視窗(通常是SSMS視窗),類似print命令的顯示效果; 用途: 常用於獲取DBCC IND, DBCC PAGE命令的輸出結果,因為這2個命令預設不輸出任何結果。 舉例: 跟蹤標記:3605 功能: 輸出DBCC命令返回結果到SQL Se ...
  • 頁併發訪問的保護:閂鎖 在多線程併發情況下,需要防止讀線程讀到寫線程正在寫的資源,在編程中,通過使用互斥器(Mutexes), 信號量(Semaphore), 臨界區(Critical Section)和事件(Event Object)來保護資源,而這些機制在SQL Server中被統一表示為 閂鎖 ...
  • http://blog.csdn.net/cyuyan112233/article/details/50190927 http://beikeit.com/post-514.html ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...