使用 Frida 来 Hook Java 类中的构造函数(构造函数带重载),获取解密后的js脚本
一个APP使用了Auto.js 的加密脚本。我们的任务是将其加密脚本进行解密并dump出来。在 https://www.52pojie.cn/thread-1112407-1-1.html 一文中,介绍了 Auto.js 脚本解密的过程,并使用了 Xposed 对解密后的脚本进行了提取。但当前所使用的手机并没有 Xposed , 只好通过 Frida 来自力更生进行提取。
话不多说,通过 jadx 找到该 APK 涉及脚本加解密的地址:
如图所示,根据上面链接的内容来看,我们要对 com.stardust.autojs.script.StringScriptSource 类的 StringScriptSource(String str, String str2) 构造函数进行 hook 。
一般来讲,Frida Hook Java类中的方法,其注入的 JS 脚本是这样的:
//Java.Perform 表示 Frida 将会从这里开始执行JavaScript脚本。
Java.perform(function () {
//定义一个变量ClassName,Java.use 后面指定想要Hook的类SecondActivity
var ClassName=Java.use('com.example.SecondActivity');
//hook该类下的myFunc1方法,implementation 表示重新实现它
MainActivity.myFunc1.implementation = function () {
send("Hook Start...");
//调用SecondActivity类中的 calc()方法,获取返回值
var returnValue = this.calc();
}
});
然而由图可知,我要hook的是构造函数,而且有两个 str 参数,还有重载,所以并不能按上面的这么写。在参考了关于Frida Hook Java 的资料 https://www.jianshu.com/p/f98aca8f3c05 和 https://www.freebuf.com/articles/system/190565.html 后,解决了 “ 带两个参数,重载,string参数 ” 这三个问题。 代码如下:
//把 data 的内容 写入到 full_path 这一文件中 function write_file(full_path, data) { var f = new File(full_path, 'w') f.write(data) f.close() } Java.perform(function () { var ClassName = Java.use('com.stardust.autojs.script.StringScriptSource'); console.log("Find ClassName Successfully!");//定位类成功! ClassName.$init.overload("java.lang.String","java.lang.String").implementation=function(param_1,param_2){ send("Hook Start..."); //send(param_1);//第一个参数是待解密的文件名,字符串“main.js” //send(param_2);//第二个参数是解密后的代码(一大堆字符代码) write_file("/storage/emulated/0/main_dump.js", param_2) var ret = this.$init(param_1,param_2); return ret; } });
代码完成了,我们将其注入到目标app中吧。需要注意的是,代码仅在程序刚启动的时候注入,所以在程序启动后注入是没有用处的。要在程序启动之前就安排好,
采取以下方式:
frida -U -l D:/myhook.js -f com.example.script --no-pause
(其中-f 即spwan,在程序最先启动的时候注入。--no-pause是不暂停。具体解释见本博:https://www.cnblogs.com/codex/p/12728908.html)
然后就可以在手机内部存储的根目录找到dump出来的文件了。