工具
JsRPC
下载
mitmproxy
下载
过程
在本机运行 JsRpc。浏览器会把页面中的加解密函数注册到本地 WebSocket,后续由本地 HTTP 接口转发调用。

复制 JsEnv_Dev.js 的内容在浏览器控制台执行

连接通信
var demo = new Hlclient("ws://127.0.0.1:12080/ws?group=test");

查找加密函数(通常搜索关键字:crypt、aes、cbc、sm……)

打上断点,点击一下其他功能点,确认 p() 为解密函数

控制台输入 window.decrypt_func=p ,将解密函数注册为全局函数
测试全局函数 decrypt_func 是否可用

去掉断点,将 decrypt_func 注册到JsRpc远程调用
demo.regAction("decrypt", function (resolve, param) {
const decrypted = decrypt_func(param);
resolve(decrypted);
});

访问 http://127.0.0.1:12080/go?group=test&action=decrypt¶m=encrypt_data 可以正常获取到结果

继续找加密函数

可疑的通通打上断点,点击其他功能点触发请求,发现是 g() 处理加密

同样注册为全局函数 encrypt_func 并测试是否可用

去掉断点,将 encrypt_func 注册到JsRpc远程调用
demo.regAction("encrypt", function (resolve, param) {
const encrypted = encrypt_func(param);
resolve(encrypted);
});
问题
中文传输乱码
不要手工把明文拼进查询字符串。使用 HTTP 客户端的参数编码功能,它会正确处理中文、+、& 和 = 等字符:
import requests
response = requests.get(
"http://127.0.0.1:12080/go",
params={
"group": "test",
"action": "encrypt",
"param": "中文明文&测试",
},
timeout=10,
)
response.raise_for_status()
print(response.text)
在 mitmproxy 插件中同样应修改结构化的 query 参数,而不是对整段 URL 做字符串替换。
JavaScript 解密后乱码
先判断返回值是哪种编码问题。字符串形如 \xe4\xb8\xad\xe6\x96\x87 时,它保存的是 UTF-8 字节的转义文本:
import codecs
def decode_escaped_utf8(value: str) -> str:
escaped_bytes = codecs.escape_decode(value.encode("ascii"))[0]
return escaped_bytes.decode("utf-8")
字符串形如 䏿–‡ 时,是 UTF-8 字节被错误地按 Latin-1 解码:
def repair_utf8_mojibake(value: str) -> str:
return value.encode("latin-1").decode("utf-8")
两种修复不要无条件叠加。先保留原始响应并确认乱码形态,再只应用对应的一步转换,否则正常中文也会被破坏。
参考
JsRpc/README.md at main · jxhczhl/JsRpc
mitmproxy Addons
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。