GKLBB

当你经历了暴风雨,你也就成为了暴风雨

导航

软件神器 --- hook之王 frida

官网:https://frida.re

Frida 是一款强大的动态代码插桩工具(Dynamic Instrumentation Toolkit),允许通过 JavaScript 注入到目标进程,实时修改、监控和分析应用程序行为。其核心功能覆盖逆向工程、安全测试、漏洞挖掘、自动化分析等场景。以下是 Frida 功能的详细分类列举:

总得来讲就是

  • 实时函数 Hook

  • 内存数据读写

  • 动态修改应用逻辑


1.寄生进程。自己的代码注入到目标进程中使用js脚本语言进行运行时自定义控制。
2.函数监事与替换:在 App 调用某个关键函数时,当个“中间人”,能监视、甚至修改它传入的参数和返回的结果。通过监听关键函数实现,甚至可以实现。文件系统监控:监视这个 App 都读了或写了手机里的哪些文件。禁用证书绑定使得抓包软件可以抓取https数据进行安全分析。绕过 Root/Jailbreak 检测。流量拦截,即使通讯是加密。比绕过root检测更近一步。直接Hook获取设备信息的函数(如Build.Serial, Build.MODEL,android_id,IMEI等),返回我自定义的虚假信息,保护个人隐私数据让App以为运行在另一台完全不同的设备上。
3.内存读写与查找:直接翻看或修改这个 App 内存里记着的数据。甚至可以实现 动态修改DEX/ELF文件 在内存中直接修补Android的DEX字节码或原生库的机器码。这比简单的函数Hook更底层,可以实现更彻底的功能修改,比如永久性地跳过一个检查逻辑。
4.强迫app调用一个内部原生函数并告诉我结果。
5.动态代码执行:让 App 临时执行一段我塞给它的新指令。
6.枚举模块与导出函数:把这个 App 都加载了哪些“技能包”(插件/库)以及包里都有哪些“技能”(函数)全都列表给我看。
7.线程控制:把这个 App 里干活的每个“工人”(线程)叫停或者让他继续干活。
8.堆栈回溯:当 App 执行到某处时,查它的“族谱”,看它是从哪一步一步步调过来的。
9.持久化注入:把这针(脚本)打成“疫苗”,让 App 每次一启动就自动带上我的命令。
10.代码追踪与分析 (Stalker),不是只监听一个函数调用,而是给App的一小段代码“戴上一个贴身记录仪”,把它执行的每一条指令(比如CPU执行的每一个步骤)都详细记录下来,生成一份极其详细的“行动报告”,用于深度分析复杂算法或混淆代码的执行流程。
11.进程间通信 (RPC - Remote Procedure Call) 让我写在App里的JS脚本“变身”成一个小服务端。我电脑上的Python程序可以直接“远程调用”这个服务端里的函数,让它返回数据或者执行任务。这样我就不用一直把结果console.log出来再手动复制了,可以实现全自动化分析。
12.崩溃收集与分析 给目标App装一个“黑匣子”。当App因为各种原因(比如我Hook出错或者它本身的Bug)突然崩溃时,这个黑匣子会自动触发,把崩溃那一刻的内存、寄存器状态、调用栈等所有信息都保存下来发给我,方便我定位问题。
13.模拟用户操作 (仅限Android) 虽然这不是Frida的核心API,但通过Frida调用Android的Java API,可以模拟点击、滑动、输入等操作,实现“机器人”式的自动化测试或UI交互,无需root权限。


一、核心功能:代码注入与运行时控制

  1. 进程注入

    • 支持注入到 本地进程(Windows/macOS/Linux)、移动端(Android/iOS)、模拟器 和 IoT 设备。

    • 注入方式:frida-tracefrida CLI, Python/Node.js API,或直接嵌入到应用。

  2. 跨平台支持

    • 目标系统:Windows, Linux, macOS, Android, iOS, QNX, FreeBSD。

    • 架构兼容:x86, x64, ARM, ARM64, MIPS。

  3. 多语言运行时绑定

    • 通过 JavaScript 编写注入脚本(核心)。

    • 支持 TypeScript(需编译为 JS)。

    • 通过 Python, C#, Node.js, Swift 等控制脚本执行。


二、动态代码插桩(Hooking)

  1. 函数级 Hook

    • 拦截任意函数调用(包括系统 API、第三方库、自定义函数)。

    • 修改参数/返回值:动态篡改输入输出。

    javascript
     
    Interceptor.attach(targetFunction, {
      onEnter: function(args) { 
        args[0] = ptr(0x1000); // 修改参数
      },
      onLeave: function(retval) {
        retval.replace(0); // 修改返回值
      }
    });
  2. 内存读写

    • 读取/修改任意内存地址:

      javascript
       
      let buffer = Memory.readByteArray(ptr(0x1000), 4);
      Memory.writeUtf8String(ptr(0x2000), "Hacked!");
  3. 内存扫描与模式匹配

    • 搜索特征码、字符串、整数等:

      javascript
       
      Memory.scan(module.base, module.size, "41 B8 ? ? ? ?", {
        onMatch: (address) => console.log("Found at:", address)
      });

三、运行时操作

  1. 调用原生函数

    • 直接调用目标进程中的函数:

      javascript
       
      let func = new NativeFunction(ptr(0x1234), 'int', ['int']);
      let result = func(42);
  2. 动态代码执行

    • 注入并执行 Shellcode:

      javascript
       
      const code = Memory.allocUtf8String("mov x0, #0x42; ret");
      const func = new NativeFunction(code, 'int', []);
      func();
  3. 对象操作(Android/iOS)

    • Android (Java):Hook Java 方法、枚举类、实例化对象:

      javascript
       
      Java.perform(() => {
        let TextView = Java.use("android.widget.TextView");
        TextView.setText.implementation = (text) => {
          this.setText("Hijacked: " + text);
        };
      });
    • iOS (Objective-C/Swift):Hook OC 方法、调用 Swift 函数:

      javascript
       
      ObjC.classes.NSString.stringWithString_("Frida Rocks!");

四、进程与模块分析

  1. 枚举模块与导出函数

    javascript
     
    Process.enumerateModules().forEach(module => {
      console.log(module.name, module.base);
      module.enumerateExports().forEach(exp => console.log(exp.name));
    });
  2. 线程控制

    • 枚举线程、挂起/恢复、注入线程上下文。

  3. 堆栈回溯(Stack Trace)

    • 实时捕获函数调用栈:

      javascript
       
      Thread.backtrace(this.context, Backtracer.ACCURATE);

五、网络与加密监控

  1. SSL/TLS 解密

  • Hook OpenSSL/BoringSSL/NSS 等库,捕获明文:

    javascript
     
    Interceptor.attach(ssl_read_ptr, { onEnter: logBuffer });
  1. HTTP(S) 流量拦截

  • Hook 网络库(如 Android 的 OkHttp, iOS 的 NSURLSession):

    javascript
     
    OkHttpClient.onRequest = (request) => { 
      console.log("Request to:", request.url());
    };

六、反调试与绕过

  1. 绕过 Root/Jailbreak 检测

  • Hook 检测函数(如 Android 的 checkSuExists()),强制返回 false

  1. 禁用证书绑定(SSL Pinning)

  • Hook 证书验证函数(如 checkServerTrusted()),直接跳过验证。

  1. 对抗反调试机制

  • Patch ptrace (Linux/Android)、sysctl (macOS/iOS) 等反调试函数。


七、工具链与集成

  1. 命令行工具

  • frida:REPL 交互环境。

  • frida-trace:快速追踪函数调用(如 frida-trace -i "open*" com.app.xxx)。

  • frida-ps:列出设备进程。

  1. 开发者 API

  • 支持 Python, Node.js, C 等编写控制脚本:

    python
     
    import frida
    device = frida.get_usb_device()
    session = device.attach("com.app.target")
    script = session.create_script(open("script.js").read())
    script.load()
  1. 可视化工具集成

  • Frida CodeShare:共享社区脚本。

  • Objection(基于 Frida):自动化移动端安全测试。

  • r2frida:与 Radare2/Ghidra 集成。


八、高级特性

  1. 持久化注入

    • 注入到 init(Android)或 launchd(iOS)实现开机自启。

  2. 远程设备管理

    • 通过 frida-linux-server 等连接远程设备。

  3. 性能分析

    • 使用 Stalker 追踪代码执行路径,生成 CPU 剖面图:

      javascript
       
      Stalker.follow({ 
        events: { compile: true },
        onReceive: (events) => { /* 分析指令流 */ }
      });
  4. 文件系统监控

    • Hook 文件操作函数(openreadwrite)记录敏感访问。

 

 


二、环境准备

1. 安装 Frida
# 安装 Python 环境 (推荐 Python 3.8+)
pip install frida-tools frida
2. 下载 Frida-Server (以 Android 为例)
  1. 查看设备 CPU 架构:

    adb shell getprop ro.product.cpu.abi
    # 输出示例:arm64-v8a
  2. 在 Frida Releases 下载对应版本的 frida-server-xx.x.x-android-xx.xz

  3. 推送并运行:

    adb push frida-server /data/local/tmp/
    adb shell "chmod 755 /data/local/tmp/frida-server"
    adb shell "/data/local/tmp/frida-server &"
3. 验证安装
frida-ps -U  # 查看 USB 连接的设备进程列表
# 成功则显示设备上的进程列表

三、第一个 Frida 脚本

目标:Hook Android 的 java.lang.String 构造函数

创建脚本 hook_string.js

javascript
 
Java.perform(() => {
  // 获取 String 类
  const StringClass = Java.use("java.lang.String");

  // Hook 构造函数
  StringClass.$init.overload("[B").implementation = function (bytes) {
    console.log("创建字符串: " + this.toString());
    return this.$init(bytes); // 调用原方法
  };
});
执行脚本:
bash
 
frida -U -l hook_string.js -f com.example.app --no-pause
  • -U: 使用 USB 设备

  • -l: 加载脚本

  • -f: 启动应用并注入

  • --no-pause: 立即启动进程


四、核心 API 详解

1. 基础结构
javascript
 
Java.perform(() => {
  // 所有 Java 相关操作必须在此回调中
});
2. Hook 方法
javascript
 
const Activity = Java.use("android.app.Activity");
Activity.onCreate.implementation = function (bundle) {
  console.log("Activity 被创建!");
  this.onCreate(bundle); // 调用原方法
};
3. 调用静态方法
javascript
 
const System = Java.use("java.lang.System");
System.exit.implementation = function (code) {
  console.log("阻止退出: " + code);
}; // 不调用原方法,阻止退出
4. 修改方法返回值
javascript
 
const Math = Java.use("java.lang.Math");
Math.random.implementation = function () {
  return 0.5; // 永远返回 0.5
};
5. 创建新对象
javascript
 
const String = Java.use("java.lang.String");
const newStr = String.$new("Hello Frida!"); // 等价于 new String("...")
6. 动态调用实例方法
javascript
 
Java.choose("android.view.View", {
  onMatch: function (instance) {
    instance.setBackgroundColor(0xFFFF0000); // 将所有 View 背景设为红色
  },
  onComplete: () => console.log("搜索完成")
});

五、实战案例:破解登录验证

假设目标应用有登录逻辑:

java
 
public boolean checkPassword(String input) {
  return input.equals("SECRET_PASSWORD");
}
Hook 脚本 bypass_login.js
javascript
 
Java.perform(() => {
  const LoginClass = Java.use("com.example.app.LoginManager");

  LoginClass.checkPassword.implementation = function (input) {
    console.log("原始输入: " + input);
    // 修改返回值,始终返回 true
    return true;
  };
});
执行:
bash
 
frida -U -l bypass_login.js -n "App Name"

六、进阶技巧

  1. 批量 Hook 所有重载方法

javascript
 
TargetClass.targetMethod.overloads.forEach(overload => {
  overload.implementation = function () {
    console.log(`调用 ${this} 的方法`);
    return this.targetMethod.apply(this, arguments);
  };
});
  1. 拦截系统加密函数

javascript
 
const Cipher = Java.use("javax.crypto.Cipher");
Cipher.doFinal.overload("[B").implementation = function (data) {
  const result = this.doFinal(data);
  console.log("加密数据: " + bytesToHex(result));
  return result;
};
  1. 内存操作

javascript
 
const base = Module.findBaseAddress("libtarget.so");
const offset = 0x1234;
const ptr = base.add(offset);

Memory.writeUtf8String(ptr, "HACKED"); // 修改内存字符串

七、调试与排错

  1. 查看堆栈

javascript
 
console.log(Java.use("android.util.Log").getStackTraceString(
  Java.use("java.lang.Exception").$new()
));
  1. 错误处理

javascript
 
try {
  riskyCode();
} catch (e) {
  console.log("错误: " + e.message);
}
  1. 日志输出到文件

bash
 
frida -U -l script.js -o log.txt

八、学习资源

  1. 官方文档

  2. Frida CodeShare - 共享脚本库

  3. 《逆向工程核心原理》 - Frida 实战章节


 

 
 

posted on 2025-08-10 20:20  GKLBB  阅读(288)  评论(0)    收藏  举报