青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

aurain
技術文摘
posts - 137,  comments - 268,  trackbacks - 0
關于輸入部分,我們將詳細介紹關于輸入函數的各種結構,通過一個例子來說明輸入函數及其相關結構是怎么放在PE文件中的。以及如何在PE文件中找到這些東西。

一 找到輸入部分在文件中位置。

1.1 得到PE Header在文件中的位置。
    通過DOS Header結構的成員e_lfanew,可以確定PE Header的在文件中的位置。

1.2 得到文件中節的數目。
    確定PE Header的在文件中的位置之后,就可以確定PE Header中的成員FileHeader和成員OptionalHeader在文件中的位置。根據 FileHeader 中的 成員NumberOfSections 的值,就可以確定文件中節的數目,也就是節表數組中元素的個數。

1.3 得到節表在文件中的位置。
    PE Header在文件中的位置加上PE Header結構的大小就可以得到節表在文件中的開始位置。PE Header結構的大小可以由Signature的大小加上FileHeader的大小再加上FileHeader中的SizeOfOptionalHeade來確定。其實到目前為止SizeOfOptionalHeade也就是結構Optional Header的大小也是固定的,所以整個PE Header結構的大小也是固定。不過為了安全起見,還是用Signature的大小加上FileHeader的大小再加上FileHeader中的SizeOfOptionalHeade來確定比較保險。

1.4 得到輸入部分在文件中的位置。
    第1.2步中我們確定了文件中節的數目,第1.3步中我們確定了節表在文件中的位置。
    現在來確定輸入部分在文件中的位置。
    取得PE Header中的Optional Header中的DataDirectory數組中的第二項,
也就是輸入部分項。DataDirectory[]數組的每項都是IMAGE_DATA_DIRECTORY結構,該結構定義如下。
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
取得DataDirectory數組中的第二項中的成員VirtualAddress的值。這個值就是在內存中資源節的RVA。
如果這個RVA的值為0表示這個PE文件中沒有輸入部分。
然后根據節的數目,遍歷節表數組。也就是從0到(節表數-1)的每一個節表項。
每個節在內存中的RVA的范圍是從該節表項的成員VirtualAddress字段的值開始(包括這個值),
到VirtualAddress+Misc.VirtualSize的值結束(不包括這個值)。
我們遍歷整個節表,看我們取得的輸入部分的RVA,在哪個節表項的RVA范圍之內。
如果在范圍之內,就找到了輸入部分所在節的節表項。
這個節表項中的 PointerToRawData 中的值,就是輸入部分所在節在文件中的位置。這個節表項中的VirtualAddress 中的值,就是輸入部分所在節在內存中的RVA。用輸入部分的RVA減去輸入部分所在節的RVA,就可以得到輸入部分在該節內偏移。用這個偏移加上該節的在文件中的位置,就可以得到輸入部分在文件中的位置。即DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - SectionTable[i].VirtualAddress + SectionTable[i].PointerToRawData 。

這樣我們就得到了輸入部分在文件中開始的位置。

二 PE文件中的輸入部分。

    輸入部分,如果要調用別的PE文件中的輸出函數,需要那些東西呢?首先需要知道所需函數在哪個文件中,比如函數 NtRaiseHardError 就在PE文件 ntdll.dll 中。所以我們需要一個文件名。而如何找到某個函數的入口地址呢,我們還需要知道該函數的函數名,或者改函數的序號,通過這兩者的任一種,我們就可以找到該函數的入口地址(如果不知道為什么,請看 JIURL PE 格式學習總結(二)-- PE文件中的輸出函數)。所以我們還需要函數名或者序號,這兩者之一。PE文件的輸入部分,有這些內容。我們還可以想到,當一個PE文件被執行的時候,它會把所用的輸入函數所在的每一個文件載入內存,并且,根據函數名或者序號,獲得每一個輸入函數的入口地址,存放起來,在程序執行的時候使用。還有就是,一個可執行文件一般都使用好幾個PE文件(通常是dll)的輸出函數。所以需要有多個dll(就說成dll吧,提供輸出函數的PE文件差不多都是dll,下面就按dll說)的相關信息。

    前面我們已經得到了輸入部分在文件中開始的位置,在輸入部分的最開始,是一個IMAGE_IMPORT_DESCRIPTOR 結構數組,這個數組的最后一個元素內容全為空,標示著這個數組的結束,這個數組的每個元素,保存著一個dll的相關信息。緊跟著這個IMAGE_IMPORT_DESCRIPTOR數組的是幾個緊挨著的DWORD數組, 數組的每個元素存有函數名字符串的RVA,或者直接保存序號,每個數組的最后一項為空,標示結束。這幾個數組之后,緊跟著的是dll名字的字符串和各個輸入函數名結構。 

IMAGE_IMPORT_DESCRIPTOR 結構在WINNT.H中定義如下。

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
};
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;

這個結構長度為20個字節,共有5個字段。
各字段含義如下:

OriginalFirstThunk:(在WINNT.H中Characteristics這個叫法已經不對了)這里實際上保存著一個RVA,這個RVA指向一個DWORD數組,這個數組可以叫做輸入查詢表。每個數組元素,或者叫一個表項,保存著一個指向函數名的RVA或者保存著一個函數的序號。
TimeDateStamp:當這個值為0的時候,表明還沒有bind。不為0的話,表示已經bind過了。有關bind的內容后面介紹。
ForwarderChain:
Name:一個RVA,這個RVA指向一個ascii以空字符結束的字符串,這個字符串就是本結構對應的dll文件的名字。
FirstThunk:一個RVA,這個RVA指向一個DWORD數組,這個數組可以叫輸入地址表。如果bind了的話,這個數組的每個元素,就是一個輸入函數的入口地址。

輸入查詢表,就是OriginalFirstThunk所指向的那個DWORD數組,它的每一個元素是一個DWORD值,當最高位為1時,低31位中的值,就是一個序號。當最高位為0時,這個元素的值就是一個指向一個輸入函數名結構的RVA。這個數組的最后一個元素值為空,表示數組的結束。

輸入函數名結構,在WINNT.H中定義如下。

typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

這個結構的長度不定,有兩個成員。第一個成員是一個WORD類型,長2個字節,保存著輸入函數的序號。第二個成員是一個ascii字符串,這個字符串是輸入函數的名字。為了保證字對齊,可能會在ascii結束符\0之后再填充一個\0。比如,1b 01 4e 74 54 65 72 6d 69 6e 61 74 65 50 72 6f 63 65 73 73 00 00 ,如果不填充最后一個00的話,長度為21個字節,不是字對齊。所以要填充一個00。

輸入地址表,就是FirstThunk所指向的那個DWORD數組,它的每一個元素是一個DWORD值。如果程序已經bind了的話,(判斷依據是TimeDateStamp,TimeDateStamp為0則沒有bind)那么這里的每個元素的值,就是一個輸入函數的入口地址。如果沒有bind的話,那么在本pe文件執行時,載入器會載入dll文件,獲得每一個輸入函數的入口地址,并填入這個輸入地址表的每一項中。(這些是我猜的,大家但愿我猜對吧)這個數組的最后一個元素值為空,表示數組的結束。

bind,從上面的介紹中可以看到,如果沒有bind的話,每次pe文件被執行時,載入器都要查詢一遍每個函數的入口地址,所以為了優化這一點,就有了bind,把入口點直接存在輸入地址表中。

載入器會載入所需要的dll。注意一下沒有bind的情況下,載入器對輸入部分所要做的事情。總之,在載入之后,所需的dll(根據文件名)已經都被載入到內存。并且輸入地址表中的每一個元素都是一個輸入函數的入口地址了。

下面我們來看一個例子,通過例子就可以明白是怎么回事了。

我們的例子是Win2k中的exe文件csrss.exe。為了防止大家版本不同,本文附帶了這個PE文件。

每個結構的不同成員用 / 分開。每行是一個結構。可以用16進制編輯器打開附帶的 routetab.dll 對照著看。
括號中內容為注釋。

用開始講到的尋找輸入部分在文件中位置的方法,我們找到了輸入部分在文件中的位置為000008DCh。
我們來計算一下第一個IMAGE_IMPORT_DESCRIPTOR中的OriginalFirstThunk,Name,FirstThunk。
輸入部分所在節的開始rva(由DataDirectory[2]得到)為1000h。輸入部分在節在文件中的位置為600h。
Name為rva(值從結構中可以看到是0000135e,如果你不明白為什么是0000135e而不是5e130000的話,請看 《JIURL PE 格式學習總結(一)》中關于 big-endian和little-endian的介紹),則Name相對于所在節開始處的偏移為135e-1000。而Name在文件中的位置為Name在相對于所在節開始的偏移加上所在節開始處在文件中的位置。所以Name在文件中的位置為135eh-1000h+600h=95eh。同樣方法我們可以算出, OriginalFirstThunk:
1318-1000+600=918。FirstThunk:1000-1000+600=600。

000008DC: 18 13 00 00 / ff ff ff ff / ff ff ff ff / 5e 13 00 00 / 00 10 00 00 
(結構IMAGE_IMPORT_DESCRIPTOR,每個代表一個dll。可以看到兩個IMAGE_IMPORT_DESCRIPTOR,所以本PE文件的輸入函數,是由兩個dll提供的。第三個全為空,表示結束。)
000008F0: 20 13 00 00 / ff ff ff ff / ff ff ff ff / c2 13 00 00 / 08 10 00 00 
(結構IMAGE_IMPORT_DESCRIPTOR)
00000904: 00 00 00 00 / 00 00 00 00 / 00 00 00 00 / 00 00 00 00 / 00 00 00 00  
(全為空,表示結束IMAGE_IMPORT_DESCRIPTOR數組結束)
00000918: 44 13 00 00 (文件中的地址為1344-1000+600=944,指向一個輸入函數名結構)
0000091C: 00 00 00 00 (為空,一個輸入查詢表結束)
00000920: 84 13 00 00 (文件中的地址為1384-1000+600=984,指向一個輸入函數名結構)
00000924: 98 13 00 00 (1398-1000+600=998)
00000928: 6a 13 00 00 (136a-1000+600=96a)
0000092C: ae 13 00 00 (13ae-1000+600=9ae)
00000930: cc 13 00 00 (13cc-1000+600=9cc)
00000934: dc 13 00 00 (13dc-1000+600=9dc)
00000938: ee 13 00 00 (13ee-1000+600=9ee)
0000093C: 0e 14 00 00 (140e-1000+600=a0e)
00000940: 00 00 00 00 (為空,一個輸入查詢表結束)
00000944: 18 00 / 43 73 72 53 65 72 76 65 72 49 6e 69 74 69 61 6c 69 7a 61 74 69 6f 6e 00
(輸入函數名結構 IMAGE_IMPORT_BY_NAME hint為18 Name為 "CsrServerInitialization.")
0000095E: 43 53 52 53 52 56 2e 64 6c 6c 00 00 
(第一個IMAGE_IMPORT_DESCRIPTOR的Name指向這里"CSRSRV.dll")
0000096A: 00 01 / 4e 74 53 65 74 49 6e 66 6f 72 6d 61 74 69 6f 6e 50 72 6f 63 65 73 73 00
("NtSetInformationProcess.")
00000984: 1c 01 / 4e 74 54 65 72 6d 69 6e 61 74 65 54 68 72 65 61 64 00
00000998: 1b 01 / 4e 74 54 65 72 6d 69 6e 61 74 65 50 72 6f 63 65 73 73 00 00
000009AE: d8 00 / 4e 74 52 61 69 73 65 48 61 72 64 45 72 72 6f 72 00 00
000009C2: 6e 74 64 6c 6c 2e 64 6c 6c 00
000009CC: 0d 00 / 44 62 67 42 72 65 61 6b 50 6f 69 6e 74 00 
000009DC: 4a 01 / 52 74 6c 41 6c 6c 6f 63 61 74 65 48 65 61 70 00
000009EE: 85 02 / 52 74 6c 55 6e 69 63 6f 64 65 53 74 72 69 
6e 67 54 6f 41 6e 73 69 53 74 72 69 6e 67 00 00
00000A0E: 30 02 / 52 74 6c 4e 6f 72 6d 61 6c 69 7a 65 50 72 6f 63 65 73 73 50 61 72 61 6d 73 00
00000A2A: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000A3A: ...

00000600: 38 1f f8 5f 
00000604: 00 00 00 00 (為空,一個輸入地址表結束)
00000608: 6d f0 f8 77
0000060C: d8 c3 f8 77
00000610: a5 b7 f8 77
00000614: 38 a4 f9 77
00000618: df f9 f9 77
0000061C: 6b 97 fc 77
00000620: ec e5 f8 77
00000624: 18 2c f9 77
00000628: 00 00 00 00 (為空,一個輸入地址表結束)

本例比較可惜的是,在兩個輸入查詢表中,都是函數名結構的RVA,沒有直接的序號(是序號還是RVA的判別方法為,看最高位是否為1,為1,其余部分表示序號。為0,整個字段表示RVA)。

三 遍歷PE文件中的輸入

    用while循環,遍歷IMAGE_IMPORT_DESCRIPTOR數組的每個元素(每個可以找到一個dll的信息和該dll提供的輸入函數)。當某元素的值都為空時,表示遍歷到了數組的最后。而對于IMAGE_IMPORT_DESCRIPTOR數組的一個元素,再用while循環,遍歷IMAGE_IMPORT_DESCRIPTOR中,兩個RVA所指的兩個DWORD數組,輸入查詢表和輸入地址表。判斷結束的條件也是看,是否數組元素的值已經為空了。也就是while(..){..while(..){}..}這樣就可獲得每一個有關輸入的內容。

    實現遍歷輸入的源程序,可以參考 PEDUMP - Matt Pietrek 1995 。《Windows95系統程式設計大奧秘》附書源碼中有。


本文所使用的PE文件csrss.exe

posted on 2009-06-29 13:56 閱讀(580) 評論(0)  編輯 收藏 引用 所屬分類: Windows開發

<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用鏈接

留言簿(17)

隨筆分類(138)

隨筆檔案(137)

網絡開發

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 501927
  • 排名 - 37

最新隨筆

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲黄色精品| 欧美人与禽性xxxxx杂性| 久久国产精品毛片| 欧美一区二区视频在线观看| 亚洲小说春色综合另类电影| 亚洲国产毛片完整版| 91久久精品国产| 一本到12不卡视频在线dvd| 亚洲精品一区二区三区av| 亚洲狼人综合| 亚洲午夜在线观看视频在线| 欧美一级专区免费大片| 久久一日本道色综合久久| 欧美高清在线视频观看不卡| 亚洲免费观看高清在线观看 | 欧美国产日韩精品| 亚洲国产色一区| 亚洲午夜精品久久| 久久久91精品国产一区二区精品| 免费欧美日韩| 国产精品视频yy9099| 亚洲高清网站| 亚洲在线一区| 欧美成人午夜剧场免费观看| 日韩亚洲欧美成人| 欧美一区二区三区精品| 欧美激情视频在线播放 | 欧美一区二区三区免费大片| 玖玖综合伊人| 亚洲午夜久久久| 美女被久久久| 国产日韩亚洲欧美| 亚洲国产婷婷香蕉久久久久久| 一区二区三区视频在线| 久久亚洲国产精品日日av夜夜| 亚洲三级影院| 久久久精彩视频| 国产精品久久久久久av下载红粉| 在线日本高清免费不卡| 亚洲字幕一区二区| 亚洲欧洲一区二区三区在线观看| 亚洲一区二区三区久久| 欧美区二区三区| 亚洲风情亚aⅴ在线发布| 久久爱www.| 一区二区三区不卡视频在线观看 | 美女脱光内衣内裤视频久久网站| 亚洲第一福利视频| 久久视频精品在线| 国产偷久久久精品专区| 亚洲欧美视频在线观看| 亚洲裸体在线观看| 欧美成ee人免费视频| 一区福利视频| 久久综合福利| 久久精品亚洲一区| 一区二区三区在线观看欧美| 久久久精品免费视频| 欧美主播一区二区三区| 国产欧美短视频| 欧美中文字幕在线视频| 欧美一区二区三区久久精品| 国产一区欧美| 欧美 日韩 国产一区二区在线视频 | 欧美一级二区| 亚洲欧美日韩精品久久久| 国产精品美女一区二区在线观看| 亚洲欧美日韩一区在线| 亚洲综合日韩| 国自产拍偷拍福利精品免费一| 久久久av水蜜桃| 久久在精品线影院精品国产| 亚洲国产精品成人| 亚洲精品美女久久7777777| 欧美日韩视频专区在线播放| 亚洲一区二区三区影院| 欧美亚洲色图校园春色| 在线观看一区| 亚洲欧洲日本一区二区三区| 欧美日韩一区二区视频在线 | 欧美一级视频免费在线观看| 先锋影音网一区二区| 在线高清一区| 亚洲一区欧美激情| 午夜影视日本亚洲欧洲精品| 黄色免费成人| aa级大片欧美三级| 黄色一区二区三区| a91a精品视频在线观看| 影音国产精品| 亚洲网站视频| 亚洲国产美女精品久久久久∴| 日韩亚洲精品在线| 樱桃成人精品视频在线播放| 99视频在线精品国自产拍免费观看| 国产精品视频网站| 亚洲电影av| 国产日韩欧美在线观看| 亚洲精品美女在线| 影音先锋欧美精品| 国产精品白丝av嫩草影院| 国产乱码精品一区二区三区不卡| 久久精品一区二区| 欧美激情一区在线观看| 久久久久久亚洲精品杨幂换脸| 欧美激情第10页| 久久久国产一区二区| 欧美成人一区二区三区| 久久性天堂网| 国产精品一区二区a| 亚洲日本电影在线| 亚洲国产成人不卡| 久久成人精品电影| 亚洲欧美精品一区| 欧美激情va永久在线播放| 看片网站欧美日韩| 国产亚洲第一区| 一区二区高清| 99精品欧美一区二区蜜桃免费| 久久成人人人人精品欧| 亚洲欧美国产另类| 欧美日韩亚洲一区二区| 亚洲国产精品高清久久久| 娇妻被交换粗又大又硬视频欧美| 亚洲一二三四区| 亚洲欧美一区二区原创| 欧美人与禽猛交乱配| 亚洲国产专区| 亚洲精品乱码| 欧美成人中文字幕| 亚洲激情电影中文字幕| 亚洲第一精品在线| 久久夜色精品国产| 欧美成人免费一级人片100| 狠狠色丁香婷婷综合影院| 西西人体一区二区| 久久免费精品日本久久中文字幕| 国产精品永久免费在线| 亚洲欧美日韩综合国产aⅴ| 欧美一级视频免费在线观看| 国产欧美日韩一区二区三区在线观看| 在线视频精品一| 午夜久久久久| 狠狠色2019综合网| 久久亚洲国产精品日日av夜夜| 美女视频一区免费观看| 亚洲日本aⅴ片在线观看香蕉| 欧美成人午夜77777| 亚洲欧洲视频| 亚洲在线观看视频网站| 国产日韩1区| 久久综合伊人| 亚洲毛片在线| 久久精品亚洲精品| 亚洲国产天堂久久国产91| 欧美激情一区二区三区在线视频观看 | 夜夜爽99久久国产综合精品女不卡| 欧美了一区在线观看| 亚洲精品一二| 久久精品国产2020观看福利| 在线观看欧美日韩| 欧美日韩伦理在线免费| 午夜视频久久久久久| 欧美成人精品三级在线观看| 亚洲国产高清在线| 欧美中日韩免费视频| 久久精品成人欧美大片古装| 在线成人亚洲| 欧美另类亚洲| 午夜精品区一区二区三| 欧美国产极速在线| 亚洲尤物视频网| 一区二区三区自拍| 欧美日韩国产麻豆| 久久精品国产久精国产一老狼 | 一区二区精品国产| 国产日韩欧美精品一区| 欧美大色视频| 欧美在线一区二区| 亚洲靠逼com| 国产主播一区二区三区| 欧美日韩免费观看一区=区三区| 午夜精品婷婷| 亚洲久久一区| 欧美高清视频在线| 久久精品国产亚洲a| 一区二区欧美日韩| 亚洲国产裸拍裸体视频在线观看乱了中文 | 一本色道久久综合亚洲精品高清 | 麻豆久久久9性大片| 亚洲综合视频一区| 99视频一区二区| 悠悠资源网亚洲青| 国产农村妇女毛片精品久久莱园子| 毛片av中文字幕一区二区| 午夜在线观看欧美| 亚洲一区国产精品| 一区二区精品在线观看| 亚洲精选一区| 日韩视频在线你懂得|