内嵌补丁

逆向工程核心原理--->内嵌补丁

参考:https://blog.csdn.net/ski_12/article/details/80670045

一 分析程序



1.1


内嵌补丁_第1张图片

此处循环,是对4010F5~401248的区域解密,对每一个字符和0x44异或。继续跟踪进入4010BD。

1.2


内嵌补丁_第2张图片

跟进4010BD函数后,发现两个循环。第一个仍然是对401007地址处的区域解密,循环7F次,所以是401007~401085的每一个字符和0x7异或。

第二个仍然是对4010F5~401248区域解密,每个字符和0x11异或。说明这4010F5~401248区域被加密了两次,所以此处解密两次。

1.3


内嵌补丁_第3张图片

继续往下分析,进入401039地址处的函数。上来就是一个循环,是对4010F5区域的字符的值,没每个字节,加到edx里面。然后到下面和0x31EB8DB比较。如果被修改过,直接跳向错误的地方。在401083处有一个跳向OEP的跳转。

1.4


内嵌补丁_第4张图片


内嵌补丁_第5张图片

来到OEP之后因为被解密过后的代码会被视为数据,而不是指令,所以我们需要点分析代码,就变为正常的代码了。开头就是GetModuleHandle,获取一个应用程序或动态链接库的模块句柄。只有在当前进程的场景中,这个句柄才会有效。说明下面一个DialogBoxParmA的四个参数(IpDialogFunc:指向对话框过程的指针

)是4010F5。跟踪到之后发现那些我们要修改的字符串了。

二 内嵌补丁

由上述分析可知,实际要打补丁的字符串都保存在经过两次加密的区域。

整个的操作过程为:先在文件适合的位置插入洞穴代码,该补丁代码更改字符串并通过JMP指令跳转至OEP处,再在004010F5~00401248区域将JMP OEP指令修改为JMP补丁代码。

当补丁代码较少时,使用第一种方法即在文件空白的区域插入补丁代码。

2.1

首先查看.text段的大小。

可以看到,第一节区的在磁盘文件的大小为400,映射到内存的大小为280,即第一节区从磁盘文件加载到内存后有大小为180(RAW 680~800区域 > RVA 1280~1400区域)的区域并未使用,该区域为空白区域(NULL-Padding),可以用来填写补丁代码。另外需要注意的是,1E4的属性值中添加的IMAGE_SCN_MEM_WRITE(可写属性),在程序进行解码操作时,必须在该节区头添加可写属性以获得相应内存的可写权限,否则会引发非法访问的异常。对于一个普通的PE文件,其代码节是无写权限的,但是压缩工具、Crypter等文件的代码节都有可写权限。

注意,内存中的节区大小为280,但实际节区的内存大小并非280,而是以Section Alignment的整数倍扩展,即实际大小为1000。


内嵌补丁_第6张图片

2.2

首先写洞穴代码,最后记得跳转到OEP处。


内嵌补丁_第7张图片


内嵌补丁_第8张图片

在跳向补丁代码的地方,因为此处的代码为和0x7解密之后的。即 E9 F8 01应该是我们修改经过解密之后的值,那解密之前呢?因为一个数的两次异或会回到本身。所以

E9 xor 7= EE  F8 xor 7= FF  01 xor 7= 6

则EE FF 6 即为解密前的数据,所以我们应该修改此值。

2.3

首先是保存洞穴代码,复制到可执行文件,退出OD。在十六进制编辑器中修改上面的数据。

而文件中实际的加密形态为(VA 00401083 > RVA 1083 > RAW 483):

在此483处我们看到我们在上一步修改的值了,这个E9 F8 01 我们已经知道是解密后的,


所以修改为 EE FF 6 ,然后保存文件。


2.4  运行查看效果。



你可能感兴趣的:(内嵌补丁)