前言
①、安装下载
1.Frida
根据你的输出:
adb shell getprop ro.product.cpu.abi
x86_64
这说明你的设备是 x86_64 架构,通常是 Android 模拟器(如雷电模拟器、夜神模拟器、蓝叠、MEmu 等),而不是真实手机。
✅ 你应该下载的 Frida Server 版本:
frida-server-{version}-android-x86_64.xz
例如:
frida-server-16.1.1-android-x86_64.xzfrida-server-15.2.0-android-x86_64.xz
📌 必须是 x86_64 版本,不能用 arm 或 arm64 版本!
📦 下载地址
前往官方发布页下载:
👉 https://github.com/frida/frida/releases
在 Assets 列表中找到:
frida-server-<version>-android-x86_64.xz
✅ 下载它!
🛠️ 安装步骤
-
解压
.xz文件用 7-Zip 或
unxz命令解压:unxz frida-server-16.1.1-android-x86_64.xz得到文件:
frida-server-16.1.1-android-x86_64 -
推送到模拟器
adb push frida-server-16.1.1-android-x86_64 /data/local/tmp/frida-server -
添加可执行权限
adb shell chmod 777 /data/local/tmp/frida-server -
启动 Frida Server(后台运行)
adb shell /data/local/tmp/frida-server & -
验证是否运行成功
adb shell ps | grep frida应该能看到
frida-server进程。 -
本地测试连接
frida-ps -Uai | grep snda如果能正常显示
包名,说明 Frida Server 已就绪。
⚠️ 常见错误(x86_64 模拟器专属)
| 错误现象 | 原因 | 解决 |
|---|---|---|
spawn: process not found |
用了 arm 版本的 frida-server |
改用 x86_64 版本 |
port 27042: Connection refused |
frida-server 没启动 | 用 adb shell 进去手动运行 |
killed |
权限不足或架构不匹配 | 重新 push + chmod |
device is not connected |
adb 未连接 | 运行 adb devices 检查 |
✅ 总结
| 你的设备 | x86_64 模拟器(如雷电、夜神) |
|---|---|
| 需要的 Frida Server | frida-server-*-android-x86_64.xz |
| 下载后操作 | 解压 → push → chmod → 后台运行 |
| 验证命令 | frida-ps -Uai |
注意
pip安装的版本最好和服务版本一致。
这里我安装的服务是15.2.0版本。对应pip指令如下:
pip install frida==15.2.0 #保证客户端版本号和服务端版本一致,不然会报错。
pip install frida-tools==10.5.0
一、启动篇
①、启动Frida
1.这里默认你的/data/local/tmp目录已经安卓好了frida服务 启动指令如下:
adb shell
gracelte:/ $ su root
gracelte:/ # cd /data/local/tmp/
gracelte:/data/local/tmp # chmod 777 frida-server
gracelte:/data/local/tmp # ./frida-server &
[1] 3716
2.端口转发
adb forward tcp:27042 tcp:27042
二、调试打包篇
①、设置android:debuggable=“true”
一般调试,或者使用Frida的spawn模式都需要是可调试状态
步骤 1:使用 apktool 反编译 APK
apktool d 包名.apk -o output_dir
步骤 2:编辑 AndroidManifest.xml
找到 <application> 标签,添加:
android:debuggable="true"
修改后像这样:
<application
android:debuggable="true"
android:icon="@drawable/icon">
步骤 3:重新打包
apktool b output_dir -o workflow.modified.apk
步骤 4:签名
使用 uber-apk-signer(推荐新手)
下载最新版,比如:uber-apk-signer-1.3.0.jar
放到你的项目目录,比如和 APK 放在一起
java -jar uber-apk-signer.jar --apk workflow.modified.apk
然后把生成好的apk重新装回去。然后执行如下指令,检查是否可调试
adb shell "dumpsys package com.snda.workflow | grep -i debuggable"
输出:flags=[ DEBUGGABLE HAS_CODE ] 表示可调试
三、Frida Hook篇
①、Frida基本语法
1.PYTHON 自启动APP模式(非附加)
import frida
import time
import subprocess
import sys
# 配置参数
DEVICE_ID = "emulator-5554" # 设备 ID,adb devices 显示的
PACKAGE_NAME = "cn.chinapost.jdpt.pda.pcs" # 应用包名
ACTIVITY_NAME = ".SplashActivity" # 启动的 Activity 名称
# 目标进程名(可从 adb shell ps 或 frida-ps 看到)
PROCESS_NAME = "中邮处理" # app图标名称
# ✅ 修改:指定 JS 文件路径,改为从文件读取
JS_FILE_PATH = "hook.js" # 与当前脚本同目录下的 hook.js 文件
def read_js_file(filepath):
"""读取外部 JS 脚本文件内容"""
try:
with open(filepath, 'r', encoding='utf-8') as f:
return f.read()
except Exception as e:
print(f"[!] 无法读取 JS 文件 {filepath}: {e}")
sys.exit(1)
def start_app(package, activity):
"""使用 adb 启动应用"""
component = f"{package}/{activity}"
cmd = ["adb", "shell", "am", "start", "-n", component]
print(f"[*] 执行: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"[!] 启动应用失败: {result.stderr}")
sys.exit(1)
else:
print(f"[*] 应用启动命令已发送: {component}")
def wait_for_process_by_name(device, process_name, timeout=30):
"""根据进程名等待并返回 PID"""
print(f"[*] 等待进程: {process_name}")
start_time = time.time()
while time.time() - start_time < timeout:
try:
processes = device.enumerate_processes()
for proc in processes:
if proc.name == process_name:
print(f"[*] 找到目标进程: {proc.name} (PID: {proc.pid})")
return proc.pid
time.sleep(1)
except Exception as e:
print(f"[!] 查询进程出错: {e}")
print(f"[!] 超时:未找到进程 {process_name}")
sys.exit(1)
def main():
# 连接到设备
try:
device = frida.get_device(id=DEVICE_ID)
print(f"[*] 连接到设备: {device.id}")
except Exception as e:
print(f"[!] 无法连接设备: {e}")
sys.exit(1)
# 启动应用
start_app(PACKAGE_NAME, ACTIVITY_NAME)
# 等待进程出现
target_pid = wait_for_process_by_name(device, PROCESS_NAME)
# 附加到进程
print(f"[*] 正在附加到 PID {target_pid}...")
try:
session = device.attach(target_pid)
print(f"[*] 附加成功: {session}")
except Exception as e:
print(f"[!] 附加失败: {e}")
sys.exit(1)
# ✅ 修改:从文件读取 JS 脚本
js_code = read_js_file(JS_FILE_PATH)
# 创建脚本并注入
try:
script = session.create_script(js_code)
script.on('message', on_message)
print("[*] 正在注入脚本...")
script.load()
print("[*] 脚本注入成功!")
except Exception as e:
print(f"[!] 脚本注入失败: {e}")
sys.exit(1)
# 保持运行
print("[*] 保持运行,按 Ctrl+C 停止...")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\n[*] 正在退出...")
session.detach()
sys.exit(0)
def on_message(message, data):
"""处理来自 Frida 脚本的消息"""
if message['type'] == 'send':
print(f"[JS] {message['payload']}")
else:
print(f"[Error] {message}")
if __name__ == "__main__":
main()
2.hexdump函数的使用
这里是hook App中加载出来的所有so文件,并打印位置。然后dump下来64字节的数据。
if (Java.available) {
Java.perform(function () {
console.log("[*] Hooking dlopen... (Only user/custom .so)");
// 定义系统路径前缀
var systemPaths = [
"/system/",
"/vendor/",
"/system/lib",
"/system/lib64",
"/vendor/lib",
"/vendor/lib64",
"/apex/",
"/dev/",
"/product/",
"/mnt/",
"/data/dalvik-cache/",
"/data/app/"
];
// 常见系统库名称(无论路径如何,都视为系统库)
var systemLibNames = new Set([
"libc.so",
"libdl.so",
"libm.so",
"liblog.so",
"libandroid.so",
"libz.so",
"libstdc++.so",
"libGLESv1_CM.so",
"libGLESv2.so",
"libEGL.so",
"libOpenSLES.so",
"libjnigraphics.so",
"libOpenMAXAL.so",
"librs_jni.so",
"libbcinfo.so",
"libRScpp.so",
"libRS.so"
]

最低0.47元/天 解锁文章

6968

被折叠的 条评论
为什么被折叠?



