内嵌代码补丁的分析和实践

2019.01.19 -

内嵌补丁,内嵌代码补丁的简称,在我们难以直接修改指定代码时,插入并运行“洞穴代码(Code Cave)”的补丁代码,实现对程序打补丁。
这种技术常用于对程序经过运行时压缩(或加密处理)而难以直接修改的情况。
原理图如下:
内嵌补丁
左侧是典型的运行时压缩或加密代码,EP代码先将加密的OEP代码揭秘,然后再跳转到OEP处。
如果需要打补丁的代码位于经过加密的OEP区域,是很难成功打上补丁的,这是因为解码过程中可能会解出不一样的结果。
右侧是一种简单的解决办法,在文件中另外设置称为“洞穴代码”的“补丁代码‘,EP代码解码完成后,修改JMP指令,运行洞穴代码。在洞穴代码中执行补丁代码后(此时已经揭秘OEP),再跳转到OEP处。也就是说,每次运行时都要对进程内存的代码打补丁,所以这种打补丁的办法成为”内嵌补丁“法。
下面以一个简单的例子实践说明一下:
1,首先运行一下程序:
内嵌补丁
内嵌补丁
程序有两个弹窗,我们的目标是修改对话框中的两个字符串。
2,OD走起:
内嵌补丁
我们可以很清楚地看到,有两个字符串很怪,明显是经过处理了。
而且EP代码十分简单,而在401007之后是加密代码。看一下字符串:
内嵌补丁
都被加密了,在这个时候我们是无法通过普通的方法找到指定字符串的
3,跟踪进入401001处的CALL,进入4010E9,然后继续进入CALL看下:
内嵌补丁
我们在这里看到了一个循环体,这是一段解密循环。
004010A3 |> /8033 44 /XOR BYTE PTR DS:[EBX], 44 ;对4010f5-401248的数据进行与44的异或解密然后跟踪进入4010B3的CALL:
内嵌补丁
在这里我们看到了另外两个解密循环,
004010C8 |> /8033 07 /XOR BYTE PTR DS:[EBX], 7 ; 对401007-401086的数据进行与7的异或解密004010DB |> /8033 11 XOR BYTE PTR DS:[EBX], 11 ; 对4010f5-401248的数据进行与11的二次异或解密
尤其是第三个解密循环,这里的解密区域与第一个解密循环的区域是一样的,这说明这段空间的数据进行了双重加密处理。
4,执行完三个解密循环后,通过4010B6的CALL进入401039:
内嵌补丁
在这里我们需要注意,这里在401046地址处有校验和计算的循环,这是从4010F5~401248的区域每次读入4个字节,进行数值加法运算,累加结果保存在EDX寄存器。循环结束,EDX中保存校验和值。
根据前面的过程我们容易知道,4010F5~401248的区域是一个双重加密区域,我们需要修改的字符串就在这里401062-401068处的CMP/JE命令将校验和(EDX)与31EB8DB0做对比,相同这说明代码没有被改动,然后JMP到OEP,不同这输出错误信息。
5,进入OEP:
内嵌补丁
这里需要注意40123E处的调用DialogBoxParamA(),它的结构大家可以上网查一下,我们需要关注它的第四个参数lpDialogFunc用来指出Dialog Box Procedure的地址。
我们可以看到这行代码的上面就是push 4010F5,所以第四个参数DlgProc(OD中的表示)的地址为4010F5.
6,进入4010F5查看:
内嵌补丁
我们看到了我们需要修改的字符串。
7,OK,原理和程序流我们都清楚了,接下来开始打补丁:
首先是选择补丁代码的位置,这里我放在第一个节区(.text)
位置选择:使用LordPE看到.text的SizeOfRAW为400,VirtualSize为280,那么区域680~800是没有被使用的,我们可以放在这里。
重新调试程序,运行到OEP(40121E):
内嵌补丁
401280(680-400+1000)处为空白区域,在此处我们填入补丁代码:
[Asm]
mov ecx,0c
mov esi, 004012a8
mov edi,00401123
rep movs ptr es:[edi], byte ptr ds:[esi]
mov ecx,9
mov esi,004012b4
mov edi,0040110a
rep movs ptr es:[edi], byte ptr ds:[esi]
jmp 0040121e

然后在4012a8与4012b4处放入我们要修改的字符串:“ReverseCore”,”Unpacked”
内嵌补丁
8,最后一步:直接修改文件以运行创建的补丁代码:
我们前面知道在401083处有JMP 40121E,40121E是我们的OEP代码,所以修改这条JMP到我们的补丁代码地址就可以了
需要注意的是,401083位于原来的加密区域,也就是说直接打开二进制文件看到的是加密后的数据
内嵌补丁
解密是 XOR 7,那么我们再COR 7回去就可以了:
也就是E9 F8 01与7异或,得到EE FF 06,这个才是正确的跳转到我们补丁代码地址的指令数据,写入,验证:
内嵌补丁
内嵌补丁
内嵌补丁
OK,搞定~
过程中涉及到的一些位置定位需要大家亲自动手计算一下,温故知新嘛,就当稳定基础了~。

阅 268
0

内嵌补丁,内嵌代码补丁的简称,在我们难以直接修改指定代码时,插入并运行“洞穴代码(Code Cave)”的补丁