打造超小PE文件
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文件了):
http://bmu009001.chinaw3.com/JoenTools/MinPe.rar
看看大牛都是如何做的
;************************************************************************* ;打造超小的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, 怎么才能够搞个代码高亮舒服点的, 你要知道可要教教我!
网友评论:
发表评论
Warning: Undefined variable $user_ID in /www/wwwroot/joenchen.com/wp-content/themes/x-agan/comments.php on line 66
您必须登录 才能进行评论。
可以看下这个里面有你现在用的东东针对asm的syntax
http://www.undermyhat.org/blog/2009/09/list-of-brushes-syntaxhighligher