下载和安装 Frida
主要参考文章:frida入门总结
Python安装Frida库
pip3 install frida
Successfully installed frida-15.1.17
pip3 install frida-tools
Successfully installed frida-tools-10.5.4 prompt-toolkit-3.0.28
模拟器下载配置 frida-server
下载地址:https://github.com/frida/frida/releases
夜神模拟器6.6,尝试下载 frida-server-15.1.17-android-arm.xz 版本(测试报错,参考文章发现模拟器中下载版本x86版本),再尝试下载 frida-server-15.1.17-android-x86_64.xz(无法执行),再下载 x86(32位是一定可以运行的,第二次尝试属实呆逼)。 (最终成功安装和验证版本:frida-server-15.1.17-android-x86)
上传到模拟器指定目录:adb.exe push frida-server-15.1.17-android-x86 /data/local/tmp
赋予权限:adb shell chmod 777 /data/local/tmp/frida-server-15.1.17-android-x86
运行:adb shell ./data/local/tmp/frida-server-15.1.17-android-x86 验证:frida-ps -U 报错:Failed to enumerate processes: unable to inject library into process without libc 解决办法:参考 python hook神器之Frida学习 下载 x86_64 版本。
x86_64 版本报错:not executable: 64-bit ELF file
查看手机进程进行验证,打开新的命令行,输入命令:frida-ps -U 最终如图,成功安装 frida-server-15.1.17-android-x86 版本。
建议把配置命令打包成 bat 脚本:
adb push frida-server-15.1.17-android-x86 /data/local/tmp
adb shell chmod 777 /data/local/tmp/frida-server-15.1.17-android-x86
adb shell ./data/local/tmp/frida-server-15.1.17-android-x86
使用Frida注入JavaScript脚本
参考技术文章:仅需10行代码,使用 Frida 完成 AutoJS脚本解密
夜神模拟器
JavaScript脚本说明:同事已经写好了 hook 脚本,所以本部分内容关注调用脚本并注入,以此来绕过 Root 检测和解密数据。
本地Hook脚本 名称:Hook.js
应用在模拟器的位置:/data/data/com.tlbank.betauat
客户端环境:夜神模拟器 6.6
同事给的注入脚本的命令:frida -UF -l Hook.js --no-pause
步骤:
- 首先使用 adb 命令开启模拟器的 frida 服务;
- 打开App
- 迅速执行注入脚本的命令
测试结果:根据回显判断Hook成功,但App进入黑屏状态,同事推测是App对模拟器有检测禁用。
安卓测试机
连接PC机方式:USB数据线,连接后可以直接使用 adb 工具操作手机。
Root 权限
安卓测试机权限问题:发现对 /data 目录没有访问权限,使用 adb 向根目录写入 Frida 发现 Read-only file system 。
查看权限:adb shell whoami,返回 shell 。(模拟器默认是root权限)
尝试提高权限:adb shell su,返回 /system/bin/sh: su: not found 。阅读相关文章,需要下载 su 文件到 adb 同一目录。(模拟器是可以执行的
运行命令:adb remount,返回 Not running as root. Try "adb root" first 。 运行命令:adb root,然后使用 adb shell 进行 push 文件仍然返回 Read-only file system。
中午询问同事,发现该测试机需要打开应用 SuperSU 后才能给予 Root 环境。测试机上打开i应用更新后,重新执行 adb 命令:adb shell su,获取到 root 权限。
安装并验证Frida
查看安卓测试机系统信息:adb shell cat /proc/cpuinfo,得到处理器是 AArch64 Processor rev 2 (aarch64)。
测试机上传 Frida 并赋权运行 , 测试 android-arm64 ,验证 frida-ps -U 报错:Failed to enumerate processes,如图。 测试 android-x86_64 ,运行时报错:not executable: 64-bit ELF file。
# arm64
adb push frida-server-15.1.17-android-arm64 /data/local/tmp
adb shell chmod 777 /data/local/tmp/frida-server-15.1.17-android-arm64
adb shell su
./data/local/tmp/frida-server-15.1.17-android-arm64
# x86_64
adb push frida-server-15.1.17-android-x86_64 /data/local/tmp
adb shell chmod 777 /data/local/tmp/frida-server-15.1.17-android-x86_64
adb shell su
./data/local/tmp/frida-server-15.1.17-android-x86_64
测试 32 位的, x86返回 not executable: 32-bit ELF file , arm 返回 Failed to enumerate processes: unable to handle 64-bit processes due to build configuration 。
# x86
adb push frida-server-15.1.17-android-x86 /data/local/tmp
adb shell chmod 777 /data/local/tmp/frida-server-15.1.17-android-x86
adb shell su
./data/local/tmp/frida-server-15.1.17-android-x86
# arm
adb push frida-server-15.1.17-android-arm /data/local/tmp
adb shell chmod 777 /data/local/tmp/frida-server-15.1.17-android-arm
adb shell su
./data/local/tmp/frida-server-15.1.17-android-arm
运行 Frida 解决方案: 询问同事,查看测试机版本是 Android 6.0.1 ,PC机和测试机的Frida版本需要使用 12.8.19 的。
# PC机卸载原有Frida并下载12.8版本
pip3 uninstall frida
pip3 uninstall frida-tools(版本兼容,无需卸载)
pip3 search frida # 未找到指定版本,访问 Github 项目地址进行下载
pip3 install frida==12.8.19(Windows搞了半天不如这一句安装语句)
pip3 install frida==6.0.1(版本不对也会报错)
WIndows安装参考:https://www.52pojie.cn/thread-1100931-1-1.html(弃)
下载地址:https://pypi.org/project/frida/12.8.19/
下载文件:frida-12.8.19-py3.7-win-amd64.egg
安装文件:easy_install "frida-12.8.10-py3.7-win-amd64.egg"
# 安装frida-server
adb push frida-server-12.8.19-android-arm64 /data/local/tmp
adb shell chmod 777 /data/local/tmp/frida-server-12.8.19-android-arm64
adb shell su
./data/local/tmp/frida-server-12.8.19-android-arm64
# 验证
frida-ps -U
# 报错:unable to connect to remote frida-server: Connection closed
# 原因:frida版本不对,不是15
frida-ps -U
# 报错:Failed to enumerate processes: enumerate_processes() got an unexpected keyword argument 'scope'
# 原因:frida-tools版本不对
最终验证成功
报错信息:之前的 Frida 没有关闭,导致端口被占用。 Unable to start: Could not listen on address 127.0.0.1, port 27042: Error binding to address 127.0.0.1:27042: Address already in use 解决方式如下,参考文章 Android_server提示端口被占用。
安卓测试机root权限执行
ps -e | grep frida # 空记录
ps|grep frida # 查询到记录
kill -s 9 10788 # 成功杀死进程
PC机执行
netstat -aon|findstr 27042 # 空记录
开始Hook
开启 Frida-Server,并使用 frida-ps -U 进行验证。
adb shell su
./data/local/tmp/frida-server-12.8.19-android-arm64
同事给的注入脚本的命令:frida -UF -l Hook.js --no-pause。 打开App,同时运行Hook命令,成功绕过检测机制! Hook脚本如下。
function rootcheck() {
Java.use("com.tlczbank.trusfort.provider.TrusfortServiceImpl").checkEnvironment.implementation = function (a) {
console.log("pass root check")
}
}
function encryptDataWithSM() {
Java.use("com.yitong.mbank.util.security.CryptoUtil").encryptDataWithSM.implementation = function (a, b, c) {
console.log("请求包结果========================>", b);
var result = this.encryptDataWithSM(a, b, c);
return result;
}
}
function decryptDataWithSM() {
Java.use("com.yitong.mbank.util.security.CryptoUtil").decryptDataWithSM.implementation = function (a, b, c) {
var result = this.decryptDataWithSM(a, b, c);
console.log("返回包结果========================>", result);
return result;
}
}
function a() {
Java.use("com.yitong.mbank.util.security.CryptoUtil").a.implementation = function (a, b, c) {
var result = this.a(a, b, c);
console.log("use a a,b,c,result===============>", a, b, c, result);
return result;
}
}
function decryptData() {
Java.use("com.yitong.mbank.util.security.CryptoUtil").decryptData.implementation = function (a, b, c) {
var result = this.decryptData(a, b, c);
console.log("use decryptData a,b,c,result===============>", a, b, c, result);
return result;
}
}
function sm2Encrypt() {
Java.use("com.yitong.mbank.util.security.CryptoUtil").sm2Encrypt.overload('android.app.Application', 'java.lang.String', 'java.lang.String', 'java.lang.String')
.implementation = function (a, b, c, d) {
var result = this.sm2Encrypt(a, b, c, d);
console.log("use sm2Encrypt a,b,c,result===============>", a, b, c, d, result);
return result;
}
}
function main() {
Java.perform(function () {
rootcheck();
encryptDataWithSM();
decryptDataWithSM();
});
}
setImmediate(main);
|