1. 程式人生 > >PE檔案格式詳解(4)

PE檔案格式詳解(4)

1.RVA to RAW     PE檔案載入到記憶體時,每個節區都要準確完成記憶體地址與檔案偏移的對映。這種對映便稱為RVA to RAW,實現這個過程需要經過以下的步驟。     1.查詢RVA所在節區。     2.使用公式計算出檔案偏移。     根據IMAGE_SECTION_HEADER結構體,換算公式如下。     RAW - PoniterToRawData = RVA - VirtualAddress RAW  = RVA - VirtualAddress + PointerToRawData 2.IAT(Import Address Table,匯入地址表) IAT儲存的內容與Windows作業系統的核心進、記憶體、DLL結構等有關。(即掌握了IAT便掌握了Windows作業系統的根基)。
1.DLL(Dynamic Linked Library) 載入DLL的方式有兩種:一種是“顯式連結”(Explicit Linking),程式使用DLL時載入,使用完畢後釋放記憶體。另一種是“隱式連結”(Implicit Linking),程式開始時遍一同載入DLL,程式終止時,再釋放佔用的記憶體。IAT提供的機制便與隱式連結有關。     DLL重定位,DLL檔案的ImageBase一般為10000000.比如某個程式使用a.dll和b.dll,OE裝載器先把a.dll裝載到記憶體的10000000(ImageBase)處,然後嘗試把b.dll也裝載到該處。但是由於該地址處已經裝載了a.dll,所以PE裝載器需要查詢其他空白的記憶體空間(ex:3E000000),然後將b.dll裝載進去。這就是DLL檔案的重定位。
2.IMAGE_IMPOT_DESCRIPTOR IMAGE_IMPORT_DESCRIPTOR結構體中記錄著PE檔案要匯入哪些庫檔案。IMAGE_OPTIONAL_HEADER32.DataDirectory[1].VirtualAddress的值即是IMAGE_IMPORT_DESCRIPTOR結構體陣列的起始地址(RVA值)。(第一個4位元組為虛擬地址,第二個4位元組為Size成員。)   注:Import:匯入,向庫提供服務(函式)。                   Export:匯出,從庫向其他PE檔案提供服務(函式)。 程式碼 IMAGE_IMPORT_DESCRIPTOR
typedef struct _IMAGE_IMPORT_DESCRIPTOR{     union{     DWORD    Characteristics;     DWORD    OriginalFirstThunk;    //INT(Import Name Table) address (RVA)     };     DWORD    TimeDatastamp;     DWORD    ForwarderChain;     DWORD    Name;    // library name string address (RVA)     DWORD    FirstThunk;     // IAT( Import Address Table) address (RVA) } IMAGE_IMPORT_DESCRIPTOR; typedef struct _IMAGE_IMPORT_BY_NAME{     WORD    Hint;     // ordinal     BYTE   Name[1];  // function name string } IMAGE_IMPORT_BY_NAME , *PIMAGE_IMPORT_BY_NAME; 執行一個普通程式時往往需要匯入多個庫,匯入多少庫就存在多少個IMAGE_IMPORT_DESCRIPTOR結構體,這些結構體形成了陣列,且結構體陣列最後以NULL結構體結束。   IMAGE_IMPORT_DESCRIPTOR的重要成員如下     專案 含義     OriginalFirstThunk    INT的地址(RVA)     Name  庫名稱字串的地址(RVA)     FirstThunk  IAT的地址(RVA) 注:INT與IAT是長整型(4個位元組資料型別)陣列,以NULL結束(未另外明確指出大小)。         INT中各元素的值為IMAGE_IMPORT_BY_NAME結構體指標(有時IAT也有相同的值)。     INT與IAT的大小應相同。 3.EAT Windows作業系統中,“庫”是為了方便其他程式呼叫而集中包含相關函式的檔案(DLL/SYS)。Win32 API是最具代表性的庫,其中的kernel32.dll檔案稱為最核心的庫檔案。     EAT是一種核心機制,它使不同的應用程式可以條用庫檔案中提供的函式(即只有通過EAT才能準確求得從相應庫中匯出函式的起始地址)。PE檔案內部有且僅有一個用來說明庫EAT的IMAGE_EXPORT_DIRECTORY結構體,並且儲存著匯出資訊。   注:IAT的結構體以陣列的形式存在,且擁有多個成員。即說明PE檔案可以同時匯入多個庫。 可以在PE檔案的PE頭中查詢到IMAGE_EXPORT_DIRECTORY結構體的聞之。IMAGE_OPTIONAL_HEADER32.DataDirectory[0].VirtualAddress值即為結構身體陣列的其實地址(RVA值)。(第一個4位元組為虛擬地址,第二個4位元組為Size成員。)    程式碼  IMAGE_EXPORT_DIRECTORY結構體     typedef struct _IMAGE_EXPORT_DIRECTORY {     DWORD    Characteristics;     DWORD    TimeDateStamp;    //creation time date stamp     WORD  MajorVersion;     WORD  MinorVersion;     DWORD   Name;    //address of library file neme     DWORD   Base;  //ordinal base     DWORD   NumberOfFunctions; //number of functions     DWORD   NumberOfNames;    //number of names     DWORD   AddressOfFunctions;    //address of function start address array     DWORD   AddressOfName;  //address of function name string array  DWORD   AddressOfNameOrdinals;   //address of ordinal array } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; 其中結構體中的重要成員如下 專案 含義 NumberOfFunctions    實際Export函式的個數 NumberOfNames     Export函式中具名的函式個數 AddressOfFunctions    Export函式地址陣列(陣列元素個數=NumberOfFunctions AddressOfNames     函式名稱地址陣列(陣列元素個數=NumberOfNames AddressOfNameOrdinals    Ordinal地址陣列 (陣列元素個數=NumberOfNames)