本文最后更新于 401 天前,其中的信息可能已经有所发展或是发生改变。
内容目录
编写最小的PE文件
在Windows上新建一个minPE.asm文件,使用vs的x86 Native Tools Command Prompt for VS 2019来编译
使用编译脚本 build.bat
ml /c minPE.asm
link /entry:START /subsystem:windows /merge:.rdata=.text /ALIGN:16 minPE.obj
注意:
这个ALIGN:16对齐值给512,就没有版本问题了(在xp上不行)
如果是在xp上运行,对齐值给4就可以,但是需要用VC++6.0编译
minPE.asm
.386
.model flat,stdcall
option casemap:none
includelib user32.lib
includelib kernel32.lib
extern MessageBoxA:proto : dword, : dword, : dword, : dword
extern ExitProcess:proto : dword
.const
g_szText db "pe for pe teach",0
g_szTitle db "tiptip",0
.code
START proc
push 0
push offset g_szText
push offset g_szTitle
push 0
call MessageBoxA
push 0
call ExitProcess
ret
START endp
end
分析PE文件内容
如果32的PE文件在16位的Dos运行,会怎么样?
可以运行啊,只运行16位的部分,打印出一提示语,先看下PE头的大小字节;
Dos的16位的格式
前面部分是PE的开头,紧挨着是Dos的16位的格式,这几句是调用了汇编代码中断输出格式
ida上看一下16位的汇编代码
stub[]
// DOS头结构体: _IMAE_DOS_HEADER
typedef struct _IMAE_DOS_HEADER { //DOS .EXE header 偏移
WORD e_magic; //幻数 Magic number; 0x00
// 中间部分成员是为了兼容16位操作系统...可修改可忽略...
LONG e_lfanew; //File address of new exe header 0x3C
// 最后部分应该有一个stub[]
stub[]
} IMAGE_DOS-HEADER, *PIMAGE_DOS_HEADER;
stub[] (也就是dos字节)的字节范围
把stub抹成0,在32或者64位下可以运行吗? 当然可以, 所以可以在这里面藏一些代码;
该结构体中两个重要字段(不可更改),分别是 e_magic,和 e_lfanew字段:
● 第一个字段 e_magic:该字段WORD类型,2字节 ,存储字符是“MZ”,对应PE文件的开头,是PE文件的标识符,前两个字节是绝对不能修改的。该标识符在Winnt.h头文件中有一个宏定义,定义如下:
#define IMAGE_DOS_SIGNATURE 0x4D5A // MZ
#define IMAGE_OS2_SIGNATURE 0x4E45 // NE
#define IMAGE_OS2_SIGNATURE_LE 0x4C45 // LE
● 最后一个字段 e_lfanew:该字段LONG类型,4字节,对应PE文件的0x3C处 :该处的值(000000C0)表示NT头在文件中的偏移地址,即32位及以上系统文件头在文件中真正的偏移。这个值可以修改,注意需要把NT头IMAGE_NT_HEADERS结构体,也要修改该值对应的偏移值处
IMAGE_DOS_HEADER 到 IMAGE_NT_HEADERS 中间有一部分数据 叫做 stub code 也叫残留代码,残留数据,这个里面是跑在16位 dos系统里面的代码,起一个提示作用