PE文件和COFF文件格式分析--MS-DOS 2.0兼容Exe文件段
来源:互联网 发布:数控加工螺纹的编程 编辑:程序博客网 时间:2024/05/21 22:26
MS 2.0节是PE文件格式中第一个“节”。其大致结构如下:(转载请指明来源于breaksoftware的csdn博客)
在VC\PlatformSDK\Include\WinNT.h文件中有对MS-DOS 2.0兼容EXE文件头的完整定义
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG 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文件格式分析--概述
- PE文件 COFF文件格式
- PE文件和COFF文件格式分析——导出表
- PE文件和COFF文件格式分析——节信息
- PE文件格式之MS-DOS头,PE文件头,区块
- PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1
- PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头2
- PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头3
- PE文件和COFF文件格式分析——RVA和RA相互计算
- PE文件和COFF文件格式分析——导出表的应用——一种插件模型
- PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL
- PE文件详解之MS-DOS头
- PE文件详解之MS-DOS头
- PE文件-PE文件格式
- COFF 与PE文件
- PE文件和COFF文件格式分析——导出表的应用——一种摘掉Inline钩子(Unhook)的方法
- c#中的日期格式转化
- 关于安装SQL2005后没有management sudio 或者是安装sql service database services失败的解决方案
- 2416的LED驱动 for wince6
- Delphi图像处理 -- 表面模糊
- ContentProvider和ContentResolver
- PE文件和COFF文件格式分析--MS-DOS 2.0兼容Exe文件段
- ubuntu下使用vi是方向键变乱码 退格键不能使用的解决方法
- macbook pro 在没有光驱的情况下使用usb 的u盘来安装windows
- Slackware Linux:更新字体
- 在Ubuntu桌面显示计算机等文件夹
- 算法导论笔记(第一章)
- 拖延症
- hjjkhkjkj
- STL示例05(泛型算法)