Jirairya

内嵌补丁练习


内嵌补丁是内嵌代码补丁的简称,难以直接修改指定代码时,插入并运行被称为“洞穴代码”(Code Cave)的补丁代码后,对程序打补丁。常用于对象程序经过运行时压缩(或加密处理)而难以直接修改的情况。

内嵌代码补丁

图左描述的是运行时压缩代码(或者加密代码)。EP代码先将加密的OEP代码解密,然后再跳转到OEP代码处。若要打补丁的代码存在于经过加密的OEP区域是很难打补丁的(即使知道代码所在位置),因为解码过程可能会出现解出完全不同的结果。

因此可用右图解决,在文件中另外设置被称为“洞穴代码”的补丁代码,EP代码解密后修改JMP指令,运行洞穴代码。在洞穴代码中执行补丁代码后,再跳转到OEP处。即,每次运行时(运行另外的补丁代码)都要对进程内存的代码打补丁,称为内嵌补丁。

普通代码补丁和内嵌补丁的不同 :

  代码补丁 内嵌补丁
对象 文件 文件&内存
次数 1次 文件中1次,内存中每次运行时
方法 直接(直接指定位置打补丁) 间接(提前设置洞穴代码,在内存中对指定区域解密时打补丁)

Patchme

消息框和主对话框

调试:查看代码流

EP代码非常简单,地址401007之后就是加密代码。为了查找到消息框和主对话框中的字符串,就鼠标右键进行所有参考文本字符串查找。全为加密状态,无法查找到指定字符串。 查找参考文版字符串

跟踪进入401001地址处CALL命令调用的函数(4010E9),跟进一段时间后:

解密循环

该代码是解密循环代码。地址4010A3处的XOR BYTE PTR DS:[EBX],44语句使用XOR命令对特定区域(4010F5~401248)解密。跟踪进入地址4010B0处CALL命令调用的函数(4010BD),可看到另外两个解密循环。

另一段解密代码

地址4010C8处的XOR命令用来解密401007~401085区域,然后再使用4010DB地址处的XOR命令对4010F5~401248区域解密。该区域和4010A3处解密区域一致,由此可知该区域是双重加密。4010BD函数调用完毕后遇到4010B6地址处的CALL 401039命令,跟踪进入被调用的函数:

004010B6处函数

00401039函数

401039函数中需要注意的是位于4401046地址处的校验和计算循环。首先使用401041地址处的MOV EDX,0命令,将0代入(初始化)EDX。然后使用401046地址处的ADD命令,从4010F5~401248区域以4个字节为单位依次读入值,进行加法运算,将累加结果存储在EDX寄存器。

循环结束时,EDX寄存器中存储着某个特定的值,这就是校验和值。由前面的讲解可知,该校验和计算区域是一个双重加密区域。可推测,要修改的字符串就在于此。

EDX寄存器为4字节大小,像这样不断向其中加上四个字节的值就会发生缓冲区溢出。一般校验和计算中常忽略一出问题,使用最后一个保存在EDX的值。

401039函数内部

位于地址401062~401068处的CMP/JE命令用来计算得到的校验和(存储在EDX寄存器的)值与31EB8DB0比较,若相同(代码未改过)则由401083地址处的JMP指令跳转到OEP(40120.)处相同;若不同则出现”CrC of this file has been modified!”终止程序。

这种校验和计算方法常用来验证特定区域的代码/数据是否被改动过。只要指定区域中的一个字节发生改变,校验和值就会发生改变。所以更改了指定区域中的代码/数据时,一定要修改校验和比较相关部分。


下一篇 CHAOS Framework

Comments

Content