首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >安卓Frida Hook基础

安卓Frida Hook基础

作者头像
用户1423082
发布2024-12-31 20:20:59
发布2024-12-31 20:20:59
32900
代码可运行
举报
文章被收录于专栏:giantbranch's bloggiantbranch's blog
运行总次数:0
代码可运行

Frida安装

python虚拟环境安装

代码语言:javascript
代码运行次数:0
运行
复制
pip config --global set global.index-url https://mirrors.cloud.tencent.com/pypi/simple

pip install virtualenvwrapper-win

设置环境变量WORKON_HOME为下面自己建立好的路径,当然默认也可以不设置,默认在用户目录下

代码语言:javascript
代码运行次数:0
运行
复制
C:\WORKON_HOME

新建环境mkvirtualenv fridatest

代码语言:javascript
代码运行次数:0
运行
复制
c新建环境
rmvirtualenv 删除环境

下次打开cmd进入环境

代码语言:javascript
代码运行次数:0
运行
复制
workon fridatest

Frida安装以及多版本处理

代码语言:javascript
代码运行次数:0
运行
复制
pip install frida-tools

Frida-server

代码语言:javascript
代码运行次数:0
运行
复制
(fridatest) C:\Users\PF>pip list
Package           Version
----------------- -------
colorama          0.4.6
frida             16.2.1
frida-tools       12.3.0
pip               24.0
prompt-toolkit    3.0.43
Pygments          2.17.2
setuptools        69.1.0
typing_extensions 4.10.0
wcwidth           0.2.13
wheel             0.42.0

上面frida 是16.2.1,所以也下载16.2.1

解压,push到手机,给执行权限并运行

代码语言:javascript
代码运行次数:0
运行
复制
adb push frida-server-16.2.1-android-arm64 /data/local/tmp

adb shell
su
OnePlus3:/data/local/tmp # chmod +x frida-server-16.2.1-android-arm64
OnePlus3:/data/local/tmp # ./frida-server-16.2.1-android-arm64

自定义端口运行

代码语言:javascript
代码运行次数:0
运行
复制
./frida-server-16.2.1-android-arm64 -l 0.0.0.0:6666

通过在电脑端,执行下面命令,可以看到手机进程说明没问题了

代码语言:javascript
代码运行次数:0
运行
复制
frida-ps -U

Frida基础知识

1.基础指令

1.frida-ps -U 查看当前手机运行的进程 2.frida-ps –help 查看help指令

2.操作模式:

操作模式

描述

优点

主要用途

CLI(命令行)模式

通过命令行直接将JavaScript脚本注入进程中,对进程进行操作

便于直接注入和操作

在较小规模的操作或者需求比较简单的场景中使用

RPC模式

使用Python进行JavaScript脚本的注入工作,实际对进程进行操作的还是JavaScript脚本,可以通过RPC传输给Python脚本来进行复杂数据的处理

在对复杂数据的处理上可以通过RPC传输给Python脚本来进行,有利于减少被注入进程的性能损耗

在大规模调用中更加普遍,特别是对于复杂数据处理的需求

3.注入模式与启动命令

注入模式

描述

命令或参数

优点

主要用途

Spawn模式

将启动App的权利交由Frida来控制,即使目标App已经启动,在使用Frida注入程序时还是会重新启动App

在CLI模式中,Frida通过加上 -f 参数指定包名以spawn模式操作App

适合于需要在App启动时即进行注入的场景,可以在App启动时即捕获其行为

当需要监控App从启动开始的所有行为时使用

Attach模式

在目标App已经启动的情况下,Frida通过ptrace注入程序从而执行Hook的操作

在CLI模式中,如果不添加 -f 参数,则默认会通过attach模式注入App

适合于已经运行的App,不会重新启动App,对用户体验影响较小

在App已经启动,或者我们只关心特定时刻或特定功能的行为时使用

Spawn模式

代码语言:javascript
代码运行次数:0
运行
复制
frida -U -f 包名 -l hook.js

attach模式 :

代码语言:javascript
代码运行次数:0
运行
复制
frida -U 进程名 -l hook.js

logcat |grep "D.zj2595"日志捕获 adb connect 127.0.0.1:62001模拟器端口转发

4. 基础语法

API名称

描述

Java.use(className)

获取指定的Java类并使其在JavaScript代码中可用。

Java.perform(callback)

确保回调函数在Java的主线程上执行。

Java.choose(className, callbacks)

枚举指定类的所有实例。

Java.cast(obj, cls)

将一个Java对象转换成另一个Java类的实例。

Java.enumerateLoadedClasses(callbacks)

枚举进程中已经加载的所有Java类。

Java.enumerateClassLoaders(callbacks)

枚举进程中存在的所有Java类加载器。

Java.enumerateMethods(targetClassMethod)

枚举指定类的所有方法。

5.日志输出语法区别

日志方法

描述

区别

console.log()

使用JavaScript直接进行日志打印

多用于在CLI模式中,console.log()直接输出到命令行界面,使用户可以实时查看。在RPC模式中,console.log()同样输出在命令行,但可能被Python脚本的输出内容掩盖。

send()

Frida的专有方法,用于发送数据或日志到外部Python脚本

多用于RPC模式中,它允许JavaScript脚本发送数据到Python脚本,Python脚本可以进一步处理或记录这些数据。

6.Hook框架模板

代码语言:javascript
代码运行次数:0
运行
复制
function main(){
    Java.perform(function(){
        hookTest1();
    });
}
setImmediate(main);

7.Frida常用API

1.Hook普通方法、打印参数和修改返回值

代码语言:javascript
代码运行次数:0
运行
复制
//定义一个名为hookTest1的函数
function hookTest1(){
	//获取一个名为"类名"的Java类,并将其实例赋值给JavaScript变量utils
    var utils = Java.use("类名");
    //修改"类名"的"method"方法的实现。这个新的实现会接收两个参数(a和b)
    utils.method.implementation = function(a, b){
	    //将参数a和b的值改为123和456。
        a = 123;
        b = 456;
        //调用修改过的"method"方法,并将返回值存储在`retval`变量中
        var retval = this.method(a, b);
        //在控制台上打印参数a,b的值以及"method"方法的返回值
        console.log(a, b, retval);
        //返回"method"方法的返回值
        return retval;
    }
}

实例

代码语言:javascript
代码运行次数:0
运行
复制

//定义一个名为hookTest1的函数
function hookTest1(){
	//获取一个名为"类名"的Java类,并将其实例赋值给JavaScript变量utils
    var utils = Java.use("com.zj.wuaipojie.Demo");
    //修改"类名"的"a"方法的实现。这个新的实现会接收两个参数(a和b)
    utils.a.implementation = function(teststr){
	    //将参数a和b的值改为123和456。
        teststr = "hahaha,frida!";
        //调用修改过的"a"方法,并将返回值存储在`retval`变量中
        var retval = this.a(teststr);
        //在控制台上打印参数a,b的值以及"a"方法的返回值
        console.log(teststr, retval);
        //返回"a"方法的返回值
        return retval;
    }
}

function main(){
    Java.perform(function(){
        hookTest1();
    });
}
setImmediate(main);

hook

代码语言:javascript
代码运行次数:0
运行
复制
frida -U wuaipojie -l hook.js

2.Hook重载参数

代码语言:javascript
代码运行次数:0
运行
复制
// .overload()
// .overload('自定义参数')
// .overload('int')
function hookTest2(){
    var utils = Java.use("com.zj.wuaipojie.Demo");
    //overload定义重载函数,根据函数的参数类型填
    utils.Inner.overload('com.zj.wuaipojie.Demo$Animal','java.lang.String').implementation = function(a, b){
        b = "自定义参数已经被修改";
        this.Inner(a,b);
        console.log(b);
    }
    
}

3.Hook构造函数

代码语言:javascript
代码运行次数:0
运行
复制
function hookTest3(){
    var utils = Java.use("com.zj.wuaipojie.Demo");
    //修改类的构造函数的实现,$init表示构造函数
    utils.$init.overload('java.lang.String').implementation = function(str){
        // 原来的参数
        console.log(str);
        str = "52破解hook33333";
        this.$init(str);
    }
}

4.Hook字段

代码语言:javascript
代码运行次数:0
运行
复制
function hookTest5(){
    Java.perform(function(){
        //静态字段的修改
        var utils = Java.use("com.zj.wuaipojie.Demo");
        //修改类的静态字段"flag"的值
        utils.staticField.value = "我是被修改的静态变量";
        console.log(utils.staticField.value);
        //非静态字段的修改
        //使用`Java.choose()`枚举类的所有实例
        Java.choose("com.zj.wuaipojie.Demo", {
            onMatch: function(obj){
	            //修改实例的非静态字段"_privateInt"的值为"123456",并修改非静态字段"privateInt"的值为9999。
                // obj._privateInt.value = "123456"; //字段名与函数名相同 前面加个下划线
                console.log("here!")
                obj.publicInt.value = 8888;
                obj.privateInt.value = 9999;
                //由于样本代码的原因,需要再主动调用一下Demo类日志输出函数test(),才能在adb的log界面看到输出改变
                obj.test();
                console.log(obj.privateInt.value )
            },
            onComplete: function(){

            }
        });
        
    });
    
}

5.Hook内部类

不过好像不太行,eeeeeeee没有输出

代码语言:javascript
代码运行次数:0
运行
复制
function hookTest6(){
    Java.perform(function(){
        //内部类
        var innerClass = Java.use("com.zj.wuaipojie.Demo$innerClass");
        console.log(innerClass);
        innerClass.$init.implementation = function(){
            console.log("eeeeeeee");
        }

    });
}

6.枚举所有的类与类的所有方法

代码语言:javascript
代码运行次数:0
运行
复制
function hookTest7(){
    Java.perform(function(){
        //枚举所有的类与类的所有方法,异步枚举
        Java.enumerateLoadedClasses({
            onMatch: function(name,handle){
	            //过滤类名
                if(name.indexOf("com.zj.wuaipojie.Demo") !=-1){
                    console.log(name);
                    var clazz =Java.use(name);
                    console.log(clazz);
                    var methods = clazz.class.getDeclaredMethods();
                    console.log(methods);
                }
            },
            onComplete: function(){}
        })
    })
}

7.枚举所有方法

代码语言:javascript
代码运行次数:0
运行
复制
function hookTest8(){
    Java.perform(function(){
        var Demo = Java.use("com.zj.wuaipojie.Demo");
        //getDeclaredMethods枚举所有方法
        var methods =Demo.class.getDeclaredMethods();
        for(var j=0; j < methods.length; j++){
            var methodName = methods[j].getName();
            console.log(methodName);
            for(var k=0; k<Demo[methodName].overloads.length;k++){
                Demo[methodName].overloads[k].implementation = function(){
                    for(var i=0;i<arguments.length;i++){
                        console.log(arguments[i]);
                    }
                    return this[methodName].apply(this,arguments);
                }
            }
        }
    })
}

8.主动调用

静态方法

代码语言:javascript
代码运行次数:0
运行
复制
function hookTest9(){
    Java.perform(function(){
        var ClassName=Java.use("com.zj.wuaipojie.Encode"); 
        var ret = ClassName.encode("aaaaaaaaaaaa");
        console.log(ret);
    })
}

非静态方法

代码语言:javascript
代码运行次数:0
运行
复制
function hookTest10(){
    var ret = null;
    Java.perform(function () {
        Java.choose("com.zj.wuaipojie.Demo",{    //要hook的类
            onMatch:function(instance){
                ret=instance.privateFunc("aaaaaaa"); //要hook的方法
            },
            onComplete:function(){
            	// console.log("result: " + ret);
            }
        });
    })
    //return ret;

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Frida安装
    • python虚拟环境安装
    • Frida安装以及多版本处理
    • Frida-server
  • Frida基础知识
    • 1.基础指令
    • 2.操作模式:
    • 3.注入模式与启动命令
    • 4. 基础语法
    • 5.日志输出语法区别
    • 6.Hook框架模板
    • 7.Frida常用API
      • 1.Hook普通方法、打印参数和修改返回值
      • 2.Hook重载参数
      • 3.Hook构造函数
      • 4.Hook字段
      • 5.Hook内部类
      • 6.枚举所有的类与类的所有方法
      • 7.枚举所有方法
      • 8.主动调用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档