unidbg直接调用tiktok so生成签名

Tiktok版本: 33.2.5 (24年1月25日)

1、前言

    通过对Tiktok抓包发现TikTok的所有http请求的头部增加了参数签名(x-argus、x-goron、x-khronos、x-ladon):

2、获取关键函数

直接将apk文件用jadx工具反编译,搜索关键字x-argus等,未搜索到任何关键字:

使用frida hook java层 Header对象的构造方法,发现有监控到https请求头设置,但是始终没有发现签名字段

var Header = Java.use("X.2jn");
Header.$init.implementation = function(key, val) {
    console.log(key + " : " + val);
    this.$init(key, val);
}

接着尝试hook interceptor拦截器,打印出请求头部,结果输出的请求头部中还是没有签名字段

    //添加intercept
    var Request = Java.use("X.LGn");
    Request.LIZJ.implementation = function(intercept){
        var newObj = Java.cast(intercept, Java.use("java.lang.Object"));
        //console.log(newObj.getClass());
        var new_cls = newObj.getClass();
        var class_name = new_cls.getName();
 
        if(!mmp[class_name]) {
            mmp[class_name] = 1;
            var hook_class = Java.use(class_name);
            hook_class.intercept.implementation = function(tt){
                var res = this.intercept(tt);
/*              var rq = tt.request();
                console.log(rq.getUrl()); */
 
                var request = getFieldVal(res, "LIZ");
                //console.log(getFieldVal(request, "LIZ"));
                //console.log(getFieldVal(request, "LIZJ"));
                //console.log(getFieldVal(request, "LJI"));
                 
                var headers = getFieldVal(request, "LIZLLL");
                //console.log(headers);
                //console.log("----------------------------------------------------");
                return res;
            }
        }
 
        this.LIZJ(intercept);
    }

Java层找了一遍始终找不到签名关键字符串,那很大可能是在native层设置,在native层在 https请求发出时进行设置。TikTok使用 cronet网络库 。将libsscronet拖IDA反编译,搜索 x-gorfon 关键字,确实找到了:

结合 cronet源码,找到Native层设置请求Header函数:

void HttpRequestHeaders::SetHeader(const base::StringPiece& key,
                                   const base::StringPiece& value) {
  DCHECK(HttpUtil::IsValidHeaderName(key.as_string()));
  // TODO(ricea): Revert this. See crbug.com/627398.
  CHECK(HttpUtil::IsValidHeaderValue(value.as_string()));
  HeaderVector::iterator it = FindHeader(key);
  if (it != headers_.end())
    it->value.assign(value.data(), value.size());
  else
    headers_.push_back(HeaderKeyValuePair(key, value));
}

定位到该libsscronet中偏移为:0x2C44BC,HOOK该地址并打印出参数:

var SetHeaders = lib.base.add(0x2C44BC);
Interceptor.attach(SetHeaders, {
    onEnter: function (args) {
        var key = args[1].readPointer().readUtf8String();  //第一个属性是字符串的地址, 第二个属性长度
        var val = args[2].readPointer().readUtf8String();
        console.log(key + " : " + val);
    },
    onLeave: function (retval) {
         
    }
});

这次全部头部都可以看到了,完美!

然后打印设置参数签名字段时的调用栈:

var SetHeaders = lib.base.add(0x2C44BC);
Interceptor.attach(SetHeaders, {
    onEnter: function (args) {
 
        var key = args[1].readPointer().readUtf8String();  //第一个属性是字符串的地址, 第二个属性长度
        var val = args[2].readPointer().readUtf8String();
        if(key.indexOf("X-Gorgon") !== -1) {
            console.log(key + " : " + val);
            console.log('SetHeaders called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
            console.log("---------------------------end----------------------------------");
        }
    },
    onLeave: function (retval) {
         
    }
});

有两处调用,分别是 0x3a662c 和 0x2c4b78:

分别对两处进行反编译分析,0x3a662c 更像是tiktok定制的设置相关header处,关键代码反编译:

v128是从某个函数调用返回的结果,对该结果分割处理就得到了参数签名字段,因此用frida hook这里,然后输出调用时的两个参数查看

直接对0x3A658C地址进行HOOK,并打印出x0和x1寄存器的值,同时打印出X23寄存器的值:

var test = lib.base.add(0x3A658C);
Interceptor.attach(test, {
    onEnter: function (args) {
        console.log(args[0].readUtf8String());
    
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值