作者:后果搞活棵_654_962 | 来源:互联网 | 2023-10-10 16:15
TinyPe是为了挑战做出更小的PE文件而出现的,现在对它进行分析.从书上的网站中找到网址并下载.虽然这个文件在我的Winxpsp3上无法运行,但不妨碍分析.可以看到这个PE文件的
TinyPe是为了挑战做出更小的PE文件而出现的,现在对它进行分析.从书上的网站中找到网址并下载.
虽然这个文件在我的Win xp sp3 上无法运行,但不妨碍分析.
可以看到这个PE文件的大小已经被减少到了84H字节.
且可以正常运行:
PE知识可知:DOS头的大小为40字节,NT头为F8字节,此处必然进行了删减和覆盖.
先观察DOS头,由于DOS头的数据中,重要的成员就2个,DOS签名(MZ)和NT头的偏移.
前18个成员是word类型,占2字节,因此e_lfanew的地址是35字节处:此处值为4.DOS存根被人为删减掉了.
PE出现的位置也确实是在第4个字节处.
下面分析NT头中的文件头:
第2个成员machine码为0x14c,表明为intel 386的CPU.
第3个成员NumberOfSections,此处显示为1.
第4个成员TimeDateStamp,第5个成员PointerToSymbolTables(指向符号表(主要用于调试)),第6个成员NumberOfSymbols(符号表中符号的个数),被user32.dll(导入函数名)占据.
第7个成员SizeOfOptionalHeader值为40.
第8个成员Characteristics值为10f,表明是32位字的机器,且重定位表、LineNumbers、本地符号表被删除,文件可执行,支持积极修剪( IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010),此属性在win 2000就已废弃.
下面分析NT头中的可选头(找到10b/20b即可):图中只标明了
在X64dbg中查看:
如图,只有7C这一个地方改变了.从前面的知识我们可以知道,PE装载器会将获得的函数地址放在IAT数组值中.而存放IAT地址的就是FirstThunk.
于是发现在6C处存放着7C的地址,6C处即是FirstThunk.往前推,68H处存储着0C,而0C处存储着库名称字符串,因此可以确定,从5C开始,就是IID结构体.
该IID结构体的内容为:
Address |
SIZE
|
NAME
|
VALUE
|
5C
|
DWORD
|
OriginalFirstThunk
|
0
|
60
|
DWORD
|
TimeDateStamp
|
FF0002
|
64
|
DWORD
|
ForwarderChain
|
7C
|
68
|
DWORD
|
Name1
|
C
|
6C
|
DWORD
|
FirstThunk
|
7C
|
接着,存储着IID结构体地址的是DataDirectory[1].VirtualAddress(5C)------84
可以看到它的Size被省略掉了,且Address只有一个字节.
至此,整理清楚了基本上所有的问题.
总结一下:
1#.Dos头可以只保留MZ和e_lfanew. Dos存根可以不要
2#.文件头可以只保留machine, NumberOfSections, SizeOfOptionalHeader, Characteristics
3#.可选头删除 Major/Minor LinkerVersion , CheckSum,Subsystem,DllCharacteristics,SizeOfStack Reverse/Commit.
4#.ExportDirectory.VirtualAddress不能省,改为0后无法运行. ????? 此处还没有理解到为什么还需要Export ????
5#.ImportDirectory.Size可以省,VirtualAddress可以只保留一个字节.