使用unidbg练习某品会的api_sign
# 查找签名位置
直接搜索可以定位到api_sign出现的位置,然后代码中,通过反射来调用native方法,最终在这里
# 抓包查看参数,主动调用,查看是否有坑
直接frida主动调用,没什么问题,参数全部出来
# java层主动调用
因为参数太多,主动调用试试参数放少一点,可以正常返回
看起来没问题,(也可以frida主动调用so层,成功才行,这里偷懒了) 上unidbg试试
# 上unidbg
直接复制以前代码,框架搭建出来,开始跑
找到so中,静态注册的方法
这里可以得到so中偏移地址为697B4
正常跑起来,然后开始补方法
这个方法,在AbstractJni中,有实现好的,复制粘贴过来就行
又出现的错误,在AbstractJni中也有实现,同理补好,现在代码是
继续跑,出现新的错误,
java.lang.UnsupportedOperationException: java/util/Iterator->next()Ljava/lang/Object;
这个方法没有现有的,但是Java又不是很熟练,如果安装之前补的方法来应该是这样
结果会出现错误,打开日志和输出可以发现到
对应so代码是
应该是对iterator.next()进行getKey方法,出错,
而上一次补的返回值 return vm.resolveClass("java/util/Iterator").newObject(iterator.next());,却是一个Iterator对象
又翻了一遍**java map 遍历方法**
然后应该返回一个Entry对象,
所以现在应该是
正确了,现在是补getKey方法和getValue方法
补好后,结果直接就出来了
对比值,也完全正确,。ok
# 其他情况
这里如果不加载apk, 会出现这个错误
java.lang.UnsupportedOperationException: android/content/Context->getPackageName()Ljava/lang/String;
去代码中查看,可以发现,先进行判断,通过后再走下面的签名方法
这个方法点进去,全是获取包名信息的内容,应该就是apk的签名校验
尝试把这个if语句patch掉
查看到对应字节码,和地址 然后写代码试试
```java
public void patchVerify1(){
Pointer pointer = UnidbgPointer.pointer(emulator, module.base + 0x697C4);
assert pointer != null;
byte[] code = pointer.getByteArray(0, 4);
if (!Arrays.equals(code, new byte[]{ (byte)0xE8, (byte) 0xF7, (byte) 0x64, (byte) 0xEA })) { // BLX
throw new IllegalStateException(Inspector.inspectString(code, "patch32 code=" + Arrays.toString(code)));
}
try (Keystone keystone = new Keystone(KeystoneArchitecture.Arm, KeystoneMode.ArmThumb)) {
KeystoneEncoded encoded = keystone.assemble("mov r0, 1");
byte[] patch = encoded.getMachineCode();
if (patch.length != code.length) {
throw new IllegalStateException(Inspector.inspectString(patch, "patch32 length=" + patch.length));
}
pointer.write(0, patch, 0, patch.length);
System.out.println("patch ok");
}
};
```
然后也可以绕过签名