BEQ和BNE是一对条件相反的跳转,这之前计算出接下来指令的地址0x3430赋值给R4,loc_340C处的代码通过POP指令将R4的值给PC,看0x3430处的代码。
接下来的代码很多都是这种动态计算跳转地址的。0x3432处的指令从0x3438中取一个dword给R0,跳到0x3440然后再跳到0x407C。0x3444处开始不是指令而是一个跳转表,索引就是R0,值就是接下来指令地址的偏移,0x407C开始的代码就是取这个偏移。所以我们可以写一个脚本patch,计算出偏移,在0x3434处就直接跳过去。
同时还会有一些跳转到0x4094的指令,像上面这样0x3464跳到0x4094之后会返回到0x346C,从0x3462到0x346C这些指令我都直接patch成NOP了。
修复脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
|
修复结束之后跟踪指令,0x3434处的代码跳到了0x345A,0x345A处的代码主要逻辑是在0x34C6跳到0x34EC通过0x34EC动态计算地址跳到了0x3520,0x3524处的代码跳到了0x365C,0x366E处的代码跳到了0x35A8,0x35A8是JNI_OnLoad的主要逻辑。
如上图所示,0x35A8基本就干了两件事:FindClass(com/meituan/android/common/mtguard/NBridge)和RegisterNatives(com/meituan/android/common/mtguard/NBridge, main, 1)。
sub_3680里面调用sub_36B4通过异或解密了一些字符串,上图我已经把解密之后的结果patch进去了。
当然用unidbg是可以直接跑JNI_OnLoad的:
不过这个系列文章主要是想讨论一下so混淆和反混淆,有精力的话还可以对这个so进行完整分析,混淆应该没有啥新的了。