安卓逆向常用指令 包含Frida IDA

前言

①、安装下载

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.xz
  • frida-server-15.2.0-android-x86_64.xz

📌 必须是 x86_64 版本,不能用 armarm64 版本!


📦 下载地址

前往官方发布页下载:

👉 https://github.com/frida/frida/releases

Assets 列表中找到:

frida-server-<version>-android-x86_64.xz

✅ 下载它!


🛠️ 安装步骤

  1. 解压 .xz 文件

    用 7-Zip 或 unxz 命令解压:

    unxz frida-server-16.1.1-android-x86_64.xz

    得到文件:frida-server-16.1.1-android-x86_64

  2. 推送到模拟器

    adb push frida-server-16.1.1-android-x86_64 /data/local/tmp/frida-server
  3. 添加可执行权限

    adb shell chmod 777 /data/local/tmp/frida-server
  4. 启动 Frida Server(后台运行)

    adb shell /data/local/tmp/frida-server &
  5. 验证是否运行成功

    adb shell ps | grep frida

    应该能看到 frida-server 进程。

  6. 本地测试连接

    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"
        ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值