常用的 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 设备上进行应用分析和调试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/742324.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

「全新升级,性能更强大——ONLYOFFICE 桌面编辑器 8.1 深度评测」

文章目录 一、背景二、界面设计与用户体验三、主要新功能亮点3.1 高效协作处理3.2 共同编辑&#xff0c;毫无压力3.3 批注与提及3.4 追踪更改3.5 比较与合并3.6 管理版本历史 四、性能表现4.1 集成 AI 工具4.2 插件强化 五、用户反馈与使用案例 一、背景 Ascensio System SIA -…

finalize——释放内存

重写 没写的话就按照定义的方法&#xff0c;object的默认方法 system.gc会主动调用垃圾回收器&#xff0c;不会使用finalize方法。需求不大 对于用debug怎么进入jdk源码&#xff0c;ararry.sort的源码进入

OpenAI: 禁止在不支持的地区使用其 API

OpenAI 给开发者发邮件表示&#xff0c;禁止其 API 用于不被允许的地区&#xff0c;否则 7 月 9 日将面临封杀。 本次封杀似乎不区分 IP &#xff0c;而是直接按照地理位置。

Centos+Jenkins+Maven+Git 将生成的JAR部署到远程服务器上

1、登录 没有安装的参考下面的安装步骤先安装: Jenkins安装手册 输入账号、密码登录系统。 2、新建任务 2.1 创建页面 1,“输入一个任务名称”; 2,任务类型点击“构建一个maven项目”; 3,点击“确定”,此时,构建任务创建完成。 2.2 General 1、描述:输入要部署…

Kotlin设计模式:代理模式详解

Kotlin设计模式&#xff1a;代理模式详解 在软件开发中&#xff0c;设计模式是解决常见问题的一种优雅方法。本文将介绍Kotlin中的代理模式&#xff08;Proxy Pattern&#xff09;&#xff0c;其应用场景&#xff0c;以及如何通过实例代码实现这一模式。 代理模式的目的 代理…

【软考高项】- 2024.05月成绩查询

查询地址&#xff1a;全国计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试 考试批次&#xff1a;2024.05.26 第二批&#xff08;论文&#xff1a;成本管理&#xff09; 我的分数&#xff1a; 结论&#xff1a;未通过本次考试&#xff0c;2025.05 继续努力&…

判断对象是否为空的多种方式

判断对象是否为空 网上也有许多方法&#xff0c;这里来整理一下 一、Object.keys(obj) ES6 写法&#xff1a; const data {}; const arr Object.keys(data); console.log(arr.length); // 0二、JSON.stringify() const obj {}; const arr JSON.stringify(obj); console.…

基本工资8000,三班倒轮班,有点辛苦,技术含量高,但越老越吃香的工作工资待遇分享...

技术员的逆袭&#xff1a;数控技术员的职场升级攻略 引言 在职场这片星辰大海中&#xff0c;有一群默默耕耘的技术员&#xff0c;他们用双手和智慧&#xff0c;雕刻着工业的明天。数控技术员&#xff0c;一个听起来就充满机械感和科技感的职业&#xff0c;他们的故事&#xff0…

05-java基础——循环习题

循环的选择&#xff1a;知道循环的次数或者知道循环的范围就使用for循环&#xff0c;其次再使用while循环 猜数字 程序自动生成一个1-100之间的随机数&#xff0c;在代码中使用键盘录入去猜出这个数字是多少&#xff1f; 要求&#xff1a;使用循环猜&#xff0c;一直猜中为止…

Linux[高级管理]——Squid代理服务器的部署和应用(传统模式详解)

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f468;‍&#x1f4bb;Linux高级管理专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月24日11点11分 &#x1f004;️文章质量&#xff1a;95分 目录 ————前言———— Squid功能 Squ…

Lobe Chat openai claude

claude-3-5-sonnet-20240620 $ docker run -d -p 3210:3210 \-e OPENAI_API_KEYsk-xxxx \-e OPENAI_PROXY_URLhttps://api-proxy.com/v1 \-e ACCESS_CODElobe66 \--name lobe-chat \lobehub/lobe-chatDocker 部署 更新 docker ps CONTAINER ID IMAGE …

字节跳动联手博通:5nm AI芯片诞生了?

字节跳动联手博通&#xff1a;5nm AI芯片诞生了&#xff1f; 前言 就在6月24日&#xff0c;字节跳动正在与美国博通合作开发一款5纳米工艺的专用集成电路(ASIC) AI处理器。这款芯片旨在降低采购成本并确保高端AI芯片的稳定供应。 根据报道&#xff0c;尽管芯片设计工作进展顺利…

使用 frida hook Android app

Frida&#xff1a; 一种基于动态插装&#xff08;dynamic instrumentation&#xff09;技术的工具包&#xff0c;它主要是为测试人员、开发人员和逆向工程爱好者创建&#xff0c;在目标程序运行时&#xff0c;允许用户将 JavaScript代码注入其中&#xff0c;实现动态修改和调试…

如何恢复Excel保存前的数据?分享5个实用技巧!

在数字化时代&#xff0c;Excel表格已经成为我们工作生活中不可或缺的一部分。然而&#xff0c;随着数据的日益增多&#xff0c;误操作或系统崩溃导致的数据丢失问题也日益突出。但你知道吗&#xff1f;数据其实并没有真正消失&#xff0c;它们只是被隐藏在了电脑深处的某个角落…

手机卡顿反应慢怎么解决?4个实用技巧,轻松提升运行速度

当你的手机变得像一只蜗牛一样缓慢&#xff0c;每一个滑动、每一次点击都充满了无尽的等待&#xff0c;是不是让你感到无比沮丧&#xff1f;别担心&#xff0c;你并不孤单。手机卡顿、反应慢是许多用户都会遇到的问题。那么&#xff0c;手机卡顿反应慢怎么解决呢&#xff1f;本…

智慧仓储的秘密武器:数据可视化的应用

智慧仓储中数据可视化是如何应用的&#xff1f;在现代物流和供应链管理中&#xff0c;智慧仓储已成为企业提升效率、降低成本和优化运营的重要手段。而数据可视化作为智慧仓储的重要工具&#xff0c;通过将复杂的数据转化为直观、易理解的图表和图形&#xff0c;极大地提升了仓…

VOSviewer分析知网文献

VOSviewer简介 VOSviewer 是一款用于构建和可视化科学文献计量网络的软件工具。它能够帮助用户分析和可视化期刊、研究人员或单个出版物之间的关系&#xff0c;这些关系可以基于引用、共引、共著或术语共现关系来构建。VOSviewer 还提供了文本挖掘功能&#xff0c;可以用来构建…

uni-app系列:uni.navigateTo传值跳转

文章目录 1. 使用URL参数2. 使用页面栈注意事项&#xff1a;uni.navigateTo API 参数详细说明回调函数参数 在uni-app中&#xff0c;如果想要通过uni.navigateTo方法跳转到另一个页面并传递参数&#xff0c;可以使用页面路由的URL参数或者页面栈的方式来传递。但是&#xff0c;…

eNSP中静态NAT和动态NAT的配置和使用

一、静态NAT 1.拓扑图 a.新建拓扑图 b.PC端配置 PC1: PC2&#xff1a; c.路由器配置 AR1: <Huawei>system-view [Huawei]sysname R1 [R1]interface GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 192.168.1.254 24 [R1-GigabitEthernet0/0/0]quit…

Arduino 旋转编码器

Arduino 旋转编码器 电位计 Arduino - Rotary Encoder In this tutorial, we are going to learn how to use the incremental encoder with Arduino. In detail, we will learn: 在本教程中&#xff0c;我们将学习如何将增量编码器与Arduino一起使用。详细来说&#xff0c;…