PE文件能够多小?? 一次一次的打破了我的想象, 网上有人发了133B的PE文件, 我就在想他是如何做到的? 分析了下. 相当的给力. 不知道还能不能够再小?
网上不少的手写PE文件的, 不过大多200B以上. 原来我自己也倒腾过PE文件, 不过都是按照套路一个一个字段的填写. 昨天偶然看了下人家写的. 那是多么的给力啊, IMAGE_DOS_HEADER和IMAGE_NT_HEADERS进行了重叠. 重叠还是小Case. 我们知道IMAGE_NT_HEADERS的IMAGE_OPTIONAL_HEADER32里面有非常多字段是用不到的, 所以即使IMAGE_NT_HEADERS和IMAGE_DOS_HEADER重叠也是节约不了多少空间的. 那么IMAGE_OPTIONAL_HEADER32头里面那些字段还应该怎么利用呢? 答案大牛已经给出了,把代码,和导入表, 字符串资源全部整合进去, 打造出来的PE文件就一个IMAGE_DOS_HEADER + IMAGE_NT_HEADERS的大小, 给力, 非常的给力.
特别是到最后这个地方, Exporot导出表居然只有一个字节?? 我倒. 以前还不知道导出表一个字节也可以跑. 因为原来是两个dword类型, 一个是偏移一个是大小, 他大小直接省略, 偏移用了一个字节. 可以吗? 这样可以吗? 事实证明这个程序确实是可以跑起来的. 只能够说明作者对PE文件, 和Windows的装载机制很了解了.
PE文件的代码是从njhhack的blog上down下来的, 不过是TASM的语法, 和Masm虽然差别不是很大, 不过我也懒得去倒腾Tasm了. 所以我修改成了Masm的语法, 我至今不知道Masm里面如何才能够生成一个没有任何东西的.exe文件, 最后我只能退而求其次了. 使用com文件, 这个好使. 你搞的是什么, 最后就是什么, 一点东西都不多. 原来Fasm一直有那么多的信仰者. 也是有道理的.. 有的时候用Masm做点规则之外的事情也是很麻烦. 比如像用Masm生成一个不带任何框架的函数, 也是很麻烦, C语言还有类似的关键字,或许Masm有这个语法. 不过也没有见人搞过. 有知道的一定告诉我哈. 不要和我说直接定义标号什么的, 我想生成一个不带框架的函数. 然后导出. 不知道怎么搞定. 扯远了, 还是看看这个PE文件吧!
参考: njhhack的专栏 绝影的blog
http://blog.csdn.net/njhhack/article/details/2120019
http://blog.csdn.net/hitetoshi/article/details/3296253
PE文件下载(直接点击里面的make.bat就可以生成一个133B的PE文件了):
MinPe.rar
看看大牛都是如何做的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
;***************************************************************************
;打造超小的win32 PE文件, 编译我已经都给出了, 只需要运行目录下的make.bat
;就可以生成一个130K的PE文件, 灰常的给力啊.
;***************************************************************************
.386
.model tiny
ImageBase equ 400000h ;模块基址
.Code
DefineStart:
;===========================================================================
;想要压缩PE文件首先要做的事情就是必须把Dos头和Pe头进行融合. 还有导入表,
;好好的看了人家搞的MinPE, 真是佩服的五体投地啊,
;===========================================================================
DosSignature word 5a4dh ;MZ 标志
word 0ffffh
NtSignature dword 4550h ;PE 标志
Machine word 014ch ;Intel 80386
MumberOfSection word 1 ;节区数量
;===========================================================================
;这里正好是IMAGE_FILE_HEADER的3个字段, 什么值都是无所谓的
;===========================================================================
User32 byte "user32.dll", 0, 0ffh
;TimeDateStamp dword 0 ;FileHeader-->TimeDateStamp
;PointerToSymbolTable dword 0 ;FileHeader-->PointerToSymbolTable
;NumberOfSymbols dword 0 ;FileHeader-->NumberOfSymbols
SizeOfOptionalHeader word OptionHeaderSize;可选头大小
Characteristics word 010fh ;属性标志(exe)
;===========================================================================
;可选头
;===========================================================================
Magic word 10bh ;普通可执行镜像10bh
LinkerVersion word 0ffffh ;连接器版本, 随便
;===========================================================================
;这里正好是IMAGE_OPTIONAL_HEADER的3个字段, 也是无所谓什么值的
;===========================================================================
SzMessageBoxA byte "MessageBoxA", 0
;SizeOfCode dword 0 ;OptionalHeader-->SizeOfCode
;SizeOfInitializedData dword 0 ;OptionalHeader-->SizeOfInitializedData
;SizeOfUninitializedData dword 0 ;OptionalHeader-->SizeOfUninitializedData
AddressOfEntryPoint dword Start ;程序入口
;===========================================================================
;这里又有2个字段是随便什么值的, 8字节不要浪费
;===========================================================================
;BaseOfCode dword 0
;BaseOfData dword 0
Next3:
word 15ffh ;Call MessageBoxA
dword ImageBase + IAT1
ret
byte 0ffh
;===========================================================================
_ImageBase dword ImageBase ;建议装载地址
SectionAlignment dword 4 ;内存对齐 DosHead-->e_lfanew
FileAlignment dword 4 ;文件对齐
;===========================================================================
;这里又是可选头的2个字段什么值无所谓, 又可以填充8个字节的代码
;===========================================================================
;OperationSystemVersion dword ;操作系统版本
;ImageVersion dword ;用户自定义版本
Start:
mov eax, offset SzMessageBoxA + ImageBase
jmp Next1
byte 0ffh ;补够8字节
;===========================================================================
;这里2个字段8字节空间又可以填充一点代码
;===========================================================================
;SubsystemVersion dword 任意
;Win32VersionValue dword 任意
word 4
Next1:
push 65
push eax
push eax
jmp Next2
;===========================================================================
SizeOfImage dword ImageSize ;任意数值,要求大于SizeOfHeaders
SizeOfHeaders dword FileHeaderSize ;文件头(Dos头, Pe头, 区表)大小
OptionHeaderSize = $-Magic
;===========================================================================
;这里很多字段都是无所谓的, 一大片空间不能够浪费, 制造一个导入表,灰常给力
;===========================================================================
IAT:
CheckSum dword 0 ;OriginalFirstThunk(无所谓值我们有FirstThunk就够了)
Subsystem word 2 ;TimeDateStamp(无所谓值)
DllCharacteristics word 0ffh ;
SizeOfStackReserve dword IAT1 ;任意数值,(Virtual Size), ForwarderChain
SizeOfStackCommit dword User32 ;任意数值,(Virtual Address),Name1, dll名称
SizeOfHeapReserve dword IAT1 ;任意数值,(Raw Data Size), FirstThunk IAT表
SizeOfHeapCommit dword User32 ;任意数值,(Raw Data Offset)
;===========================================================================
;一个可选头就把代码和导入表全部包括进去了, 以前真是太浪费了..可耻啊
;这里4个字节不要浪费, LoaderFlags没有什么用, 加4个字节代码
;===========================================================================
;LoaderFlags dword 0 ;调试标记, 无所谓值
Next2:
push 0
jmp Next3
NumberOfRvaAndSizes dword 2h ;程序数据目录的项数
;===========================================================================
;接下来的就是数据目录了
;===========================================================================
IAT1:
Ide00_Export dword SzMessageBoxA-2, 0;这个输出表应该没有什么意义, 占位置的
;===========================================================================
;我倒, 5c刚好是IAT这个地方, 输出表只占用了一个字节也可以?太了解
;windows装载了吧
;===========================================================================
Ide01_Import byte IAT - DefineStart
FileHeaderSize = $
ImageSize = FileHeaderSize + 4
END
|
里面注释非常, 齐全了. 我就不多说了, 总之就是前面说的DOS头和NT头,重叠了, 然后导入表放在了可选头里面. 代码也在可选头里面, 我只是分析了下,
原作者贴了个代码, 什么也没有说, 估计他认为大家应该都是了解PE文件格式的..我就加了些注释, 应该有些帮助才是.
代码在网页上不好看, 建议直接去下载那个源代码然后分析, 条件不够啊, 我也不知道怎么倒腾WordPress, 怎么才能够搞个代码高亮舒服点的, 你要知道可要教教我!