tgcwc 发表于 2023-2-5 17:14:47

保存当前上下文并在返回时修改的疑惑,记一次大白补丁制作过程

本帖最后由 tgcwc 于 2023-2-5 17:33 编辑

关键调用有两处,下面分别介绍:第一处:此处相对简单,0x711DA4(虚拟地址VA:0x311DA4)调用返回时EAX>=0,则后面的跳转就实现。同时【ECX】地址处需要返回hex值“9951 B8 25”。见下图:
因本次破解补丁地址不超过4个,补丁地址采用硬件断点,第一条采用“函数返回时修改上下文”来修改eax的值,具体设置见下图:
第二条采用“保存当前上下文并在返回时修改”来修改ecx指向的内存的值,具体设置见下图:

大白日志记录显示如下:
说明此地址设置的两条补丁成功。需要特别说明的是,eax的修改是在函数返回时,ecx指向的内存修改是在运行到0x711DA4地址时先保存ecx的值,函数返回时才修改保存的ecx的值指向的内存数据。
第二处:此处情况稍微复杂了一些,【ECX】对应的值会因为EDX的值不同而不同,这里需要用到条件断点,0x711E5C(虚拟地址VA:0x311E5C)调用返回时EAX>=1,则后面的跳转就实现。同时当edx=0时【ECX】地址处需要返回hex值“3330 37 36 38 34 34 35 37 35 00 00”。当edx=1时【ECX】地址处需要返回hex值“BABC D6 ********(此处省略几百字节) 00 00 00 FF FF FF FF FF FF FFFF 00 00 00 00”。汇编代码见下图:

补丁设置见下图:
条件断点:edx=0条件断点edx=1:


经过上述设置,在函数返回时eax=1,当edx=0时,ecx指向的内存设置为hex1,当edx=1时,ecx指向的内存设置hex2。我们的预想是运行后应该是这样一个结果,但是实际运行的log记录如下:
eax和ecx的值没有按照我们预想的来进行处理,经过反复尝试,卡在此处很长一段时间始终没有解决。
    经过求助众位表哥和Nisy老师,最后Nisy模拟了一段代码并制作的对应的补丁,其采用的是在同一个地址设置三条补丁,其中两条是带条件断点的,经测试可以正确补上,代码如下:
补丁运行结果如下:



需要说明的是,此补丁采用的是如下方式:
此种方式是直接在运行到断点地址时进行打补丁,三条补丁全部成功。
受此方式启发,我对第二处补丁进行了调整,调整的结果为:不采用修改返回值的方式,直接在函数尾部(VA:0x311F2E处)设置断点,修改eax的值和ecx指向的值(此时ECX的值与运行到0x711E5C地址处的值一致),最终补丁成功。大白记录如下:

本例正好是ecx的值和edx的值在函数内始终没有改变,如果遇到ecx和edx的值被修改的情况,将不适用。
通过上述过程的对比分析,最终怀疑是大白在“保存上下文并在返回时修改”情况下,处理条件断点时出现了问题,造成运行结果与预期不一致。

tgcwc 发表于 2023-2-5 18:22:54

本帖最后由 tgcwc 于 2023-2-5 20:58 编辑

最后用替换补丁来逐条代替出问题的异常中断补丁来测试,首先替换掉修改eax的这条函数返回时修改上下文补丁,保留两条保存上下文返回时修改的条件断点补丁,依然出错;然后是保留一条返回时修改上下文和一条保存上下文返回时修改的条件断点补丁,仍然出错;最后是只保留一条保存上下文返回时修改的条件断点,补丁成功。推测问题是出在保存上下文返回时修改的条件断点与返回是修改上下文,或者是与保存上下文返回时修改的条件断点组合时没有正确处理。

经测试同一地址设置断点的几种情况:

两条保存上下文返回时修改(加条件断点):无法实现
一条函数返回时修改上下文和一条保存上下文返回时修改(加条件断点):无法实现
一条函数返回时修改上下文和一条保存上下文返回时修改(无条件断点)可以实现

一条保存上下文返回时修改(加条件断点):可以实现

断点地址直接修改一条无条件断点+两条条件断点补丁:可以实现

飞天梦 发表于 2023-2-5 21:56:02

谢谢分享

zhaohj 发表于 2023-2-6 10:17:05

第二条,函数返回时修改上下文为何不统一

tgcwc 发表于 2023-2-6 19:37:08

zhaohj 发表于 2023-2-6 10:17
第二条,函数返回时修改上下文为何不统一

函数返回时修改上下文 和 保存上下文返回时修改是有差别的。

共同点是修改时机都是函数返回时;
不同点:
函数返回时修改上下文是函数返回时修改返回地址处所对应的寄存器环境;保存上下文返回时修改是先把运行到断点地址时的寄存器环境保存下来,待函数返回时再利用保存的寄存器值来修改内存,这种方式不支持直接修改寄存器值,只能修改内存值。


第一处断点地址,eax的值是要等函数返回才修改,而ecx指向的内存地址的内容是函数头部先保存ecx,然后等函数返回时利用保存的值来修改指向的内存。


第二处断点地址情况比第一处稍复杂,ecx指向的内存地址,需要根据edx的值来设置条件断点。

pizazzboy 发表于 2023-2-7 08:48:57

感谢表哥的精彩分享。

乐活 发表于 2023-2-8 16:06:08

过来学习,多谢

xiaomils 发表于 2023-2-9 11:55:45

进来学习的

lhtzty 发表于 2023-2-15 06:22:07

学习了,感谢!!
页: [1]
查看完整版本: 保存当前上下文并在返回时修改的疑惑,记一次大白补丁制作过程