type
status
date
slug
summary
tags
category
icon
password
学习加深一下frida使用能力
使用mac + pixel3真机的环境
  • frida版本16.5.5
  • jadx-gui
  • js代码环境

Java层

1) 0x1

💡
重写MainActivity中主动调用的方法
notion image
如图,从 check 方法入手,其中 i 是 get_random 方法取得随机数,i2 = i * 2 + 4 且 i2是我们需要输入的数字。
那么,我们hook可以至少有两种思路,首先是hookget_random 方法的返回值i,然后计算i * 2 + 4得到i2通过check;还可以把get_random 方法的返回值写死,比如返回0,这样i2固定为4即可。
这是MainActivity中主动调用的函数,可以重新定义这个方法来hook(使用implementation)
模板

exp

获得 i 和 i2
把返回值写死为0

2) 0x2

💡
MainActivity中未被调用的静态方法
notion image
其判定方式为a是否为4919,那么我们把它写死为4919即可
由于这里我们不用重写方法,只需要固定该方法的传入值,因此不用使用implementation,直接调用方法传参

exp

3) 0x3

💡
调用非MainActivity类中的静态变量
先看MainActivity
notion image
这里其实想办法把Checker.code固定为512即可,点进Checker类看
notion image
我们可以发现,code变量是static的,且下面有个increase()方法,那么又可以用两种方法来实现:可以直接hook checker.code,写死为512;也可以调用checker类的increase()方法,使之循环256次让code为512
修改静态变量的模板
这里把两种思路hook都实现

exp

4) 0x4

💡
调用非MainActivity中的非静态方法
notion image
可以看到,这里get_flag方法在Check类中,且不是静态方法,我们想要调用它的话,就需要和java里创建类的对象一样,创建一个类的实例
创建实例并使用模板
知道如何调用了,就需要来分析一下这个代码了,和之前的0x2有点像,把get_flag方法的传参a写死为1337即可

exp

5) 0x5

💡
调用MainActivity中的非静态方法
notion image
可以先分析一手:这是MainAcivity类中的非静态方法,我们需要hook flag() 方法,把code的值写死为1337,让其正常执行try块里的内容。
 
与其他类的非静态方法不一样,不能直接使用.$new()创建实例。
当Android应用程序启动时,系统会创建MainActivity的一个实例(或AndroidManifest.xml文件中指定的启动器活动)。创建MainActivity实例是Android应用程序生命周期的一部分。
所以,我们可以使用frida获取MainActivity的实例。
模板
这里可以分析一下这个模板
两个API
  • Java.performNow:用于在Java运行时环境中执行代码的函数。
  • Java.choose:在运行时枚举指定Java类(作为第一个参数提供)的实例。
两个回调函数
  • onMatch
    • onMatch回调函数在Java.choose操作期间找到指定类的每个实例时执行。
    • 这个回调函数接收当前实例作为它的参数。
    • 您可以在onMatch回调中定义自定义操作,以在每个实例上执行。
    • function(instance) {}instance参数表示目标类的每个匹配实例。您可以使用任何其他名称。
  • onComplete
    • onComplete回调在Java.choose操作完成后执行操作或清理任务。此块是可选的,如果您在搜索完成后不需要执行任何特定操作,则可以选择将其留空。

exp

6) 0x6

💡
调用MainActivity中的非静态方法,变量非静态,无构造方法
notion image
MainActivity中我们可以分析出来,把num1和num2分别固定为1234和4321即可
但是这里的num1和num2是Checker类中的变量,跟进
notion image
根据0x5中的模板来增添

exp

7) 0x7

💡
调用MainActivity中的非静态方法,变量非静态,有构造方法
&&
hook 构造函数
notion image
MainActivity中乍一看和0x6很相似,固定num1和num2即可,但是前面已经创建了一个实例
再看Checker类
notion image
和0x6不一样的是,这里已经为这个类写好了构造方法。
这里我们也有两个思路去解决,首先是利用已有的构造方法,仿照0x6的exp进行解决;再而就是hook构造函数来解决。
这里来说说第二种hook构造函数,我们使用$init关键字来构造方法,再用implementation 关键字,就可以实现了

exp

 

Native层

8) 0x8

💡
Hook Native层中调用的函数并且读取传入的参数
notion image
这里有明显的 loadLibrary 关键字,很明显是调用native层的方法
我们hook的话可以用如下模板:
  • Interceptor.attach:将回调函数附加到指定的函数地址。targetAddress 是我们想要挂钩的本地函数的地址。
  • onEnter:当挂钩的函数被调用时,调用此回调,它提供对函数参数 (args) 的访问。
  • onLeave:当挂钩的函数即将退出时,调用此回调,它提供对返回值 (retval) 的访问。
需要获取targetAddress我们可以方便的使用如下API:
  1. Module.enumerateExports()通过调用 Module.enumerateExports(),我们可以获取到导出函数的名称、地址以及其他相关信息。这些信息对于进行函数挂钩、函数跟踪或者调用其他函数都非常有用
  1. Module.getExportByName()当我们知道要查找的导出项的名称但不知道其地址时,可以使用 Module.getExportByName()。通过提供导出项的名称作为参数,这个函数会返回与该名称对应的导出项的地址
  1. Module.findExportByName()这与 Module.getExportByName() 是一样的。唯一的区别在于,如果未找到导出项,Module.getExportByName() 会引发异常,而 Module.findExportByName() 如果未找到导出项则返回 null
  1. Module.getBaseAddress()通过调用 Module.getBaseAddress() 函数,我们可以获取指定模块的基址地址,然后可以基于这个基址地址进行偏移计算,以定位模块内部的特定函数、变量或者数据结构
  1. Module.enumerateImports()通过调用 Module.enumerateImports() 函数,我们可以获取到指定模块导入的外部函数或变量的名称、地址以及其他相关信息
 
继续分析:
notion image
可以看到,这里调用native层的cmpstr函数
解压apk文件,在lib里面选择arm64的.so文件,用ida打开
notion image
关键函数一眼丁真
不管逻辑的情况下,我们最应该锁定的是strcmp函数,作比较的值,有一个肯定为正确结果
仔细审逻辑的话,也能判断,a3是我们的输入,经过一些格式化操作过后,为s1,与s2进行比较
那么,s1就是我们的输入,s2就是flag
所以我们需要获取导入表的函数相关内容
notion image
可以看到是libc.so里的函数,且地址为0x7216d58500 ,然后我们就可以以此做文章来hook了

exp

hook过后,apk端输入包含字符串“abcd”即可
notion image

9) 0x9

💡
Hook修改native层程序返回值
notion image
很明显check_flag native层调用
notion image
看看native层,发现这个函数的返回值是固定的1,我们要hook进去的话,需要让其返回1337
模板
这个retval,就是我们hook程序的返回值,我们可以使用retval.replace(val)来修改返回值
和8一样,先获取导出表相关内容
notion image

exp

10)0xA

💡
hook native层中未被调用的方法
notion image
MainActivity中加载了JNI 函数,去native层看
notion image
没啥用,也跟进里面的函数找了一圈
在导出函数窗口,能找到与flag相关的函数
notion image
跟进
notion image
很明显,这个函数是获取flag的,而且是运行自解密
如果只是要获取flag的话,直接写脚本就行
但是我们要hook,这个函数是未被调用的
而且这里使用了__android_log_print,hook过后需要在日志里找
直接hook这个函数获得他的地址
notion image
这里发现无法获取到get_flag的地址
notion image
回到汇编窗口,可以看到get_flag的函数名叫做_Z8get_flagii
notion image
然后就可以来hook flag了,先学习一下模板
然后需要关注一下主动调用这个函数时需要传入的参数
notion image
两个int类型数据,且和为3

exp

notion image

11)0xB

💡
修改Native层方法的汇编指令
notion image
经典native,去native看
notion image
空函数啊,很有意思
实则不然,进入控制流界面观察
notion image
这里的B.NE指令是上一条指令结果不为0的话,无条件跳转到loc_1532C去,下面的loc_15250(和flag相关的部分)并没有被识别,因为这里是永假
0xDEADBEEF - 0x539 永远不可能为0
那么我们就需要去patch这段汇编,让他正常进入loc_15250部分即可
直接把B.NE指令这段nop掉就行
notion image
这条指令的偏移为0x15248
如何用frida实现呢?
又学习一下模版

exp

notion image
Frida学习某次元app分析
Loading...
Sh4d0w
Sh4d0w
漫长学习路ing
最新发布
360加固复现学习
2025-6-15
java反射机制
2025-6-14
classLoader机制
2025-6-14
dex文件结构
2025-6-14
APP启动流程
2025-6-14
JNI学习
2025-6-14
公告
Welcome to Sh4dw’s blog!
敬请指导,Q 467194403