PE文件和COFF文件格式分析--MS-DOS 2.0兼容Exe文件段
??????? MS 2.0節是PE文件格式中第一個“節”。其大致結構如下:(轉載請指明來源于breaksoftware的csdn博客)
??????? 在VC\PlatformSDK\Include\WinNT.h文件中有對MS-DOS 2.0兼容EXE文件頭的完整定義
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE headerWORD e_magic; // Magic numberWORD e_cblp; // Bytes on last page of fileWORD e_cp; // Pages in fileWORD e_crlc; // RelocationsWORD e_cparhdr; // Size of header in paragraphsWORD e_minalloc; // Minimum extra paragraphs neededWORD e_maxalloc; // Maximum extra paragraphs neededWORD e_ss; // Initial (relative) SS valueWORD e_sp; // Initial SP valueWORD e_csum; // ChecksumWORD e_ip; // Initial IP valueWORD e_cs; // Initial (relative) CS valueWORD e_lfarlc; // File address of relocation tableWORD e_ovno; // Overlay numberWORD e_res[4]; // Reserved wordsWORD e_oemid; // OEM identifier (for e_oeminfo)WORD e_oeminfo; // OEM information; e_oemid specificWORD e_res2[10]; // Reserved wordsLONG e_lfanew; // File address of new exe header} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
??????? 這個結構占用0x40個字節,其中我們將主要關注兩個成員變量:e_magic和e_lfanew。
?????? 以我xp電腦上notepad為例,我們使用UE打開C:\windows\notepad.exe
? ? ? ? 可以發現IMAGE_DOS_HEADER結構中e_magic對應的數據位0x5A4D(MZ),e_lfanew對應的是0x000000E0。這個兩個數據是這個結構體中最需要關心的兩個成員變量。幻數(Magic Num)這個概念是用于區分一個格式文件的類型,就像一個人的姓,知道你姓啥之后,就可以明確你是不是我們族人。同樣,解析這些文件的程序也會去嘗試讀取這樣的幻數,以確認這個文件符合它要求的。在我所知道的一些格式中,他們的幻數往往是這個格式發明者的名稱縮寫(或者是格式后綴)。我們這個MS-Dos 2.0兼容EXE文件頭中的幻數MZ也是紀念他的發明者,可以想到,這個名字應該不是蓋茨,因為MZ和Bill Gates(BG)一點也沒關系,也不是Paul Allen(PA),更不可能是銷售出生的Steve Ballmer。它是Mark Zbikowski,中文翻譯是馬克·茨柏克沃斯基。
? ? ? ? 那么為什么PE格式文件會有個Dos文件頭呢?Dos系統時代,有兩種(我所知道的,我壓根沒經歷過那個年代)可執行文件格式,一種是.exe為后綴的文件,其結構是MZ格式。另一種是以.com為后綴的文件,其結構是COM格式。從Wiki上對MZ格式的介紹可以看出來,MZ格式要比COM格式要新,MZ格式頭中包含了重定向信息(本文第一個圖中),且其支持可執行體大于64KiB。如今我們電腦上PE可執行文件的后綴也是.exe,為了讓該后綴程序在Dos和Nt間有個過渡,我們需要讓Dos系統能知道它不能“正確”執行該Exe文件。于是我們PE可執行文件一開始處便插入了一個MS-Dos 2.0兼容Exe文件頭,Dos系統加載我們PE文件時,從一開始讀取我們文件,發現是“DOS下可執行程序”,于是成功且順利的執行我們的程序中DOS系統可執行部分,這部分DOS程序輸出“該程序不能在DOS上”執行的提示。
? ? ? ? 現在我們來看下MS-2.0節結構圖和我們結構體的對應關系:
? ? ? ? MS-Dos 2.0兼容Exe文件頭 ? 對應于IMAGE_DOS_HEADER中e_magic到e_ovno
? ? ? ? 未使用 對應于 e_res[4],雖說這段沒使用,但是我還是覺得這段很有意思的。我在做注冊表沙箱時,研究了下某公司的沙箱,可是它的沙箱不讓regedit.exe進入沙箱運行,于是我就改了e_res[4]這段數據中部分,從而讓修改后的regedit.exe在它的沙箱中運行。為什么呢?很容易想象,“MD5+簽名”是安全公司一大“安全準繩”。我改了這個沒啥用的數據段,不會影響程序運行,但是會使MD5不同,且簽名被破壞。這段地址是(文件起始偏移0x1C)
? ? ? ? OEM標志 對應于?e_oemid
? ? ? ? OEM信息 對應于?e_oeminfo
? ? ? ? OEM信息和PE文件頭偏移 之間存在一段空白,這段空白對應于?e_res2[10],這段數據和之前e_res[4]一樣,改改也無妨。這段地址是(偏移0x28)
? ? ? ? PE文件頭偏移 對應于 e_lfanew,其位于0x3C偏移處。
? ? ? ? MS-Dos 2.0占位程序和重定向表和未使用數據段如下圖,因為我也沒仔細研究過這個結構,所以也不能準確區分出哪塊是占位程序,哪塊是重定向表,哪塊是未使用段。
? ? ? ?從上面的數據我們可以看到,如果我們程序運行在Dos下,會輸出“This program connot be run in Dos mode"。
? ? ? ?那么NT系統加載我們的PE可執行程序呢?它不會去執行DOS占位程序,而會跳到PE頭位置繼續讀取和執行。PE頭位置就是e_lfanew字段的值,該值是PE頭和文件頭的之間的偏移量。如本例中就是0x000000E0。我們去該偏移去查看數據
? ? ? ?看到PE了么?這個PE是PE頭的Magic Num。我會在之后介紹PE文件頭及其相關知識。
? ? ? ?以上是非常常見的MS-DOS 2.0兼容Exe文件段,似乎有點枯燥。那我們現在思考一個問題,應該很有意思的。MS-DOS 2.0兼容Exe文件段是為了程序在DOS環境下運行時提示“不兼容”。但是目前DOS環境真的很少了,似乎我們真的沒必要去糾結于我們的程序是否會在DOS下提示“不兼容”,即使在DOS不能運行,也沒什么大不了的——反正功能也用不了。那么這么一大塊空間,我們是不是可以放點別的?是的,我們可以。舉個例子,我電腦上PPTV有個.ax文件叫(.ax文件就是DirectShow Filters的DLL文件)CoreAVC.ax。它就將它的導入表放在這段空間里!
? ? ? ?看到了?導入表是使用了Kernerl32.dll中的LoadLibraryA和GetProcessAddress兩個函數。再仔細看,而除了e_magic和e_lfanew兩個字段要保證OK外,其他字段和DOS代碼空間都可以被利用!那么不禁有人要問,這樣做有什么好處呢?首先,減少了PE文件大小(雖然只是那么一點點)。其次,它可以讓一些非常強大的分析工具分析出錯,比如我電腦上的PE Explorer,因為它足夠“較真”,所以它識別不出來該文件的信息。至于原因,我會在之后介紹導入表的時候給出來。這兒再廢話幾句,研究完PE文件格式,我發現一個道理:標準是標準,即使標準很嚴謹,但是如果標準實現不完善,那么也會產生各種有趣的漏洞和利用。
? ? ? ?貼一下代碼
#define DOSMAGIC 0x5A4DBOOL CGetPEInfo::IsMzFile() {size_t unWordSize = sizeof(WORD);ULONG ulFileSize =(ULONG)( m_lpFileEnd - m_lpFileStart );if ( ulFileSize < unWordSize ) {return FALSE;}WORD wMagic = 0;SafeCopy( &wMagic, m_lpFileStart, unWordSize );return (DOSMAGIC == wMagic) ? TRUE : FALSE;
}BOOL CGetPEInfo::GetDOSHeaderInfo() {if ( FALSE == IsMzFile() ) {return FALSE;}size_t unDosHeader = sizeof(IMAGE_DOS_HEADER);memset( &m_DosHeader, 0, unDosHeader );BOOL bSuc = SafeCopy( &m_DosHeader,m_lpFileStart, unDosHeader );if ( FALSE == bSuc ) {_ASSERT(FALSE);}else {m_dwInfoMask |= DOSHEADER;}return bSuc;
}
總結
以上是生活随笔為你收集整理的PE文件和COFF文件格式分析--MS-DOS 2.0兼容Exe文件段的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PE文件和COFF文件格式分析--概述
- 下一篇: PE文件和COFF文件格式分析——签名、