Frida Hook Java 层

Frida两种启动方式的区别

  1. span 模式:frida 重新打开一个进程

    frida -U -f 包名 -l js路径 --no-pause
  2. attch 模式: 附加在当前打开的进程

    frida -U -l js路径 --no-pause

    区别就是一个带 -f 一个不带

命令行参数详解

  --version             显示版本号
-h, --help 查看帮助
-D ID, --device=ID 用给定的ID连接到设备
-U, --usb 连接 USB 设备
-R, --remote 连接远程设备
-H HOST, --host=HOST 连接远程的设备 地址
-f FILE, --file=FILE spawn FILE 模式
-F, --attach-frontmost
attach to frontmost application 附加到最前端的应用程序
-n NAME, --attach-name=NAME
attach to NAME 附加的名称
-p PID, --attach-pid=PID
attach to PID 附加的进程ID
--stdio=inherit|pipe stdio behavior when spawning (defaults to “inherit”)
--runtime=duk|v8 script runtime to use (defaults to “duk”) 指定js解释器 duk 或者 v8
--debug enable the Node.js compatible script debugger
-l SCRIPT, --load=SCRIPT 加载脚本文件
load SCRIPT
-P PARAMETERS_JSON, --parameters=PARAMETERS_JSON
Parameters as JSON, same as Gadget
-C CMODULE, --cmodule=CMODULE
load CMODULE
-c CODESHARE_URI, --codeshare=CODESHARE_URI
load CODESHARE_URI
-e CODE, --eval=CODE evaluate CODE
-q quiet mode (no prompt) and quit after -l and -e
--no-pause automatically start main thread after startup 启动后自动启动主线程
-o LOGFILE, --output=LOGFILE 日志输出文件
output to log file
--exit-on-error exit with code 1 after encountering any exception in
the SCRIPT 异常退出脚本

Hook一个Java层函数

  • Java.use

    功能:

    动态为className生成一个JavaScript包装器;可以通过调用$new()来实例化对象来调用构造函数

    参数: className
  • implementaion

    功能: 方法重新实现的属性
  • overloads

    功能: 重载函数指定类型方法

示例:

function hook_java() {
// 必须写在 Java 虚拟机中
Java.perform(function() { const login = Java.use('com.example.androiddemo.Activity.LoginActivity');
login.a.overload('java.lang.String', 'java.lang.String').implementation = function(a1, a2) {
let result = this.a(a1, a2);
console.log(a1, a2, result);
return result
}
}) }

修改一个函数返回值或参数

示例:

function hook_java() {
// 必须写在 Java 虚拟机中
Java.perform(function() { const login = Java.use('com.example.androiddemo.Activity.LoginActivity');
const string = Java.use('java.lang.String');
login.a.overload('java.lang.String', 'java.lang.String').implementation = function(a1, a2) {
// string int bool 这3种类型 frida 会直接帮我们转换成 java 类型的
var result = '这是我修改返回的' // 我们自己进行类型转换
var result = string.$new("我们自己去转换的java类型的") return result
}
}) }

调用静态函数和非静态函数

静态函数和静态方法可以使用 Java.use 出来的函数直接调用。Java.use 相当于new了一个新的对象

非静态函数和静态方法,有两种使用情况,一种是 Java.use 出来的对象,自己进行实例化 obj.$new() 这种方法需要知道构造参数,比较麻烦。

那么可以使用 Java.choose 该方法是从内存中找到实例化好的类进行调用

示例:

function hook_java() {
// 必须写在 Java 虚拟机中
Java.perform(function() { // 调用静态方法
var frida_activate = Java.use('com.example.Frida');
frida_activate.setStatic_bool)var() // 调用非静态方法
Java.choose('com.example.androiddemo.Activity.FridaActivity2', {
// 匹配到的情况下,进行调用
// 注意: 内存中可以有多个实例化好的类?
onMatch: function (instance) {
// 调用方法
instance.setBool_var()
// 设置变量值
instance.static_bool_var.value = true;
},
onComplete: function () { }
}) }) }

设置成员变量

设置和函数名相同的成员变量

属性和函数名重名了,需要在属性前面 加一个 下划线 _

示例:

function hook_java() {
// 必须写在 Java 虚拟机中
Java.choose('com.example.androiddemo.Activity.FridaActivity3', {
onMatch: function (instance) {
// instance.static_bool_var.value = true;
instance.bool_var.value = true;
// TODO 关注一下这个属性,他跟函数名重名了,需要加一个 _ 下划线
instance._same_name_bool_var.value = true;
console.log(instance.bool_var.value, instance._same_name_bool_var.value)
},
onComplete: function () { }
}) }

Hook内部类,枚举类的函数

示例:

function call_frida4() {
// hook 类的多个函数, 内部类
Java.perform(function () {
// 这是hook类的 内部类
const FridaActivity4 = Java.use('com.example.androiddemo.Activity.FridaActivity4$InnerClasses');
// getDeclaredMethods 获取当前类的方法 getMethods 获取当前类以及继承类的所有方法
const methods = FridaActivity4.class.getDeclaredMethods();
for (let method of methods) {
// console.log(method)
let method_str = method.toString();
let mtdsplit = method_str.split('.')
let meds = mtdsplit[mtdsplit.length - 1].replace('()', '');
console.log(meds)
FridaActivity4[meds].implementation = function () {
return true
}
} })
}

查找接口,Hook动态加载dex

示例:

function call_frida5() {

    // hook 动态加载的dex 类, 以及查看类的类名

    Java.perform(function () {

        // 1. 尝试 hook 一下 接口类
// 会提示 Error: java.lang.ClassNotFoundException:
// Java.use('com.example.androiddemo.Dynamic.AbstractC0000CheckInterface'); // 2. 查看动态加载的类名
const FridaActivity5 = Java.use('com.example.androiddemo.Activity.FridaActivity5');
FridaActivity5.getDynamicDexCheck.implementation = function () { let result = this.getDynamicDexCheck();
// 查看当前返回值的 类名
console.log(result.$className)
return result } // 这个时候还是 没有找到类 需要将 类 loader 进来
// Java.use('com.example.androiddemo.Dynamic.DynamicCheck').check.implementation = function (){
// return true
// } // 3. hook 动态加载的 dex
// 枚举类加载
Java.enumerateClassLoaders({
onMatch: function (loader) {
console.log(loader)
try {
if (loader.findClass('com.example.androiddemo.Dynamic.DynamicCheck')) {
console.log(loader);
// 切换classloader
Java.classFactory.loader = loader
}
} catch (e) {
// console.log(e) } },
onComplete: function () { }
})
// 这个时候再来 hook 这个类
Java.use('com.example.androiddemo.Dynamic.DynamicCheck').check.implementation = function () {
return true
} })
}

枚举class

示例:


function call_frida6() { // hook 多个 class
// 发现一个关键点 就是 当一个类 没有执行的时候, frida 枚举是枚举不出来的。
Java.perform(function () {
// 遍历当前 loader 的 所有类
Java.enumerateLoadedClasses({
onMatch: function (name, handle) {
// console.log(name)
if (name.indexOf('com.example.androiddemo.Activity.Frida6') >= 0) {
console.log(name);
Java.use(name).check.implementation = function () {
return true;
} }
},
onComplete: function () { }
}) })
}

Hook 构造函数

$init 表示构造函数

示例:


function call_frida6() { Java.perform(function () {
// $init 表示构造函数
Java.use('com.example.androiddemo.Dynamic.DynamicCheck').$init.implementation = function (a,b) {
return this.$init(a,b)
} })
}

打印调用栈

示例:


function show_stack() {
Java.perform(function () {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new())); })
}

加载本地DEX

// 打开 dex 文件
var dex = Java.openClassFile('/data/local/tmp/ddex.dex')
Java.perform(function () {
// 加载 dex
dex.load()
// 进行hook
Java.use('com.tlamb96.kgbmessenger.LoginActivity').j.implementation = function () {
return true
} })

Frida高级逆向-Hook Java的更多相关文章

  1. Frida高级逆向-Hook Native(Java So)

    Frida Hook Native Frida Hook Java Jni demo: function hook_java() { Java.perform(function () { const ...

  2. Frida高级逆向-Hook Native(Java So)2

    Frida Hook So 一些操作说明 Native方法第一个参数是 JNIEnv *env 如何在Frida中获取 JNIEnv 对象呢? Java.vm.getEnv(); 如何将string类 ...

  3. frida的用法--Hook Java代码篇

    frida是一款方便并且易用的跨平台Hook工具,使用它不仅可以Hook Java写的应用程序,而且还可以Hook原生的应用程序. 1. 准备 frida分客户端环境和服务端环境.在客户端我们可以编写 ...

  4. Hook Java API以获得MD5加密前数据

    Java实现MD5加密 在Java中,我们用MD5对数据进行加密,代码大概是这样的: import java.security.MessageDigest; import java.security. ...

  5. Android进程so注入Hook java方法

    本文博客链接:http://blog.csdn.net/qq1084283172/article/details/53769331 Andorid的Hook方式比较多,现在来学习下,基于Android ...

  6. JAVA高级之路----JAVA多线程

    介绍 这段时间一直在学习和整理一些通往java高级程序猿必备的知识点,有些是工作中必须要知道的,有些是面试必须要知道的, 但是不管怎么样,学习了就不会有坏处,不可能全部记得住,最起码得雁过留痕,知识不 ...

  7. 数据结构与算法——常用高级数据结构及其Java实现

    前文 数据结构与算法--常用数据结构及其Java实现 总结了基本的数据结构,类似的,本文准备总结一下一些常见的高级的数据结构及其常见算法和对应的Java实现以及应用场景,务求理论与实践一步到位. 跳跃 ...

  8. Java高级--Java线程运行栈信息的获取 getStackTrace()

    我们在Java程序中使用日志功能(JDK Log或者Log4J)的时候,会发现Log系统会自动帮我们打印出丰富的信息,格式一般如下:为了免去解析StackTrace字符串的麻烦,JDK1.4引入了一个 ...

  9. mysql逆向生成 java 实体类

    import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; import java.sql.Connecti ...

随机推荐

  1. MySQL-基础-2

    MySQL数据库介绍 • MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理. • MySQL的历 ...

  2. Python安装环境配置和多版本共存

    Python安装环境配置和多版本共存 1.环境变量配置: (1) 右键点击"计算机",然后点击"属性" (2) 然后点击"高级系统设置" ( ...

  3. 超实用的idea技巧,windows技巧,用于节省时间!

    进去https://zhangjzm.gitee.io/self_study 找平常积累,或者其它的

  4. android kotlin 子线程中调用界面UI组件崩溃

    UI 只能在主线程内更新,子线程需要更新UI组件时可以这样: fun fuck(){ Executors.newSingleThreadExecutor().execute{ // url reque ...

  5. Docker容器管理——Docker容器常用命令

    1.查看所有的容器 docker ps 2.查看运行的容器 docker ps -a 3.启动.停止.重启docker容器 docker start ... docker stop ... docke ...

  6. Linux下cat命令的使用

    1.普通用法-->查看文件内容 cat file_name 查看文件时的相关参数: 1.cat f1.txt,查看f1.txt文件的内容. 2.cat -n f1.txt,查看f1.txt文件的 ...

  7. shell循环之跳出循环

    1.break break命令允许跳出所有循环(终止执行后面的所有循环). 下面的例子中,脚本进入死循环直至用户输入数字大于5.要跳出这个循环,返回到shell提示符下,需要使用break命令. #! ...

  8. MFGTool2 的使用

    环境 宿主机平台:Ubuntu 16.04.6 目标机:iMX6ULL开发板 MFGTool 2.7 参考:https://www.cnblogs.com/helloworldtoyou/p/6053 ...

  9. 浅析mybatis中${}和#{}取值区别

    mybatis作为一个轻量级的ORM框架,应用广泛,其上手使用也比较简单:一个成熟的框架,必然有精巧的设计,值得学习. 在使用mybatis框架时,在sql语句中获取传入的参数有如下两种方式: ${p ...

  10. k8s garbage collector分析(1)-启动分析

    k8s garbage collector分析(1)-启动分析 garbage collector介绍 Kubernetes garbage collector即垃圾收集器,存在于kube-contr ...