查壳

  • 无壳

查看构造

  • 通过 uiautomatorviewer 发现存在控件 不是H5的APP

抓包

  • 使用SocksDroid + Charles进行抓包

1.png

  • 可以看到请求参数被加密
{
    "Encrypt":"NIszaqFPos1vd0pFqKlB42Np5itPxaNH\/\/FDsRnlBfgL4lcVxjXii\/UNcdXYMk0E528uVVD\/0oha\nmd+6EbReUTXq4wQwrAlA4GIK0VIz\/nAc0+boMzy4OAzJS0+7MjEgpOkVXBHYaV\/l2OSPXGJjwPFL\nena6H7f4aNrco1hGK6DRVh6AqctVUMOGeU4yMBshu+5W7xg9gbebaTkpUyPrPImVtmSiYmhk\n"
}

反编译查看源码

  • 通过jadx搜索"Encrypt"发现有二十多出,通过观察类名发现最像的有两个,且都为put,所以本次直接hook put函数及查看调用栈来确定关键代码位置

    2.png

HOOK调试

  1. hook put函数及打印调用栈确定关键代码位置

    // 打印调用栈
    function printStacks() {
        console.log(
            Java.use("android.util.Log")
            .getStackTraceString(
                Java.use("java.lang.Throwable").$new()
            )
        );
    }
    
    Java.perform(function () {
        var hashMap = Java.use("java.util.HashMap");
        hashMap.put.implementation = function (key, value) {
            if (key=="Encrypt") {
                console.log("hashMap.put: ", key, value);
                printStacks();
            }
            return this.put(key, value);
        };
    });
  2. 查看hook结果确定就是这里

    3.png

  3. 进入该方法时,发现有三个重载,不确定是哪一个?hook它

    4.png

  4. hook方法所有重载

    var targetClass = "com.dodonew.online.http.JsonRequest";
    var targetMethod = "addRequestMap";
    var targetClassMethod = targetClass + "." + targetMethod;
    //目标类
    var hook = Java.use(targetClass);
    //重载次数
    var overloadCount = hook[targetMethod].overloads.length;
    //打印日志:追踪的方法有多少个重载
    console.log("Tracing " + targetClassMethod + " [" + overloadCount + " overload(s)]");
    //每个重载都进入一次
    for (var i = 0; i < overloadCount; i++) {
    //hook每一个重载
        hook[targetMethod].overloads[i].implementation = function() {
            console.warn("\n*** entered " + targetClassMethod);
            //这里可以打印每个重载的调用栈,对调试有巨大的帮助,当然,信息也很多,尽量不要打印,除非分析陷入僵局
            // 打印参数
            if (arguments.length) console.log();
            for (var j = 0; j < arguments.length; j++) {
                console.log("arg[" + j + "]: " + arguments[j]);
            }
            //打印返回值
            var retval = this[targetMethod].apply(this, arguments); // rare crash (Frida bug?)
            console.log("\nretval: " + retval);
            console.warn("\n*** exiting " + targetClassMethod);
            return retval;
        }
    }
  5. 通过查看hook结果确定重载方法的参数列表为:[Map, int]

    5.png

  6. 进入加密方法addRequestMap

    6.png

  7. 分析调用关系

    1. 加密结果encrypt通过调用encodeDesMap方法而来,推测使用des加密
    2. encodeDesMap方法参数有三个,code,desKey为固定字符串,desIV为固定字符串
    3. code参数通过调用paraMap方法而来
    4. paraMap方法参数有三个,addMap,BASE_APPEND为固定字符串,"sign"为固定字符串
    5. addMAP是传进来的,hook看看,同时addMap进方法后新增了一个键值对timeStamp
  8. hook方法addRequestMap,查看参数

    var JsonRequest = Java.use('com.dodonew.online.http.JsonRequest');
    JsonRequest.addRequestMap.overload('java.util.Map', 'int').implementation = function (map, int) {
        // ---------------
        var result = "";
        var keyset = map.keySet();
        var it = keyset.iterator();
        while (it.hasNext()) {
            var keystr = it.next().toString();
            var valuestr = map.get(keystr).toString();
            result += valuestr;
            console.log("keystr: " + keystr + ", valuestr: " + valuestr)
        }
        console.log('int int: ', int);
        var retval = this.addRequestMap(map, int);
        console.log('retval: ', retval);
        return retval;
    }
  9. 通过hook可以看到addRequestMap方法的参数

    7.jpg

代码还原

8.png

代码位置:https://github.com/jiangfubang/android_hook/tree/master/src/main/java/dodonew

最后修改:2022 年 04 月 18 日
如果觉得我的文章对你有用,请随意赞赏