日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1

發(fā)布時間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? 本文將討論PE文件中非常重要的一部分信息。(轉(zhuǎn)載請指明來源于breakSoftware的CSDN博客)

? ? ? ? 首先說一下VC中對應(yīng)的數(shù)據(jù)結(jié)構(gòu)。“簽名、COFF文件頭和可選文件頭”這三部分信息組合在一起是一個叫IMAGE_NT_HEADERS的結(jié)構(gòu)體。

typedef struct _IMAGE_NT_HEADERS64 {DWORD Signature;IMAGE_FILE_HEADER FileHeader;IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;typedef struct _IMAGE_NT_HEADERS {DWORD Signature;IMAGE_FILE_HEADER FileHeader;IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

? ? ? ? 其中Signature對應(yīng)于“簽名”,FileHeader對應(yīng)于“COFF文件頭”,OptionalHeader對應(yīng)于“可選文件頭”。

? ? ? ? 對于PE鏡像文件,Signature對應(yīng)的數(shù)據(jù)是0x00004550(‘PE\0\0’)。對于如何找到這個位置,在前一篇文章中已經(jīng)有了解說:從文件頭偏移0x3C讀取一個DWORD大小的數(shù)據(jù),從文件頭偏移該數(shù)據(jù)長度,就到了Signature的起始位置。
? ? ? ? 看一下COFF文件頭結(jié)構(gòu)

typedef struct _IMAGE_FILE_HEADER {WORD    Machine;WORD    NumberOfSections;DWORD   TimeDateStamp;DWORD   PointerToSymbolTable;DWORD   NumberOfSymbols;WORD    SizeOfOptionalHeader;WORD    Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

? ? ? ? 以notepad為例

? ? ? ? Machine字段為0x014C,其對應(yīng)的信息是“Intel 386或其后續(xù)處理器及兼容處理器”。

? ? ? ? NumberOfSections是0x0003,它是個非常重要的字段,表示節(jié)的數(shù)目。PE文件是由一系列“節(jié)”構(gòu)成的,比較常見的是.text和.data等節(jié),這樣的獨立的區(qū)塊是用來存儲“代碼”、“數(shù)據(jù)”和“資源”等信息的。如xp上notepad,從數(shù)據(jù)中我們可以看到它有3個節(jié),我們用其他工具分析得到它確實存在如下3個節(jié)。


? ? ? ??TimeDateStamp是0x41107CC3,該字段記錄的是文件創(chuàng)建時間離1970年1月1日00:00的秒數(shù)。

? ? ? ??PointerToSymbolTable是0x00000000,該字段記錄了該PE文件中調(diào)試信息符號表。由于符號表信息是在程序運行時不需要加載進入內(nèi)存的,所以這個偏移使用的是相對文件頭偏移RA。目前微軟推薦是:將映像文件調(diào)試符號表信息獨立的放在PDB文件中,所以不會在PE文件中再保存調(diào)試符號表信息,于是這個字段應(yīng)該為0。當然這并不是硬性要求,我發(fā)現(xiàn)我電腦上就存在很多該字段不為0的文件。剛開始時我也不是很明白它們?yōu)槭裁匆褂眠@個字段,特別是其指向的字符表個數(shù)(NumberOfSymbols)為0!!你說既然大小為0,那你指向有什么意思呢?其實這種設(shè)計是非常有深意的,我會在之后的章節(jié)中介紹這種深意。

? ? ? ??NumberOfSymbols是0x00000000,該字段記錄了該PE文件中調(diào)試信息符號表元素個數(shù)。對于映像文件,該字段為0(非硬性要求),,理由在PointerToSymbolTable中已經(jīng)說明。通過NumberOfSymbols和PointerToSymbolTable,我們可以找到字符串表起始位置,因為字符串表緊跟在符號表之后。

? ? ? ??SizeOfOptionalHeader是0x00E0,該字段用于描述“可選文件頭”的大小。之后會看到“可選文件頭”的中有個具有16個元素是數(shù)組,該數(shù)組保存了一系列“塊信息”,但是并不是所有文件都有全部的“塊信息”,于是鏈接器在鏈接生成PE文件時,也是根據(jù)實際存在的“塊信息”位置(以后會說明為什么是位置而不是數(shù)量)去填充這個數(shù)組的。也就是說我們可能只是填充了1個元素,而剩下的15個元素直接被砍掉,而不是在內(nèi)存中使用0來填充。

? ? ? ? 這兒就引入一個問題,就是我們不能從“簽名”位置開始,就直接memcpy一段IMAGE_NT_HEADERS大小的空間到一個IMAGE_NT_HEADERS對象中。因為“可選文件頭”還要看“COFF文件頭”中的SizeOfOptionalHeader數(shù)據(jù)。

? ? ? ??Characteristics字段用于標記該文件屬性,notepad.exe該字段值為0x010F。下面我們來解釋下該組合屬性

標志說明
IMAGE_FILE_RELOCS_STRIPPED0x0001僅適用于映像文件。它表明此文件不包含機制重定位信息,于是它只能被加載到其首選基地址。如果首選基地址不可用,則加載器會報錯。鏈接器默認會移除可執(zhí)行文件中的重定位信息。一般情況下,Exe文件會設(shè)置該值(如notepad.exe,但ntoskrnl.exe就沒設(shè)置),而因為DLL文件為了其良好的兼容性是不會去設(shè)置這個值的(如Kernel32.dll、User32.dll等)。
IMAGE_FILE_EXECUTABLE_IMAGE0x0002僅適用于映像文件。它用于表明該文件是合法的,可以被運行。如果沒有設(shè)置,則代表鏈接出現(xiàn)問題。這個一般都會設(shè)置。
IMAGE_FILE_LINE_NUMS_STRIPPED0x0004COFF行號信息已經(jīng)被移除。不贊成使用該標志。但是我發(fā)現(xiàn)notepad.exe、Kernel32.dll、User32.dll等都設(shè)置了該標志。而一般我們編譯的PE文件是不設(shè)置該項的。
IMAGE_FILE_LOCAL_SYMS_STRIPPED0x0008COFF符號表中有關(guān)局部符號的項已經(jīng)被移除。不贊成使用該標志。但是我發(fā)現(xiàn)notepad.exe、Kernel32.dll、User32.dll等都設(shè)置了該標志。而一般我們編譯的PE文件是不設(shè)置該項的。
IMAGE_FILE_AGGRESSIVE_WS_TRIM0x0010該標志已經(jīng)被廢棄。
IMAGE_FILE_LARGE_ADDRESS_ AWARE0x0020應(yīng)用程序可以處理大于2GB的地址。
?0x0040為未來保留的字段。
IMAGE_FILE_BYTES_REVERSED_LO0x0080小尾,LSB在MSB前面。不贊成使用該標志。windows xp就是小尾。
IMAGE_FILE_32BIT_MACHINE0x0100適用于32位系統(tǒng)。我的xp系統(tǒng)上DLL和Exe文件基本都設(shè)置了該標志。
IMAGE_FILE_DEBUG_STRIPPED0x0200調(diào)試信息已經(jīng)從該映像文件中移除。
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP0x0400如果該文件是在移動介質(zhì)上,需要將其完全加載到交換文件中。
IMAGE_FILE_NET_RUN_FROM_SWAP0x0800如果該文件是在網(wǎng)絡(luò)介質(zhì)上,需要將其完全加載到交換文件中。
IMAGE_FILE_SYSTEM0x1000該映像文件是一個系統(tǒng)文件,不是一個用戶文件。
IMAGE_FILE_DLL0x2000此文件是DLL文件。
IMAGE_FILE_UP_SYSTEM_ONLY0x4000該文件僅能運行于單處理機器上。
IMAGE_FILE_BYTES_REVERSED_HI0x8000大尾,LSB在MSB后面。

? ? ? ? 我觀察了我系統(tǒng)上幾個文件,發(fā)現(xiàn)以下規(guī)律:

? ? ? ?1 Sys和Exe的該屬性為0x010E或者0x010F。

? ? ? ?2 DLL文件該屬性一般為0x210E。DLL文件一般不會設(shè)IMAGE_FILE_RELOCS_STRIPPED(0x0001),因為它為了良好的兼容性,不能設(shè)置它必須要被加載的地址。一個Exe可能會加載多個DLL,如果系統(tǒng)“不小心”把某個DLL加載到0x70000000,那么如果有某個DLL設(shè)置了IMAGE_FILE_RELOCS_STRIPPED并將其首選加載地址正好也設(shè)置為0x70000000,那么系統(tǒng)為該Exe加載這個DLL將會失敗。但是的確存在這樣的文件,比如我電腦上ResourceCache.dll。DLL文件肯定要設(shè)置IMAGE_FILE_DLL。所以即使某個DLL文件的后綴名改了,你可以結(jié)合這個“特征碼”來還原其真面目。

? ? ? ?這兒我還要說一個認知的誤區(qū)。 IMAGE_FILE_32BIT_MACHINE標志可以用于標志這個文件是適用于32位系統(tǒng),但是如果僅僅通過該標志就去鑒別這個文件是32位文件還是64位文件是不正確的。我也不知道微軟為什么設(shè)計了該標志而沒有嚴格限制這個標志。我通過掃描我電腦里所有文件,發(fā)現(xiàn)了一個可能具有指導(dǎo)性的鑒別策略:

? ? ? ?1 如果沒有設(shè)置?IMAGE_FILE_32BIT_MACHINE但是設(shè)置了IMAGE_FILE_LARGE_ADDRESS_ AWARE的文件是64位文件。沒有設(shè)置IMAGE_FILE_32BIT_MACHINE意味著該文件可能是64位程序,而設(shè)置了IMAGE_FILE_LARGE_ADDRESS_ AWARE,則說明該文件可以處理大于2G的空間的內(nèi)存,則該文件是64位文件。如我本機上wwst64.exe。

? ? ? ?2 除了以上判斷之外的其他可能標志該文件是32位文件。

? ? ? ? ? 比如設(shè)置了IMAGE_FILE_32BIT_MACHINE而沒有設(shè)置IMAGE_FILE_LARGE_ADDRESS_ AWARE,則說明這個文件可以處理2G以內(nèi)內(nèi)存空間,是32位文件;

? ? ? ? ? 比如沒有設(shè)置IMAGE_FILE_32BIT_MACHINE和IMAGE_FILE_LARGE_ADDRESS_ AWARE,怎么解釋呢?反正它不是64位文件,因為不能處理大于2G內(nèi)存空間,那它只能是32位文件了。如我本機上文件sqlite3.dll。

? ? ? ? ?比如設(shè)置了IMAGE_FILE_32BIT_MACHINE和IMAGE_FILE_LARGE_ADDRESS_ AWARE,那說明這是個可以處理大于2G內(nèi)存空間的32位文件。如我本機上AcroBroker.exe。

BOOL CGetPEInfo::GetFileType() {CHECKFILETYPE();GETFILEHEADER();m_eFileType = E32Bit;m_bIsDllFile = ( m_FileHeader.Characteristics & IMAGE_FILE_DLL ) ? TRUE : FALSE;if ( !( IMAGE_FILE_32BIT_MACHINE & m_FileHeader.Characteristics ) && !( IMAGE_FILE_LARGE_ADDRESS_AWARE & m_FileHeader.Characteristics ) ) {//_ASSERT(FALSE);}else if ( !( IMAGE_FILE_32BIT_MACHINE & m_FileHeader.Characteristics ) && ( IMAGE_FILE_LARGE_ADDRESS_AWARE & m_FileHeader.Characteristics ) ){m_eFileType = E64Bit;}else if ( ( IMAGE_FILE_32BIT_MACHINE & m_FileHeader.Characteristics ) && ( IMAGE_FILE_LARGE_ADDRESS_AWARE & m_FileHeader.Characteristics ) ) {}return TRUE;
}

總結(jié)

以上是生活随笔為你收集整理的PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。