玩转补丁移植( 二 )


如果这个补丁的移植过程没有看明白,建议先不要继续下面的内容 。
二、待机画面取消软键显示

1.补丁原型:
;S65
0854992: 05D1 0028
08548B3: D0 E0
0877A4C: 06D1 0028

2.基本思路:
相当多的补丁不能用上面那种简单的、搜索固定字串的方式来移植 。由于地址、数据和程序位置的不同,特征字串里面可能会有一些不确定的变数,需要进行模糊搜索,具体的方法就是用?号来代替那些不确定的数据 。
在“0854992: 05D1 0028”中,05D1是一个条件跳转指令(BNE loc_A08549A0)的机器码,用来判断是否在屏幕上显示软键提示,我们不想要这个判断,需要取消显示,让程序继续执行下去,所以要屏蔽掉这条指令,方法是用一个无实际效果的多余指令来代替它(相当于NOP),作者选用了“ CMP R0, #0”(机器码就是0028) 。
我们知道05D1在S65中的位置是A0854992,现在,我们用程序分析的方法来确定这条程序在C6C中的位置,然后屏蔽它 。
3.补丁移植:

3.1
用IDA反汇编S65 Fullflash从A0854992开始的代码:
ROM:A0854992*BNEloc_A08549A0
ROM:A0854994MOVR0, #0x1A
ROM:A0854996STRR0, [R5,#0x24]
ROM:A0854998STRR0, [R5,#0x20]
ROM:A085499ABloc_A08549A0
ROM:A085499CMOVR3, #0
ROM:A085499ESTRR3, [R5,#0x20]
ROM:A08549A0* loc_A08549A0
ROM:A08549A0LDRR0, =0xA847F4B4
ROM:A08549A2LDRR3, [R5,#0x1C]
由于BNE loc_A08549A0只是一个范围很小的、跨越了几条指令的短跳,不同地址,但是具有相同方向和距离的相对地址的短跳指令具有相同的机器码 。尽管在它的指令机器码中包含了相对的地址偏移量,我们还是先假定在C6C中具有相同的跳转,这样,可以先直接搜索它的机器码而不是用?号来代替搜索 。接下来的几条指令都是一些常数赋值处理,在C6C中应该具有相同的指令 。基于这样的认识,我们假定在C6C里面具有完全相同的代码段,先使用固定的特征字串进行定位 。

这一次,我们用Smelter来搜索 。

用Smelter打开C6C的Fullflash,按Ctrl B,搜索前两条指令的机器码05D11A20,得到两个地址,增加搜索长度05D11A206862,得到唯一的地址a084bbe6,也许是巧合,但是我们先假定这次也是幸运的,或者可以再用一个IDA看一下C6C的a084bbe6开始的程序结构与S65是否类似,以此确定地址的准确性 。
这样就得到了第一行移植后的补丁数据:
084bbe6:05D1 0028

3.2

用IDA反汇编补丁第二行A08548B3处的程序:
ROM:A08548B3*DCB 0xD0 ; 反汇编不出来
ROM:A08548B4BLsub_A083FA8A
ROM:A08548B8CMPR0, #0
ROM:A08548BABEQloc_A08548E4
ROM:A08548BCMOVR0, #0x1A
ROM:A08548BESTRR0, [R5,#0x1C]
ROM:A08548C0Bloc_A08548F4
发现这个地址开始的数据D0没有反汇编出来,被当作了一个字节的数据,难以确定搜索特征 。我们继续从上一个地址位置重新反汇编,得到新的结果:
ROM:A08548B0CMPR0, #0
ROM:A08548B2*BEQloc_A08548BC
ROM:A08548B4BLsub_A083FA8A
ROM:A08548B8CMPR0, #0
ROM:A08548BABEQloc_A08548E4
ROM:A08548BC loc_A08548BC
ROM:A08548BCMOVR0, #0x1A
ROM:A08548BESTRR0, [R5,#0x1C]
ROM:A08548C0Bloc_A08548F4

这一下明白了,原来A08548B2处的数据03是指令BEQloc_A08548BC的固定部分,在新的补丁中没有变化,所以补丁中没有写出这个字节来 。
用UltraEdit将A08548B3处的D0改为E0,再用IDA反汇编:

ROM:A08548B2*Bloc_A08548BC
ROM:A08548B4BLsub_A083FA8A
ROM:A08548B8CMPR0, #0
ROM:A08548BABEQloc_A08548E4
ROM:A08548BC loc_A08548BC
ROM:A08548BCMOVR0, #0x1A
ROM:A08548BESTRR0, [R5,#0x1C]
ROM:A08548C0Bloc_A08548F4
补丁里将条件跳转改成了无条件跳转 。其中BEQloc_A08548BC类似实例一中的情况,所以,我们也假设C6C中有相同的机器码 。但是,接下来的BL sub_A083FA8A是一个4字节的绝对地址跳转,这在不同的机型中的机器码很可能是不一样的,不能做为特征值搜索,使用?号代替(或者代替其中的变数部分),为了缩小搜索范围,把后面的两条比较“老实”的指令的机器码也加入搜索 。这样,用Smelter在C6C的Fullflash里面搜索“03D0????????002813D0” 得到唯一的地址A084BB06,需要修改的地址是A084BB07,于是,我们得到了第二行移植后的补丁数据:

推荐阅读