样本apk下载地址:
https://pan.baidu.com/s/1QcMnrWBooGMJDHKem6kzSA 提取码: fkfi
界面如下,就是判断name和code是否输入正确。
java层的代码就不分析了,直接看so,其native层的校验函数如下:
双击进去看伪C代码,如下:
再双击跟进这个子函数,看看处理逻辑:
这里有两个子函数,现在关注后面的一个吧,
这里的v8 是返回值,如果不等于20,则返回 0,也就是校验失败。
跟进这个子函数,其代码特征比较像 base64的解码函数,
而且,我们查看 a456789 这个数组时,可以发现 base64的码表:
因此我们可以大胆的猜想,这就是 一个 base64的解码函数,其解码的字符串放进了 v23数组里面,函数的返回值猜想为 解码后的字符串长度。
那我们用 frida Hook来进行我们的猜想吧。
先记住这个子函数的相对地址 (0x1498):
frida Hook未导出函数,我已知的方法有两种:
一:通过 获取 so的基址 + 相对地址 + 1 就是函数的绝对地址了,至于为什么 +1 ,赵四大神的这篇文章说的很清楚,可以参考:
http://www.520monkey.com/archives/1256
很快,就可以写出如下的Hook代码:
Java.perform(function () {
send("Running Script");
var base_addr = Module.findBaseAddress("libCheckRegister.so");//获取 so的基址
var nativePointer = base_addr.add(0x1498+1) //加上相对地址,得到绝对地址,记住,这里一定要加1
var result_pointer;
Interceptor.attach(nativePointer,{
onEnter:
function(args){
result_pointer = args[0] //将数组进行保存,供下面的函数使用
console.log(Memory.readCString(args[1]));//打印第二个参数值
},
onLeave:
function(retval){
var resultPointer = new NativePointer(result_pointer);
var resultstr = Memory.readUtf8String(resultPointer);//读取数组里面的值
send(retval.toInt32()); //打印结果
send("result pointer:" + resultPointer +", result:" + resultstr);//打印解码后的字符串
}
});
send("Hooks installed.");
});
我们还需构造一个 20位长度的字符串,对其进行base64的编码,我这里选择 "12345678901234567890",其编码后的字符串是:
MTIzNDU2Nzg5MDEyMzQ1Njc4OTA=
app界面输入如下:
上面代码的Hook 结果:
Hook 出来的结果证实了之前的猜想。
二:通过获取 已导出的JNI 函数地址来作为跳板,计算so的基址,然后再加上未导出函数的相对地址,即可以得到函数的绝对地址,注意,这种方式获取 的地址不需要加1,因此,将上面的代码稍微改一下,就可以写出如下的Hook代码:
Java.perform(function () {
send("Running Script");
var base_addr = Module.findExportByName("libCheckRegister.so","Java_com_tencent_tencent2016a_MainActivity_NativeCheckRegister").sub(0x1758);//获取so的基址
var nativePointer = base_addr.add(0x1498) //不需要 +1
var result_pointer;
Interceptor.attach(nativePointer,{
onEnter:
function(args){
result_pointer = args[0]
console.log(Memory.readCString(args[1]));
},
onLeave:
function(retval){
var resultPointer = new NativePointer(result_pointer);
var resultstr = Memory.readUtf8String(resultPointer);
send(retval.toInt32());
send("result pointer:" + resultPointer +", result:" + resultstr);
}
});
send("Hooks installed.");
});
其结果显示也是一样的: