今天要分析的app 叫 dGFwdGFwIDIuMjA=
(base64 解码),来一起学习下。
找个视频接口,上来先抓个包,没错今天就是要分析下这个sig
参数。
这个app 在高版本上有加固壳
,并且还有frida检测
(ps:遇到困难不会放弃,以后慢慢研究),这里只是研究sig参数,所以采用低版本了。
把app 拖到jadx 打开,然后搜索"sign"
关键词,找到下面👇🏻
public static HashMap<String, String> a(HashMap<String, String> hashMap) {
if (hashMap != null && hashMap.size() > 0) {
hashMap.put("sign", d(hashMap));
}
return hashMap;
}
sign 参数是d(hashMap)
方法计算出来的,跟进去。
往底部看,sign 又是NativeHttp.getSign(AppGlobal.a, sb.toString().getBytes());
计算出来的,继续跟进去。
看关键词native
,好吧 加密在so层,用到的so文件叫tap-patch
。
拿出我们的ida pro
把样本libtap-patch.so 拖进去看看。
我们先ctrl+F 搜索Java层静态注册的方法名,结果没有找到,所以它肯定是个动态注册的,所以在导出表 直接看 JNI_Onload
。
然后按F5
,查看伪代码。
这里有很多函数,一个个的点进去看看,先看这个off_6004
,跟进去。
然后来到这里看法了熟悉的名字"getSign"
,这不就是在Java层调用的函数名称吗
再看(Landroid/content/Context;[B)Ljava/lang.....
这一串 不就是 函数smail 语法下的入参参数吗
往下面有个 sub_18FC+1
跟进去看看sub_18FC
方法。
看到汇编代码,再按F5。
点击去一个个看,这里有个sub_16E4
方法,继续跟进去。
可以看到,这里好像是定义了一个盐值。
然后经过sub_24D0
方法,点进去。
熟悉的四个常量,看过md5源码的同学肯定知道 这是做md5加密的初始化操作。
再看下sub_2504
方法。
加密的逻辑大概就是把请求参数进行字典key排序,再拼接 然后尾部加个盐值。
静态分析差不多到此,接下来上frida 去动态分析下。
先frida 调试下Java层:
Java.perform(function (){
var NativeHttp = Java.use("xmx.tap.http.NativeHttp");
NativeHttp["getSign"].implementation = function (context, bArr) {
console.log("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
console.log('getSign is called');
console.log('context: ' + context);
console.log('bArr: ' + bArr);
var java_string = Java.use("java.lang.String");
console.log('bArr: ' + java_string.$new(bArr));
var ret = this.getSign(context, bArr);
console.log('getSign ret value is ' + ret);
console.log("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
return ret;
};
}
)
看看效果:
很明显传递进来的请求url 和 post body 的参数进行拼接,最后返回的就是 32位的MD5加密值。
但是直接把这段字符串 进行md5加密后,却和实际的值不一样,说明so层里面还有操作。
接下来继续frida 调试 sub_16E4
和sub_2504
方法
我们把hexdump转换下
然后我们手动把两段字符串拼接,再用MD5测试下,不出所料,果然和hook 出来的结果对的上去。
我们的猜想得到了验证。
最后一步当然是 Python 还原了(源代码就不贴了)
sign计算正确,搜索接口的数据也拿到手了,告辞,早点睡觉。