利用frida抓取头x系西红柿app的小说
apk爬虫的好处还是很多的,先要比web端稳定,版本升级一般不会影响到旧版本,缺点是要比web端要难些,当然在掌握逆向后,也就感觉没有区别了。
爬虫第一步分析他的包,这里用的是charles,如何使用就不细说了。在分析包的过程中,发现了一个熟悉的参数

这不是抖音的x-gorgon加密算法吗?让每个爬虫er都头皮发麻的算法。
下一步反编译apk,用的工具是jadx,我们可以找到生成加密的方法是在native方法中,也就是说无法看到这个方法到底是怎么样加密的。

现在头条系已经可以监控到xposed框架,在android上写xposed脚本服务器做转发已经行不通了,只能另找方法。
frida是一款神器,它可以帮助逆向人员对指定的进程的so模块进行分析。它主要提供了功能简单的python接口和功能丰富的js接口,使得hook函数和修改so编程化,值得一提的是接口中包含了主控端与目标进程的交互接口,由此我们可以即时获取信息并随时进行修改。使用frida可以获取进程的信息(模块列表,线程列表,库导出函数),可以拦截指定函数和调用指定函数,可以注入代码,总而言之,使用frida我们可以对进程模块进行手术刀式剖析。
其实就是入侵到了二进制文件,达到控制某个方法作用。
device = frida.get_remote_device()
# 应用包名
app_package_name = "包名"
try:
# pid = device.spawn([app_package_name])
# device.resume(pid)
# time.sleep(1) # 2
session = device.attach(app_package_name)
print("[*] start hook")
print(session)
# 加载脚本
with open("hook的js文件", "r", encoding="utf-8") as file:
js_code = file.read()
script = session.create_script(js_code)
script.on('message', on_message)
script.load()
return script
except frida.NotSupportedError:
print("请检查包名的有效性.")
frida的使用就是这样,get_remote_device是我需要远程连接服务器,frida也提供了get_usb_device方法。主要难度是在js hook部分
frida_rpc的使用:
通过hook 可以看到他前面的native方法所需要的参数,无非是一些请求头里的参数和时间戳,
rpc.exports = {
"b": function (str1,json_str){
var ret = {};
Java.perform(function () {
var tt1 = Java.use("com.ss.sys.ces.gg.tt$1").$new();
var url = str1;
var ArrayList = Java.use("java.util.ArrayList").$new();
var ObjectJava = Java.use("java.lang.Object");
var map = Java.use("java.util.HashMap").$new();
var obj = JSON.parse(json_str);
for (var key in obj){
var m1 = ArrayList;
var list_tmp = obj[key];
m1.add(list_tmp);
map.put(key, Java.cast(Java.cast(m1, ArrayList), ObjectJava));
}
var result = tt1.a(url, map);
ret["X-Gorgon"]=result.get("X-Gorgon").toString();
ret["X-Khronos"]=result.get("X-Khronos").toString();
});
return ret;
}
};
这段js代码就是用python爬虫程序生产参数,通过frida hook 来拿到加密参数,再返回给爬虫使用。
爬虫里需要做的事,是在请求前,先拿到加密参数
map_data = {
"x-ss-tc": "0",
"cookie": headers.get('cookie'),
"accept-encoding": "gzip, deflate",
"user-agent": headers.get('user-agent'),
"x-ss-req-ticket": f"{time_stamp}"
}
xgo = script.exports.b(fanqie_url, json.dumps(map_data))
headers['x-gorgon'] = xgo.get('X-Gorgon')
headers['x-khronos'] = xgo.get('X-Khronos')
# js的对象即为json
到这一步,就算破解算法成功,又可以开开心心的看小说啦!下次有时间再细说下frida这个工具,这个工具不止在安卓,在各个端都可以使用,非常的强大。不友好的是官方文档写的真的太晦涩,太烂了。