[原创]frida小试
抓包
首先抓包看下请求参数,这个app很简单,没有做什么防抓包的策略,可以看到请求中有个hnairSign,这个参数就是目标。
POST /mapp/webservice/v5/common/flight/list?hnairSign=234B7E54A9E83A19040FC3E66720B81AC7C9441A HTTP/1.1
User-Agent: okhttp/3.9.1
Content-Type: application/json; charset=utf-8
Content-Length: 595
Host: app.hnair.com
Connection: Keep-Alive
Accept-Encoding: gzip
Pragma: no-cache
Cache-Control: no-cache
{"common":{"abuild":"55572","akey":"184C5F04D8BE43DCBD2EE3ABC928F616","aname":"com.rytong.hnair","atarget":"standard","aver":"7.5.0","did":"8XV5T15A23004277","gtcid":"151631a36b8e19d7235c3bea66bb36d7","mchannel":"xiaomi","schannel":"AD","slang":"zh-CN","sname":"google\/angler\/angler:6.0.1\/MTC20L\/3230295:user\/release-keys","stime":"1568599814440","sver":"6.0.1","szone":"+0800","riskToken":"5d7eee48p3BusPiNPOzOBjkRrfxxe6pncDiJK1y3","captchaToken":""},"data":{"adultCount":1,"cabins":["*"],"childCount":0,"depDate":"2019-09-17","dstCode":"CAN","infantCount":0,"orgCode":"SZX","tripType":1}}
Java层
java层的调用很简单,直接搜索hnairSign就能很快定位到关键函数,最后会调用getHNASignature这个方法,是个native方法,在libsignature.so中
public class HNASignature {
private static final String TAG = "HNASignature";
static {
try {
System.loadLibrary("signature");
} catch (Exception e) {
Log.e(TAG, "HNASignature load signature error ", e);
}
}
public static native String getHNASignature(String paramString1, String paramString2, String paramString3, String paramString4, String paramString5);
}
So层
静态分析
ida打开这个so,先看下导出函数有哪些,

Java_com_rytong_hnair_HNASignature_getHNASignature对应的就是java层的getHNASignature(),先静态分析跟一下,点进去这个函数,从返回结果往上看,大概猜到算法在 HNASignature::HNASignature这里面。

点进去,继续往下跟,很明显看到HNASignature::sign

继续点进去,很明显看到用到的算法了,猜测就是hmacSha


动态分析
下面就用frida来hook做动态分析,验证上面分析。
首先写一个主动调用的函数,方便我们自定义简单的参数,分析起来方便些
function call_getSignFromJni() { //调用最外层函数 java层调用jni
Java.perform(function () {
var HNASignature = Java.use("com.rytong.hnair.HNASignature");
var result = HNASignature.getHNASignature("{}", "{}", '{"abuild":"55572"}', "ad", "cccc");
console.log("BitmapkitUtils.getSignFromJni:", result);
});
}
再写个hook函数,这里对HNASignature::sign进行hook,先找到它的导出函数

下面是hook代码,
function hook_sign() {
var a = Module.findExportByName("libsignature.so", "_ZN12HNASignature4signEPhS0_");
console.log('hook_sign: ',a);
Interceptor.attach(a, {
onEnter: function(args) {
this.arg0 = args[0]
console.log("hook_sign arg2==: "+ptr(args[2]).readCString()+" arg3==: "+ptr(args[3]).readCString());
},
onLeave: function (retval) {
console.log('hook_sign onLeave: ', 'retval: ', Memory.readCString(this.arg0.readPointer()))
}
});
}
function hook_hmacSha() {
var base_libsinature = Module.findBaseAddress("libsignature.so");
console.log('base1: ',base_libsinature);
var a = Module.findExportByName("libsignature.so", "_ZN12HNASignature7hmacShaEPhS0_");
console.log('hook_hmacSha: ',a);
Interceptor.attach(a, {
onEnter: function(args) {
console.log("hook_hmacSha param: "+ptr(args[2]).readCString());
console.log("hook_hmacSha key: "+ptr(args[3]).readCString());
},
onLeave: function (retval) {
// console.log('hook_hmacSha onLeave: ', 'retval: ', ptr(retval).readCString())
}
});
console.log("hook_hmacSha...");
}
启动frida执行上面的脚本,

可以看到,HNASignature::sign就是算法的地方,也能看到执行算法返回后后面的拼接参数就是我们传进去的参数。
最后就是确定算法是不是标准的hmac_sha了,随便找个在线网站,发现计算的结果和我们动态hook的是一致的。

