<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0in; margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体;} @page Section1 {size:8.5in 11.0in; margin:1.0in 1.25in 1.0in 1.25in; mso-header-margin:.5in; mso-footer-margin:.5in; mso-paper-source:0;} div.Section1 {page:Section1;} -->
为 PE 文件添加资源节
为什么想到要为 PE文件添加资源节呢?最初的需要将 gui.exe,添加到 console.exe的尾巴上,将 2个文件打包成一个文件 out.exe(其中 console.exe没有资源节, gui.exe有资源节,有程序图标和文件属性声明等)。 out.exe运行时释放并运行 gui.exe。显然按图示方式打包成的 out.exe不能显示图标,要是 out.exe能显示出和 gui.exe一样的程序图标,文件属性声明那就更爽了。
于是想到了将 gui.exe整个文件当成资源数据添加到 console.exe的末尾,然后修改数据目录 (DATA_DIRECTORY), 使打包后的文件 out.exe有资源节 ,并能显示出 gui.exe的图标,文件声明等 ,如下图 :
可以使用 stud_pe和 utraEdit手工为程序添加资源节,也可以写个程序来完成。以下是手工修改方法。
第一步,将 console.exe的文件数据拷贝到 out.exe中,再将 gui.exe的文件数据添加到 out.exe的末尾,如果 gui.exe的数据量不是 console.exe文件对齐 (fileAlignment)的整数倍的话,还需要在 out.exe再填充数据。本例中 console.exe的文件对齐是 0x1000,gui.exe的大小是 0x00009000,是 0x1000的整数倍,所以直接将 gui.exe的数据拷贝到 out.exe中,不需要填充。保存文件。记下添加的数据大小为 0x00009000.
第二步,用 stdu_pe打开 out.exe,将 numberofsection加 1。将 sizeofimage加上 0x00009000.。保存文件。
NumberOfSection = 4
SizeOfImage = 0x00013000
第三步,修改节表头的 Virtual Offset/Virtual Size/Raw Offset /Raw Size。
Virtual Offset = (上一节的 Virtual Offset + 上一节 Virtual Size)根据内存对象修正大小
Virtual Size = 实际节大小,不包括填充数据
Raw Offset = (上一节的 Raw Offset + 上一节的 Raw Size)根据文件对象修正大小
Raw Size = 总共添加的数据大小,包括填充数据。
本例中 :
文件对齐是: 0x00001000
内存对齐是: 0x00001000
上一节 Virtual Offset = 0x00008000
上一节 Virtual Size = 0x00001c68
上一节 Raw Offset = 0x00008000
上一节 Raw Size = 0x00001000
计算得出:
Virtual Offset = 0x00008000 +0x00001c68 = 0x0000a000
Virtual Size = 0x00009000
Raw Offset = 0x00008000 + 0x00001000 = 0x00009000
Raw Size = 0x00009000
用双击节,将以上数据写如文件,记得最后要 Save to File
第四步:修改数据目录。资源节的数据目录在 IMAGE_DATA_DIRECTORY的第 3个位置,包括 VirtualAddress 和 Size 两个字段。计算方法:
VirtualAddress = 新建资源节的 VirtualAddress + gui.exe的资源节的文件 offset
Size = gui.exe 中的大小
VirutalAddress = 0x0000A000 + 0x00007000 = 0x00011000
Size = 0x000018d0
将以上数据写如文件,记得最后要 Save to File
完成以上 4步以后,查看 Resource发现所有资源的目录结构都出现了。但是图标资源还是不能正确显示。
那是因为资源数据地址 000071d0是 gui.exe中的 RVA,需要对每个资源的数据地址做相应修改。
第五步 ,修改每个资源的 RVA。
OffsetToData是资源数据的 RVA,也就是上图中的 0x000071d0
Out的 OffsetToData = out 资源 DATA_DIRECTORY的 VirtualAddress + 资源数据相对资源起始位置的偏移
Out的 OffsetToData = out 资源的 DATA_DIRECTORY的 VirtualAddress +gui的 OffsetToData – gui资源的 DATA_DIRECTORY的 VirtualAddress
计算得出 OffsetToData = 0x00011000+ 0x000071d0 – 0x00007000 = 0x000111d0
只需要将 000071d0修改成 0x000111d0就可以显示出图标了,但遗憾的是 stud_pe无法修改这个值。可以通过 utraEdit修改。根据 <加密与解密 >295页所讲的方法找到 OffsetToData一个一个的修改。有一个简便的方法,就是在 utraEdit中 Ctrl+F查找要修改的数据,如 0x000071d0,如果只找到一处的话,那么这里肯定就是 OffsetToData的位置,直接修改。修改完了,保存文件,发现 out.exe已经可以显示图标了,用 stud_pe查看,每个资源都正常。
以上过程已经写程序实现了,代码以后在贴出来了。