内嵌补丁练习

内嵌补丁

  1. 内嵌补丁时内嵌代码补丁的简称,难以直接修改指定代码时,插入并运行被称为洞穴代码的补丁代码后,对程序打补丁。常用于对象程序经过运行时压缩而难以修改的情况。
    在这里插入图片描述

  2. 左图描述的是典型的运行时压缩代码,EP代码先将加密的OEP代码解密,然后再跳转到OEP代码处,若要打补丁的代码存在于经过加密的OEP区域是何难打补丁的,因为解码过程中可能会解出完全不同的结果。

  3. 解决问题的办法是,在文件中另外设置被称为“洞穴代码”的“补丁代码”,EP代码解密后修改JMP指令,运行洞穴代码,再洞穴代码执行补丁代码后(因为已经解密OEP,故可以这样修改),再跳转到OEP处。

Patchme

  1. 运行Patchme程序。
    在这里插入图片描述
    在这里插入图片描述
  2. 这个patchme程序比较简单,只要修改上述2处字符串即可。但问题是程序文件中2个字符串都处于加密状态,难以修改。

调试

  1. 首先使用OllyDbg打开程序文件。
    在这里插入图片描述
  2. 地址401007值后即使加密代码,为了查找上述字符串,点击右键->Search for All referenced text strings。
    在这里插入图片描述
  3. 所有的字符串都处在加密状态,这种情况下无法查找到指定字符串,跟踪进入401001地址处CALL命令调用的函数(4010E9),执行一段时间后碰到一个循环:
    在这里插入图片描述
  4. 这段代码就是解密循环,地址4010A3处的XOR BYTE PTR DS:[EBX],44语句使用XOR命令对特定区域(4010F5~401248)解密,跟踪进入地址4010B0处CALL命令调用的函数(4010BD),可以看到另外2个解密循环:
    在这里插入图片描述
  5. 地址4010C8处的XOR命令用来解密401007~ 401085区域,然后再使用4010DB地址处的XOR命令对4010F5~401248区域解密,特别是该区域于上述解密区域一致,由此可知该区域经过双重加密处理。
    在这里插入图片描述
  6. 4010BD函数调用完毕后遇到4010B6地址处的CALL 401039命令,跟踪进入被调用的函数:
    在这里插入图片描述
  7. 401039函数中需要注意的是位于401046地址处的校验和计算循环,首先使用401041地址处的MOV EDX,0命令,将0代入EDX,然后使用401046地址处的ADD命令,从特定地址区域(4010F5~401248)以4字节为单位依次读入值,进行加法运算后,将累加结果存储到EDX寄存器。
  8. 循环结束时,EDX寄存器中存储着某个特定值,这就是校验和值,该校验和计算区域是一个双重加密区域,可以推测,我们要修改的字符串就存在于此。
  9. 位于地址401062~401068处的CMP/JE命令用来将计算得到的校验和值与31EB8DB0比较,若相同,则由401083地址处的JMP指令跳转到OEP处,若不同,则输出错误信息“CrC of this file has been modified!!!”,终止程序。
  10. 下面显示的时OEP代码,用来运行对话框,执行位于40123E地址处的CALL user32.DialogBoxParamA()命令后,即弹出对话框,下面时DialogBoxParamA()API的定义:
    在这里插入图片描述
INT _PTR WINAPI DialogBoxParam(
	__in_opt HINSTANCE hInstance,
	__in 	 LPCTSTR lpTemplateName,
	__in_opt HWND hWndParent,
	__in__OPT DLGPROC lpDialogFunc,
	__in	  LPARAM dwInitParam
);
  • DialogBoxParamA()API的第四个参数lpDialogFunc用来指出Dialog Box Procedure的地址,再40122C的地址处有条PUSH 4010F5,由此可见,函数第四个参数DlgProc的地址为4010F5,查看该部分代码,可以看到我们要修改的字符串。
    在这里插入图片描述
  • 该程序的各部分都做了加密处理,特别是要修改的字符串被加密了两次,并且再程序内部针对字符串区域计算校验和值,借以检验字符串是否发生更改,这些都大大增加了修改字符串的难度。

代码结构

在这里插入图片描述

  1. [A]、[B]、[C]区域为加密后的代码,[EP Code]、[Decoding Code]区域存在着用于解密的代码。
  2. [EP Code]只是用来调用[Decoding Code]的,实际解密处理是由[Decoding Code]完成的,按照[B]-[A]-[B]的顺序解码,运行解密后的[A]代码,在[A]代码中会求得[B]区的校验和,并据此判断[B]区代码是否发生过更改,然后对[C]区解码,最后跳转到OEP处。

内嵌补丁练习

  1. 首先向文件合适位置插入用于修改字符串的代码,然后[A]区域将JMP OEP命令修改为JMP补丁代码,若运行程序遇到[A]区中的JMP补丁代码语句(此时所有代码均处于解密状态且通过校验和验证),就在补丁代码中更改字符串,通过JMP命令跳转到OEP处,这样整个内嵌补丁过程就完成了。
  2. 补丁代码设置在何处:
  • 设置到文件的空白区域。
  • 拓展最后节区后设置。
  • 添加新节区后设置。
  1. 使用PEView查看示例文件的第一个节区头:
    在这里插入图片描述
  • 第一个节区(.text)的Size of RAW Data为400,Virtual Size为800,也就是说,第一个节区磁盘文件中的尺寸为400,但是仅有280大小被加载到内存,其余区域(680~800)处于未使用状态,该区域即使要查找的空白区域。
  • 节区的Virtual Size为280,这并不意味着实际节区的内存大小为280,而要以Section Alignment的倍数拓展,故实际大小为1000.
    在这里插入图片描述
  • 打开文件并查找空白区域,空白区域全部填充0,这种区域称为Null-padding区域,接下来在该区域设置补丁代码。
    在这里插入图片描述
  1. 制作补丁代码
  • 再次使用OllyDbg调试示例程序,运行到OEP处。
    在这里插入图片描述

  • 前面查找的空白区域在文件中的偏移为680~ 800,将其变换为进程VA后为401280~ 401400,接下来,在401280位置处创建补丁代码。
    在这里插入图片描述

  • 地址40128F与4012A0处的REP MOVSB命令用于修改下面的字符串:

(401123)"You must patch this NAG!!!" -> (4012A8) "ReverseCore"
(40110A)"You must unpack me!!!" -> (4012B4) "Unpacked"
  • 4012A2地址处的JMP命令跳转到OEP处,至此,补丁代码全部完成,每当补丁代码运行时,进程内存解密后的字符串就会被打补丁。
  • 保存修改的内容,Copy to exectable - ALL modification

执行补丁代码

  1. 内嵌补丁技术的最后一步是直接修改文件以运行前面创建的补丁带代码,可以发现地址401083处存在JMP OEP指令,只要把JMP OEP命令更改为JMP洞穴代码就可以了,即在转到OEP之前先把控制权限交给洞穴代码,使得字符串得以修改。
  2. 这里需要注意的时,该区域(401083)是原来的加密区域,地址401083属于[A]区域,是使用XOR 7加密的区域,文件中实际的加密形态:
    在这里插入图片描述
  3. 从文件偏移看,加密区域知道485,后面的00并不是加密区域。我们需要将EE 91 06改写为E9 F8 01执行完XOR 7的值,即加密后的值EE FF 06.
    在这里插入图片描述
    在这里插入图片描述
  4. 运行程序
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值