【Frida Android】基础篇10:Native层Hook基础--普通 Hook

文章目录

    • [1. 基础概念](#1. 基础概念)
      • [1.1 原生函数(Native函数)](#1.1 原生函数(Native函数))
      • [1.2 原生函数Hook的意义](#1.2 原生函数Hook的意义)
    • [2. 核心语法(基于Frida 17+)](#2. 核心语法(基于Frida 17+))
      • [2.1 环境准备](#2.1 环境准备)
      • [2.2 获取目标类](#2.2 获取目标类)
      • [2.3 Hook目标方法](#2.3 Hook目标方法)
      • [2.4 关键API说明](#2.4 关键API说明)
    • [3. 案例解析](#3. 案例解析)
      • [3.1 代码分析](#3.1 代码分析)
      • [3.2 Hook思路](#3.2 Hook思路)
      • [3.3 Hook脚本实现](#3.3 Hook脚本实现)
      • [3.4 获取结果](#3.4 获取结果)
    • [4. 技术总结](#4. 技术总结)
      • [4.1 核心要点](#4.1 核心要点)
      • [4.2 应用场景](#4.2 应用场景)
      • [4.3 注意事项](#4.3 注意事项)

⚠️本博文所涉安全渗透测试技术、方法及案例,仅用于网络安全技术研究与合规性交流,旨在提升读者的安全防护意识与技术能力。任何个人或组织在使用相关内容前,必须获得目标网络 / 系统所有者的明确且书面授权,严禁用于未经授权的网络探测、漏洞利用、数据获取等非法行为。

1. 基础概念

1.1 原生函数(Native函数)

原生函数指通过C/C++语言编写、经编译生成动态链接库(如Android中的.so文件)的函数,通常在Java层通过native关键字声明并调用。这类函数相比Java层代码具有更高的执行效率,常被用于性能敏感场景(如加密算法、数据校验等)。

1.2 原生函数Hook的意义

原生函数由于其编译后的二进制特性,直接逆向分析难度较高。通过Hook技术可绕过原生函数的内部逻辑(如复杂的加密校验),快速定位关键逻辑或验证功能猜想,是逆向工程中高效分析原生函数的重要手段。

2. 核心语法(基于Frida 17+)

2.1 环境准备

通过Java.perform确保在Java虚拟机(JVM)环境中执行Hook逻辑,避免因线程上下文问题导致的执行失败:

javascript 复制代码
Java.perform(function () {
  // Hook逻辑需写在此处
});

2.2 获取目标类

使用Java.use(className)获取目标Java类的引用,className为类的完整路径(包含包名):

javascript 复制代码
var TargetClass = Java.use("com.example.TargetClass");

2.3 Hook目标方法

通过修改方法的implementation属性重写目标方法逻辑,可获取参数、修改返回值或调用原方法:

javascript 复制代码
TargetClass.targetMethod.implementation = function (param1, param2) {
  // 打印参数(调试用)
  console.log("参数1: " + param1);
  
  // 可选:调用原方法获取原始返回值
  var originalResult = this.targetMethod(param1, param2);
  
  // 修改返回值(按需定制)
  return modifiedResult;
};

2.4 关键API说明

  • Java.use():获取类的包装器,用于访问类的方法和属性;
  • implementation:方法的实现属性,重写该属性即可拦截方法调用;
  • this:在重写的方法中,this指向当前实例,可通过this.otherMethod()调用同类其他方法。

3. 案例解析

本章示例应用的链接:

https://pan.baidu.com/s/16EE2XE-OZS_xBRPlWUODbw?pwd=n2vb

提取码: n2vb

使用APK:Challenge 0x8.apk

3.1 代码分析

以下为目标Android应用的核心代码(MainActivity类):

java 复制代码
public class MainActivity extends AppCompatActivity {
    private ActivityMainBinding binding;
    Button btn;
    EditText edt;

    // 声明原生函数(具体实现在.so库中)
    public native int cmpstr(String str);

    // 加载包含原生函数的动态库
    static {
        System.loadLibrary("frida0x8");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化UI组件
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        edt = findViewById(R.id.editTextText);
        btn = findViewById(R.id.button);

        // 按钮点击事件逻辑
        btn.setOnClickListener(v -> {
            // 获取输入框内容
            String ip = edt.getText().toString();
            // 调用原生函数cmpstr进行校验
            int res = cmpstr(ip);
            // 根据返回值显示结果
            if (res == 1) {
                Toast.makeText(MainActivity.this, "YEY YOU GOT THE FLAG " + ip, 1).show();
            } else {
                Toast.makeText(MainActivity.this, "TRY AGAIN", 1).show();
            }
        });
    }
}

关键逻辑分析

  • 应用通过System.loadLibrary("frida0x8")加载原生库libfrida0x8.so,其中包含cmpstr函数的实现;
  • 用户点击按钮时,输入框内容被传入cmpstr函数,其返回值决定了验证结果(返回1则成功,否则失败);
  • 核心目标:通过Hookcmpstr函数,使其返回1以绕过校验。

3.2 Hook思路

  1. 定位目标函数 :通过代码分析可知,cmpstr是决定验证结果的关键函数,且为Java层声明的原生函数,可通过Java层Hook拦截;
  2. 设计Hook逻辑 :无需关心cmpstr的内部校验逻辑,直接强制其返回1,即可让应用认为输入合法;
  3. 执行Hook :将脚本注入目标进程,拦截cmpstr调用并修改返回值。

3.3 Hook脚本实现

javascript 复制代码
import Java from 'frida-java-bridge';

Java.perform(function () {
    // 获取MainActivity类引用
    var MainActivity = Java.use("com.ad2001.frida0x8.MainActivity");
    
    // Hook cmpstr方法
    MainActivity.cmpstr.implementation = function (str) {
        // 打印输入参数(用于调试,查看用户输入)
        console.log("输入的字符串: " + str);
        
        // 强制返回1,使校验通过
        return 1;
    };
});

3.4 获取结果

执行Hook脚本后,无论输入框中填写什么内容(这里输入1),cmpstr函数都会返回1,应用将显示成功提示:

4. 技术总结

4.1 核心要点

  • 原生函数Hook的核心是拦截函数调用并修改其行为,无需了解函数内部实现细节;
  • 对于Java层声明的原生函数,可通过Frida的Java.useimplementation属性快速Hook;
  • 关键步骤:定位目标函数→编写Hook逻辑(参数打印、返回值修改等)→注入进程执行。

4.2 应用场景

  • 逆向分析:快速验证原生函数的作用(如参数含义、返回值影响);
  • 功能调试:绕过复杂校验逻辑(如注册码、权限验证),测试后续功能;
  • 安全测试:模拟异常输入或返回值,验证应用稳定性。

4.3 注意事项

  • Hook需在目标进程运行时进行,需确保进程已启动且具备附加权限;
  • 对于纯Native层函数(未在Java层声明),需使用Frida的Native层Hook语法(如Interceptor.attach);
  • 过度修改返回值可能导致应用逻辑异常,需结合实际场景设计Hook逻辑。
相关推荐
xiangpanf8 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
大方子11 小时前
【PolarCTF】Don‘t touch me
网络安全·polarctf
robotx11 小时前
安卓线程相关
android
消失的旧时光-194311 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
未知鱼11 小时前
Python安全开发之子域名扫描器(含详细注释)
网络·python·安全·web安全·网络安全
dalancon12 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon13 小时前
VSYNC 信号完整流程2
android
dalancon13 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户693717500138414 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android14 小时前
Android 刷新一帧流程trace拆解
android