Frida—HOOK 学习笔记1
JAVA层HOOK
在开始之前,依旧是熟悉的工具官方文档。因本人英文水平不高,大佬们可通过官网(https://frida.re/docs/home/)或看雪(https://bbs.pediy.com/thread-222729.htm)自取准确说明文档观看。
1.JAVA方法基础
Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
在Java中方法有一个的样子;
修饰符:告诉编译器如何调用该方法。定义了该方法的访问类型。
返回值类型:就是功能结果的数据类型。当这个方法没有返回值的时候,返回值的类型为void;当这个方法有返回值的时候,返回值的类型根据返回的数据来确定*(如果有返回值,必须使用return)**。*
方法名:符合命名规则即可。
参数:实际参数:就是实际参与运算的。形式参数;就是方法定义上的,用于接收实际参数的。
参数类型:就是参数的数据类型
参数名:就是变量名
方法体语句:就是完成功能的代码。
return*:结束方法的。*
返回值:就是功能的结果,由return带给调用者。
在知晓基本的Java方法结构后,开始本处的重点之一。
1) 普通方法
定义:简单的说方法就是完成特定功能的代码块。
普通方法分为:有明确返回值的方法和没有明确返回值的方法。
A.有明确返回值的方法的调用
可以单独调用、输出调用、赋值调用。
B.没有明确返回值的方法调用(void类型方法的调用)
只能单独使用。
举个简单的例子:
public class Fangfa {// 主方法public static void main(String args[]) {System.out.println(add(10,20));}//返回两个整数相加public static int add(int a , int b){return a + b ;}}
通过例子可以发现,普通方法就是我们写的最常见、最大众化的。满足方法基本结构。
2) 构造方法
构造方法是类的一种特殊方法,用来初始化类的一个新的对象,在创建对象(new 运算符)之后自动调用。Java 中的每个类都有一个默认的构造方法,并且可以有一个以上的构造方法。
构造方法需满足条件:
1、方法名与类名同名。
2、在方法中不能使用return 语句返回即为该方法没有任何返回值,包括 void。
3、在方法名的前面没有返回值的类型声明
通过上述条件可发现,构造方法会在普通的方法结构上发生一些变化,举个例子:
public class Constructor {// 给Constructor类定义了一个成员变量nameprivate String name;// 无参构造方法,方法名必须跟类名一致,即首字母需要大写public Constructor() {System.out.println("调用无参数的构造方法。。");}// 带一个参数的构造方法public Constructor(String name) {// 通过this()调用无参构造方法this();this.name = name;// 构造方法里可以调用普通方法commonMethod();}public void commonMethod() {System.out.println("调用普通方法");}// 写个主函数测试一下public static void main(String[] args) {// 通过无参构造创建一个Constructor对象Constructor cons1 = new Constructor();cons1.name = "我是通过无参构造器创建的对象";System.out.println(cons1);System.out.println("=====================我是分隔线=====================");// 通过有参构造方法创建另一个对象Constructor cons2 = new Constructor("我是通过有参构造方法创建的对象");System.out.println(cons2);}public String toString() {return this.getClass().getSimpleName() + "[我的名字是:" + name + "]";}}
运行结果如下:
3) 重载方法
重载方法(Overloading)的定义:如果有两个方法的方法名相同,但参数不一致,哪么可以说一个方法是另一个方法的重载。 具体满足条件包括:
- 方法名相同
- 方法的参数类型,参数个不一样
- 方法的返回类型可以不相同
- 方法的修饰符可以不相同
- main 方法也可以被重载
举个例子:
class MyClass {int height;MyClass() {System.out.println("无参数构造函数");height = 4;}MyClass(int i) {System.out.println("房子高度为 " + i + " 米");height = i;}void info() {System.out.println("房子高度为 " + height + " 米");}void info(String s) {System.out.println(s + ": 房子高度为 " + height + " 米");}}public class MainClass {public static void main(String[] args) {MyClass t = new MyClass(3);t.info();t.info("重载方法");//重载构造函数new MyClass();}
}
程序执行结果如下:
2.Frida安装
对于安装这部分,大家可在互联网自行搜索安装。个人建议是使用python2的旧版本,因为在burp中有一个brida工具来帮助使用Frida。Brida的使用可参考下述文章(https://blog.csdn.net/weixin_39190897/article/details/102691898),网络上存在说python3也可使用该工具,不过本人尝试后未成功。
在安装Frida时要主要参考最新安装教程所涉及的Frida及frida-tools的版本,直接使用pip进行安装存在frida安装最新版可以成功,但是安装frida-tools时则会报错。
3.普通方法HOOK
针对普通方法、构造方法、重载方法可使用APP安装包:方法hook.app
安装并启动APP:
此处插入一个题外话,大佬们是不是看见一个可爱的群号呀,是不是想去搜一下呀。我替大家搜过了,知道了结果也就不打码了。结果是这个样子滴:
看到这个结果是不是可以放下手机了???
言归正传,发现APP在启动后弹出3000,点击普通方法弹出4000。
使用JADX等反编译工具对APP进行反编译操作,获取到源码。
在安卓源码中存在文件AndroidManifest.xml,在这个文件内可寻找到中找到app的入口地址。访问MainActivity,其代码如下:
通过代码可看出应用在运行后执行了一个onCreate方法,方法中包含一个方法为getCalc。这部分主要是写了三个按键的事件和监听,在方法最后一行出现了和按键无关的数字1000,2000。这个时候还记得应用运行时的弹出的3000吗?
本节是使用Frida对普通函数进行hook,在app界面对应为按钮1(button1),对于按键的响应事件被定义在onClick方法里,效果为点击button1后弹出一个文本。在代码中的关键方法为Utils.getCalc,这也是要hook的关键。在查看该方法的代码:
发现该方法为简单的加法运算。启动firda对该函数进行hook。需要编写一个脚本来进行操作,具体代码这么写呢?不要着急,frida官网给出了脚本的模版(https://frida.re/docs/examples/android/)通过本例写出的脚本,告诉大家每部分是干嘛的。
frida的hook代码如下:
import frida, sys //导入脚本所需的包jscode = """ //hook主要执行的代码区域Java.perform(function () {//hook核心代码包含在Java.perform函数之中。 var util = Java.use('com.xiaojianbang.app.Utils');//此处com.xiaojianbang.app.Utils为将要hook的方法所处的类的路径。 util.getCalc.implementation = function (a, b) { // getCalc为在获取类路径后将要hook方法名。在这里更改类的方法的实现(implementation)console.log("Hook Start..."); send(a);send(b);send("Success!");return this.getCalc(a,b)//以上三行为hook代码的执行代码。} }); """ def message(message, data): if message["type"] == 'send': print("[] {0}".format(message['payload'])) else: print(message) process = frida.get_remote_device().attach('com.xiaojianbang.app') //利用Frida包中函数对要hook的app包名创建一个进程 script= process.create_script(jscode) script.on("message", message) script.load() sys.stdin.read()
对代码了解之后可发现只需对标红处代码进更改即可。编写的重点在于执行代码处。对于代码标绿处有如图两种情况:
代码正常执行后结果为:
将执行代码进行如下修改:
执行结果如下:
通过以上执行结果发现传入的100,300成功的进行了加运算。说明对该函数成功进行了hook。
本节所涉及代码框架应用于全文,建议大家理解普通方法的hook脚本后继续向下。后文代码将以hook处理代码为主。
4.构造方法HOOK
本节利用上节APP进行构造方法hook,对应功能为button2,点击后效果如下:
按键代码如下:
查看代码中关键方法Utils.getMoney。
发现getMoney方法内存在一个new的实例化方法Money,查看该方法的代码。根据最开始对Java方法的基础学习发现这个方法符合构造方法的特征。
要hook这个函数,依据上节的经验开始编写:
正常的写代码到这个位置了,但是这时突然想起构造方法名是不是和类名一模一样的。那就没有必要在这个地方再写方法名称。这个时候拿出了一个固定写法为$init。将上述代码改为:
代码执行结果如下:
出现上述结果说明hook成功了,但是要利用工具对我们输入的值进行操作,可将代码改写为:
执行代码之后,app的执行结果应为下图所示,说明hook并成功利用了方法。
5.重载方法HOOK
本节进入重载的hook,事件绑定在button3。其按键监听代码为:
代码中关键方法为Utils.test。查看其代码:
发现有两个方法都叫test,根据掌握的知识,这两个方法互为重载。对该函数进行hook。根据上面两节的经验在进行更改类的实现的时候,会有一个疑惑:两个方法名字一样,代码如何去选择?这个地方引入一个overload(),该方法()填写内容为hook方法的参数的类型,空参时该括号内容也为空。例如:overload(“int”)
hook的测试代码为:
执行结果如下:
通过上述过程,脚本在hook同名方法时,只需在overload()中将参数的类型依次填入。在遇到string类型的参数时,应填写为:Java.lang.String,因为string是Java提供用来来创建和操作字符串的类。
6. 函数参数类型表示
不同的参数类型都有自己的表示方法
对于基本类型,直接用它在Java中的表示方法就可以了,不用改变,例如:
· int
· short
· char
· byte
· boolean
· float
· double
· long
基本类型数组,用左中括号接上基本类型的缩写
基本类型缩写表示表:
基本类型 | 缩写 |
---|---|
boolean | Z |
byte | B |
char | C |
double | D |
float | F |
int | I |
long | J |
short | S |
例如:int[]类型,在重载时要写成[I
任意类,直接写完整类名即可
例如:java.lang.String
对象数组,用左中括号接上完整类名再接上分号
例如:[java.lang.String;
1) 带参数的构造函数
修改参数为byte[]类型的构造函数的实现
ClassName.$init.overload('[B').implementation=function(param){//do something}
注:ClassName是使用Java.use定义的类;param是可以在函数体中访问的参数
修改多参数的构造函数的实现
ClassName.$init.overload('[B','int','int').implementation=function(param1,param2,param3){//do something}
2) 无参数构造函数
ClassName.$init.overload().implementation=function(){//do something}
调用原构造函数
ClassName.$init.overload().implementation=function(){//do somethingthis.$init();//do something}
注意:当构造函数(函数)有多种重载形式,比如一个类中有两个形式的func:void func()和void func(int),要加上overload来对函数进行重载,否则可以省略overload
3) 一般函数
修改函数名为func,参数为byte[]类型的函数的实现
ClassName.func.overload('[B').implementation=function(param){//do something//return ...}
4) 无参数的函数
ClassName.func.overload().implementation=function(){//do something}
注: 在修改函数实现时,如果原函数有返回值,那么我们在实现时也要返回合适的值
ClassName.func.overload().implementation=function(){//do somethingreturn this.func();}
7. 构造对象参数HOOK
本节进入重载的hook,事件绑定在button4。执行效果为:
其按键监听代码为:
发现关键方法test中传入了一个对象。查看关键函数代码:
对比三个test方法,发现最后一个test的参数为一个对象还是一个重载。
按照重载方法hook的方式,我们可以编写代码:
var utils = Java.use('com.xiaojianbang.app.Utils');utils.test.overload().implementation = function (a) 但是因为本次传入的内容是个人定义的内容。overload方法这里填写内容这个时候可参考string的传入。我们将overload内容要求变成传入方法的全路径。utils.test.overload('com.xiaojianbang.app.Money').implementation
代码整理后为:
运行结果如下:
这个时候在输出中文时会出现如下报错:
解决办法是:
但是本节的结果是构造对象参数,将随机输入的参数利用hook函数进行处理。操作代码如下;
jscode = """Java.perform(function () {var utils = Java.use('com.xiaojianbang.app.Utils');var money = Java.use('com.xiaojianbang.app.Money');//上述两行是将hook方法中涉及的方法所在类导入utils.test.overload('com.xiaojianbang.app.Money').implementation = function (a) {send("Hook Start...");send(a.getInfo());//利用hook方法内方式进行输出,简单就是将money这个参数值标示变成了avar mon = money.$new(2000,'gangyuan');//因为test内输入参数所利用的Money为构造函数,在使用时需利用$new进行实例化使用,可当一个通用方式来写。send(mon.getInfo());return this.test(mon);}});"""
执行结果如下,说明我们成功对目标方法进行了hook,并修改了传入值。
8. 实例
在渗透测试过程中常会遇到数据包加密的情况。如下APP
用户登陆数据如下:
针对数据包提示信息在源码中进行搜索。
或者依据数据包提示接口位置进行搜索,在代码附近找寻加密方式。各位大佬也可以用自己习惯的方式去找寻。
通过搜索关键字等方式,是为找到代码中执行加密的部分:
我们发现传输的内容经过RequestUtil.encodeDesMap进行了处理。处理的数据内容为addMap,数据传输流程如下:
1.函数接受输入参数发送,在login方法流程最后调用了requesNetwork方法。
2.requestNetwork方法中para2接受的参数一路传递至addRequestMap。
加密流程至加密处理时要加密内容进入到addMap。故获取encodeDesMap相关信息。
RequestUtil.paraMap相关信息如下:
按上文获取到加密代码,目前可确定将要HOOK内容为paraMap:
在查看处理代码时发现paraMap处理的内容为Map集合,直接HOOK该处内容为Map集合,涉及到字符串的拼接等不便于数据展示。在该方法的代码中可发现Utils.md5方法,该方法对拼接后的数据进行了处理:
此处HOOK结果如下:
我们对encodeDesMap进行HOOK可获取到加密后的结果。
9. 工具使用HOOK
这里用到的工具及环境有
BurpSuite,
HTTPDecrypt(https://github.com/lyxhh/lxhToolHTTPDecrypt),
Python3。
注意这个地方环境变成了python3,对应的Frida和frida-tools要重新安装。
拿到一个新的app之后,总会有一段懵逼
Frida—HOOK 学习笔记1相关推荐
- Frida—HOOK 学习笔记2
Android部分 基础知识 1)安卓分层 简单提一下安卓分层,这个点知道了更好,不知道也无所谓.毕竟我们不是开发,只是为了避免下述情况: 我要学习so文件HOOK.一波百度 "HOOK s ...
- PC微信hook学习笔记(一)—— 获取个人信息
PC微信hook学习笔记(一)-- 获取微信个人信息 1 起步 2. 获取基址 2.1 用CE查看个人信息 2.1.1 获取昵称基址 2.1.2 dll模块基址 2.2 用OD查看个人信息 2.3 内 ...
- Angular ngOnChanges hook学习笔记
只有这三种事件才会导致Angular视图的更新,都是异步事件. Events:如 click, change, input, submit 等用户事件 XMLHttpRequests:比如从远端服务获 ...
- HOOK学习笔记与心得
一. Hook介绍 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理 ...
- css view a if属性,uni-app学习笔记(2)view属性控制css样式
uni-app学习笔记(2)view属性控制css样式 uniapp通过标签属性来改变样式 当鼠标按下去的时候,他会变成这个样式 hover-class="box-active" ...
- PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call
您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...
- java获取内存基址_安卓逆向|菜鸟的FRIDA学习笔记:内存读写
假设你的手机已经root,并已开启frida服务,电脑端已安装好Python,frida,IDA,GDA. 样本地址: 链接: https://pan.baidu.com/s/1y3kIXcBv25Q ...
- Windows驱动开发学习笔记(六)—— Inline HOOK
Windows驱动开发学习笔记(六)-- Inline HOOK SSDT HOOK Inline Hook 挂钩 执行流程 脱钩 实验一:3环 Inline Hook 实验二:0环 Inline H ...
- Windows驱动开发学习笔记(五)—— SSDT HOOK
Windows驱动开发学习笔记(五)-- SSDT HOOK 系统服务表 系统服务描述符表 实验一:通过代码获取SSDT表地址 通过页表基址修改页属性 方法1:修改页属性 方法2:修改CR0寄存器 实 ...
最新文章
- js面试必考:this
- 【错误记录】VMware 虚拟机报错 ( 向 VMWare 虚拟机中的 Ubuntu 系统拷贝文件时磁盘空间不足 )
- hgameweek4 secret
- 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16
- axios关于针对请求时长策略设计的思考
- 使用Automake和Autoconf生成Makefile
- springboot 闪退。falling back to default profiles: default StandardService - Stopping service [Tomcat]
- Java并发编程之并发容器ConcurrentHashMap(JDK1.8)解析
- python提交事务_事务提交和回滚
- JQuery动画之淡入淡出动画
- iphone桌面上的圆圈怎么设置_iPhone的备忘录如何排序?什么便签可以更改排列展示顺序...
- 给创业前的你4点建议
- deepnode处理过的图片_微信图文排版用什么软件?文章图片大小不一样排版不齐怎么办?...
- .vue文件怎么使用_师父给了我一个 .proto 文件,我应该怎么使用?
- flask和ajax实现前后端交互
- 乌班图 修改ip_unbuntu(乌班图)虚拟机修改ip地址NAT模式
- 微带线等效电感电容效果
- unity 接 steam,获取steamID ,username
- 台式计算机怎么把声音输出,台式电脑音频管理器的设置教程 台式电脑音响没声音怎么弄...
- css 响应式布局(媒体查询),兼容pc,ipad,移动端的布局单位