您的位置:首页 > 文旅 > 美景 > 常用的 Android frida hook 代码片段

常用的 Android frida hook 代码片段

2024/12/23 11:36:06 来源:https://blog.csdn.net/future_M/article/details/139955699  浏览:    关键词:常用的 Android frida hook 代码片段

1.获取 com.example.ClassName类,并修改其中的 getVip(i) 方法。

Java.perform(function () {var targetClass= Java.use('com.example.ClassName')//改为需要hook的类名//重写其中的getVip(i) 函数targetClass.getVip.implementation = function (i) {console.log('i: ', i);var result = this.getVip(i);console.log('result: ', result);return result;}
});

2.从内存中寻找包含 com.example.ClassName的类,并打印出来

Java.perform(function() {Java.enumerateLoadedClasses({onMatch: function(className) {if (className.includes('com.example.ClassName')) {改为需要hook的类名console.log(className);}},onComplete: function() {console.log('Class enumeration complete');}});
});

3.获取某类中的所有成员变量 打印:名称+数值+类型

Java.perform(function() {// 找到目标类var targetClass = Java.use('com.example.ClassName');//改为需要hook的类名// hook指定函数从而找到实例,打印实例中所有的字段targetClass.e.implementation = function(str) {var fields = this.class.getDeclaredFields();for (var i = 0; i < fields.length; i++) {fields[i].setAccessible(true);//确保可以访问console.log("[*] Field " + fields[i].getName() + ": " + fields[i].get(this)," Type: ",fields[i].getType().getName());}}
});

4.Hook 已经存在的实例,通过构造函数或内存查找找到实例,从而调用其中的函数。不通过拦截某函数的方式。

global.instances = [];// 存储实例的全局数组
Java.perform(function () {// 获取目标类var MyClass = Java.use('com.example.ClassName');// Hook构造函数以捕获新创建的实例,重写构造函数时需要具体修改传入的变量类型'java.lang.String'MyClass.$init.overload('java.lang.String').implementation = function (str) {console.log('MyClass instance created');var instance = this;// 将实例存储到全局数组中global.instances.push(instance);return this.$init(str);};// 查找所有已经存在的实例Java.choose('com.example.ClassName', {onMatch: function (instance) {console.log('Found instance: ' + instance);global.instances.push(instance);},onComplete: function () {console.log('Instance search complete');}});// 调用方法示例Java.perform(function () {if (global.instances.length > 0) {var instance = global.instances[0]; // 获取第一个实例console.log('Calling myMethod on: ' + instance);instance.myMethod(); // 调用方法} else {console.log('No instances found');}});
});

5.打印构造函数的调用堆栈(通过抛出错误来获取)

Java.perform(function () {// 替换`com.example.ClassName`为你要监控的类名var targetClass = 'com.example.ClassName';var targetConstructor = Java.use(targetClass).$init.overload('long', 'java.lang.ref.WeakReference', 'boolean');//参数需要根据具体的构造方法修改targetConstructor.implementation = function (param1, param2, param3) {console.log('Constructor of ' + targetClass + ' called with parameters:');console.log('param1: ' + param1);console.log('param2: ' + param2);console.log('param3: ' + param3);// 获取当前的调用堆栈var stackTrace = Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Exception').$new());console.log(stackTrace);// 调用原始构造函数return targetConstructor.call(this, param1, param2, param3);};
});

6.当某实例类作为参数传入时,通过反射来修改其实例类中的私有字段

Java.perform(function() {// 找到目标类var targetClass = Java.use('com.example.ClassName');// hook指定函数从而找到实例,打印实例中所有的字段targetClass.D0.implementation = function(userInfo) {console.log("==================");// 使用反射来访问和修改字段var fieldName = 'someFieldName'; // 替换为实际的字段名var field = userInfo.class.getDeclaredField(fieldName);field.setAccessible(true); // 确保可以访问// 打印原始字段值console.log("[*] Before modification: " + field.get(userInfo));// 修改字段值field.set(userInfo, 'newValue'); // 替换'newValue'为你想设置的值fields.set(this, Long.$new(6666));//设置的值必须复合要求的格式// 打印修改后的字段值console.log("[*] After modification: " + field.get(userInfo));// 调用原始函数this.D0(userInfo);return;};
});

7.其他:

获取内部类:

const className = Java.use('外部类$内部类') //通过添加 $ 符号

当变量与函数名称一样时,修改变量的值:

this._a.value='1'; //在要修改的变量名前面加下划线_

获取匿名类:
匿名类根据内存生成,没有显式的类名,通过 smali 代码来判断,获取到的可能像下面这样:

const className = Java.use('包名.MainActivity$1') // 匿名类名称:1,调用类似内部类

获取所有类:

Java.enumerateLoadedClassesSync() // 同步获取已加载所有类,返回一个数组
Java.enumerateLoadedClasses() // 异步

加载类下所有方法,属性:

const Utils = Java.use('com.example.ClassName')
const methods = Utils.class.getDeclaredMethods() // 方法
const constructors = Utils.class.getDeclaredConstructors() // 构造函数
const fields = Utils.class.getDeclaredFields() // 字段
const classes = Utils.class.getDeclaredClasses() // 内部类
const superClass = Utils.class.getSuperclass() // 父类(抽象类)
const interfaces = Utils.class.getInterfaces() // 所有接口

类型转换:
将 variable 转换为 String类型

var StringClass=Java.use("java.lang.String");
var NewTypeClass=Java.cast(variable,StringClass);

自己初始化一个实例并调用参数:

var ClassName=Java.use("com.example.ClassName");
var instance = ClassName.$new();//创建一个实例,$new 实际代表调用构造方法
instance.func();

8.函数参数类型表示:

当重载某个函数时,frida需要根据参数的类型来找到特定的重载函数,参数类型如果是基本类型,可直接用其Java/JavaScript中的名称,如果是基本类型数组需要左括号加缩写,如果是普通类型,则需要类名全拼。如下:

  1. 基本类型不变:int short char byte boolean float double long
类型重载时
boolean[][Z
byte[][B
char[][C
double[][D
float[][F
int[][I
long[][J
short[][S
  1. 任意类: 完整类名 例如:java.lang.String
  2. 对象数组:加左括号 例如: [java.lang.String

不同的 frida 版本的区别:

  1. frida-clr-16.3.0:
    这是一个用于 .NET/CLR (Common Language Runtime) 平台的 Frida 版本。它允许在 .NET 应用程序中进行动态分析和调试。
  2. frida-core-devkit-16.3.0:
    这是 Frida 核心库的开发工具包,提供了核心 API 的头文件和库,用于开发自定义的 Frida 应用。
  3. frida-gadget-16.3.0:
    Frida Gadget 是一个轻量级的嵌入式版本,适合于将 Frida 集成到现有的应用程序中,特别是移动设备上的应用。
  4. frida-gum-devkit-16.3.0:
    Gum 是 Frida 的低级 API,用于提供跨平台的代码注入功能。这个开发工具包包含了使用 Gum 的必要文件。
  5. frida-gumjs-devkit-16.3.0:
    这是一个基于 Gum 的 JavaScript 引擎开发工具包,使开发者可以使用 JavaScript 进行跨平台的代码注入。
  6. frida-inject-16.3.0:
    这是 Frida 用于将代码注入到目标进程的工具,允许用户在运行时将脚本注入到应用程序中。
  7. frida-portal-16.3.0:
    Frida Portal 是一个 Web 界面,用于管理和监控 Frida 实例,方便用户进行远程操作。
  8. frida-qml-16.3.0:
    这是用于 QML (Qt Modeling Language) 应用程序的 Frida 版本,适用于 Qt 开发者。
  9. frida-server-16.3.0:
    Frida Server 是运行在目标设备上的一个服务,使得远程设备可以被 Frida 控制和调试。常用于 Android 和 iOS 设备。
  10. frida-v16.3.0-electron:
    这是一个预编译的 Frida 版本,适用于基于 Electron 框架的应用程序,方便开发者进行调试和分析。
  11. frida-v16.3.0-node:
    这是一个预编译的 Frida 版本,适用于 Node.js 应用程序,帮助开发者在 Node.js 环境中进行动态分析。
  12. frida_16.3.0_appletvos:
    这是 Frida 适用于 Apple TV (tvOS) 的版本,帮助开发者在 Apple TV 上进行应用分析和调试。
  13. frida_16.3.0_iphoneos:
    这是 Frida 适用于 iOS 设备 (如 iPhone、iPad) 的版本,帮助开发者在 iOS 设备上进行应用分析和调试。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com