2015-03-02 84 views
1

我需要區分一個32位PE從16位DOS MZ。 做什麼是正確的方法? 我可以使用啓發式查找PE標頭,但我覺得它不一定是確定性的如何diffrentiate 16位MZ和32位MZ

+1

這不是「只是一個啓發式」。所有的可執行文件都有一個16位的加載程序,而對於32位(也可以是LE)的頭文件,它提供了必要的信息。其他操作系統如何知道? – usr2564301 2015-03-02 07:27:33

回答

5

所有DOS樣式的可執行文件都有'MZ'作爲前兩個字節。
要識別MSDOS可執行文件與其他衆多變體,最好的辦法似乎是讀取文件中偏移量爲0x0018的重定位表的位置,如果該位置大於0x0040(進入文件),則不僅僅是普通的DOS。

爲了將可執行文件明確標識爲'PE'可執行文件,文件中的偏移量0x003C處有一個指針。這是文件內的一個偏移量,它將包含字節「PE」和兩個字節。其他MSDOS'MZ'變體將使用相同的位置來放置其他代碼,例如'NE','W3','LE'等。

'PE'風格的可執行文件也有很多種形式,我希望你會至少對32位和64位感興趣。

也許這類事情的最終權威是Unix的'文件'命令,它的目的是通過調查它的內容來可靠地識別任何文件類型。 MSDOS部分列出了here。微軟並不是一個可靠的機構,因爲他們忽略了非微軟的信息。

1

普通的DOS EXE頭只有28(0x1C)個字節長,通常在DOS重定位表後面會出現。 NT PE標頭的IMAGE_DOS_HEADERstruct在64(0x40)字節處大得多,因爲它已被擴展用於各種其他Windows可執行格式。這個頭的大小不同是爲什麼@ user3710044的答案不僅是最快的,而且是可靠的:如果重定位表[e_lfarlc] < 0x40),EXE就是普通的DOS。

只要你意識到在普通的DOS可執行文件中不存在e_lfanew成員(一些可能的「擴展」頭文件的偏移量),還可以使用以下邏輯來區分各種MZ樣式格式:

  1. 如果文件的開頭並非以「MZ」或「ZM」開頭,則它不是DOS或Windows可執行映像。否則,您可能有以下類型的可執行格式之一:普通DOS,NE(Windows 16位),LE(16位VXD),PE32或PE32 +(PE64)。

  2. 通過查看e_lfanew值,確定您是否擁有普通的DOS可執行文件。普通的DOS可執行文件將有一個超出範圍e_lfanew指向文件限制之外的零,或者如果偏移恰好在範圍內,則其偏移處的簽名將不匹配下面的任何簽名。

    "PE" followed by two zero bytes if the image is a PE32 or PE32+ (PE64) and is further determined by the "magic" in the NT Optional Header 
    "NE" indicates the image is a 16-bit Windows executable 
    "LE" indicates the image is a 16-bit Virtual Device Driver (VXD) 
    

更多晦澀簽名(從Ralph Brown's INT 21/AH=4Bh引用)::

  • 嘗試通過e_lfanew具有以下WORD或DWORD值匹配的「範圍內」偏移指向的簽名

    LX  variant of LE used in OS/2 2.x 
    W3  Windows WIN386.EXE file; a collection of LE files 
    W4  Windows95 VMM32.VXD file 
    DL  HP 100LX/200LX system manager compliant executable (.EXM) 
    MP  old PharLap .EXP 
    P2  PharLap 286 .EXP 
    P3  PharLap 386 .EXP