本节将介绍在PE最后一节添加补丁代码的工具开发。
本节必须掌握的知识点:
编程思路
手工打造目标PE文件
源代码
工具测试
14.1.1 编程思路
■在PE最后一节中插入程序的基本思路如下:
●步骤1在PE文件的最后一节将补丁代码添加进去。
●步骤2修改最后一个节表的内容,主要是SizeOfRawData、PointerToRawData和 Characteristics三个字段的值。
●步骤3修正PE文件头部的相关字段,这些字段包括:映像尺寸SizeOflmage、函数的入口地址 AddressEntryPoint。
●步骤4修正嵌入补丁框架中E9指令的操作数,即代码中的跳转指令地址。
●根据以上分析的编程思路,可以知道编写补丁工具的大致流程如下:
1.获得补丁代码段大小,因为假设补丁程序使用了嵌入框架,所以数据、代码均在代码 段中,补丁程序没有数据段定义。
2.将目标文件按照文件对齐粒度对齐。这主要是为了防止有一些文件结尾时,不考虑对 齐粒度,从而导致在最后一节添加内容时造成不对齐。
3.求最后一节在文件中的偏移。
4.求最后一节的大小并按照文件对齐粒度对齐。
5.计算出添加了补丁程序的新文件的大小(原文件对齐后的值+补丁大小)。
6.按照计算出的新文件大小申请内存空间,并将原文件复制到申请的内存空间起始位置。
7.复制补丁代码到dwNewFileAlignSize 处。
8.计算最后一节的SizeOfRawData和Misc的值,并更正;然后,设置该节的属性为可 执行、可读、可写,即0c0000060H。
9.修正文件头部关键字段SizeOflmage。
10.修正函数入口地址和嵌入补丁框架最后的E9转移指令的操作数。
11.将内存中的内容复制到磁盘文件中。
14.1.2 手工打造目标PE文件
实验九十九:手工打造目标PE文件
使用Winhex工具,在目标PE文件的最后一节中手动添加补丁代码,并修改PE头相关字段。
要求:先执行补丁代码,然后再继续执行目标程序原有功能。
■补丁程序:patch1.exe:加载pach2.dll。
■目标程序:notepad.exe(32位记事本)。
■实现目标:将补丁程序添加到目标程序的最后一节。
■手工添加的步骤:生成NEWnotepad32文件。
●步骤1:在目标PE文件的最后一节添加补丁代码。
00010400 8B FF E8 13 00 00 00 4C 6F 61 64 4C 69 62 72 61 ??...LoadLibra
00010410 72 79 41 00 70 61 63 68 32 00 5A 52 52 64 A1 30 ryA.pach2.ZRRd?
00010420 00 00 00 8B 40 0C 8B 70 1C AD 8B 58 08 8B 73 3C ...婡.媝.瓔X.媠<
00010430 03 F3 8B 76 78 03 F3 8B 7E 20 03 FB 8B 4E 14 56 .髬vx.髬~ .麐N.V
00010440 33 C0 57 51 8B 3F 03 FB 8B F2 33 C9 B1 0C F3 A6 3繵Q?.麐?杀.螃
00010450 74 08 59 5F 83 C7 04 40 E2 E8 59 5F 5E 8B 7E 24 t.Y_兦.@忤Y_^媬$
00010460 03 FB D1 E0 03 F8 66 8B 07 8B 7E 1C 03 FB C1 E0 .?鴉?媬..?
00010470 02 03 F8 8B 07 03 C3 5A 83 C2 0D 52 FF D0 E9 1A ..鴭..肸兟.R虚.
00010480 43 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 C.............
00010490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000104A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000104B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000104C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000104D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000104E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000104F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000105A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000105B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000105C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000105D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000105E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000105F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
●步骤:2修改最后一个节表的内容,主要是SizeOfRawData、PointerToRawData和 Characteristics三个字段的值。
目标程序:notepad.exe 的最后一节.rsrc
00000220 2E 72 73 72 63 00 00 00 .rsrc...
00000230 20 7F 00 00 00 B0 00 00 00 80 00 00 00 84 00 00 ....?..€...?.
00000240 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 40 ............@..@
补丁后NEWnotepad32.exe文件:
00000220 2E 72 73 72 63 00 00 00 .rsrc...
00000230 00 82 00 00 00 B0 00 00 00 82 00 00 00 84 00 00 .....?..?..?.
00000240 00 00 00 00 00 00 00 00 00 00 00 00 60 00 00 E0 ............`..?
1.SizeOfRawData字段:B0 7F 00 00
计算方法:原notepade.exe 最后一节.rsrc节的大小为00007F20h,添加patch1.exe补丁代码200h为00008200h。
patch1.exe补丁代码节:
000001A0 2E 74 65 78 74 00 00 00 83 00 00 00 00 10 00 00 .text...?......
000001B0 00 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................
000001C0 00 00 00 00 20 00 00 60 .... ..`
2.PointerToRawData字段:00 82 00 00。
计算方法:
patch.exe补丁代码大小为00000200h,加原文件内对齐大小00008000h = 00008200h。
3.Characteristics字段:节属性修改为可读可写可执行,60 00 00 E0 或者 60 00 00 C0。
●步骤3:修正PE文件头部的相关字段,这些字段包括:映像尺寸SizeOflmage、函数的入口地址 AddressEntryPoint。
1.修改IMAGE_OPTIONAL_HEADER32.SizeofImages (50h)内存中整个PE映像尺寸 增加1000h,00 30 01 00 改为 00 40 01 00。
2.修改程序的入口地址:
原入口地址:9D 73 00 00。
修改后地址:00 30 01 00。