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

这里用到的工具及环境有

  1. BurpSuite,

  2. HTTPDecrypt(https://github.com/lyxhh/lxhToolHTTPDecrypt),

  3. Python3。

注意这个地方环境变成了python3,对应的Frida和frida-tools要重新安装。

拿到一个新的app之后,总会有一段懵逼

Frida—HOOK 学习笔记1相关推荐

  1. Frida—HOOK 学习笔记2

    Android部分 基础知识 1)安卓分层 简单提一下安卓分层,这个点知道了更好,不知道也无所谓.毕竟我们不是开发,只是为了避免下述情况: 我要学习so文件HOOK.一波百度 "HOOK s ...

  2. PC微信hook学习笔记(一)—— 获取个人信息

    PC微信hook学习笔记(一)-- 获取微信个人信息 1 起步 2. 获取基址 2.1 用CE查看个人信息 2.1.1 获取昵称基址 2.1.2 dll模块基址 2.2 用OD查看个人信息 2.3 内 ...

  3. Angular ngOnChanges hook学习笔记

    只有这三种事件才会导致Angular视图的更新,都是异步事件. Events:如 click, change, input, submit 等用户事件 XMLHttpRequests:比如从远端服务获 ...

  4. HOOK学习笔记与心得

    一.  Hook介绍 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理 ...

  5. css view a if属性,uni-app学习笔记(2)view属性控制css样式

    uni-app学习笔记(2)view属性控制css样式 uniapp通过标签属性来改变样式 当鼠标按下去的时候,他会变成这个样式 hover-class="box-active" ...

  6. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  7. java获取内存基址_安卓逆向|菜鸟的FRIDA学习笔记:内存读写

    假设你的手机已经root,并已开启frida服务,电脑端已安装好Python,frida,IDA,GDA. 样本地址: 链接: https://pan.baidu.com/s/1y3kIXcBv25Q ...

  8. Windows驱动开发学习笔记(六)—— Inline HOOK

    Windows驱动开发学习笔记(六)-- Inline HOOK SSDT HOOK Inline Hook 挂钩 执行流程 脱钩 实验一:3环 Inline Hook 实验二:0环 Inline H ...

  9. Windows驱动开发学习笔记(五)—— SSDT HOOK

    Windows驱动开发学习笔记(五)-- SSDT HOOK 系统服务表 系统服务描述符表 实验一:通过代码获取SSDT表地址 通过页表基址修改页属性 方法1:修改页属性 方法2:修改CR0寄存器 实 ...

最新文章

  1. js面试必考:this
  2. 【错误记录】VMware 虚拟机报错 ( 向 VMWare 虚拟机中的 Ubuntu 系统拷贝文件时磁盘空间不足 )
  3. hgameweek4 secret
  4. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16
  5. axios关于针对请求时长策略设计的思考
  6. 使用Automake和Autoconf生成Makefile
  7. springboot 闪退。falling back to default profiles: default StandardService - Stopping service [Tomcat]
  8. Java并发编程之并发容器ConcurrentHashMap(JDK1.8)解析
  9. python提交事务_事务提交和回滚
  10. JQuery动画之淡入淡出动画
  11. iphone桌面上的圆圈怎么设置_iPhone的备忘录如何排序?什么便签可以更改排列展示顺序...
  12. 给创业前的你4点建议
  13. deepnode处理过的图片_微信图文排版用什么软件?文章图片大小不一样排版不齐怎么办?...
  14. .vue文件怎么使用_师父给了我一个 .proto 文件,我应该怎么使用?
  15. flask和ajax实现前后端交互
  16. 乌班图 修改ip_unbuntu(乌班图)虚拟机修改ip地址NAT模式
  17. 微带线等效电感电容效果
  18. unity 接 steam,获取steamID ,username
  19. 台式计算机怎么把声音输出,台式电脑音频管理器的设置教程 台式电脑音响没声音怎么弄...
  20. css 响应式布局(媒体查询),兼容pc,ipad,移动端的布局单位

热门文章

  1. 工业数据分析技术与实战之设备管理——昆仑数据田春华培训听课记录
  2. 老板挖个鱼塘,让用户免费钓鱼,结果所有人都惊呆了……
  3. 分组取最新的一条数据
  4. Apache Hadoop 基础设施容器化在 Uber 的实践
  5. 【HISI系列】之开发板调试基本知识
  6. 越读越有味的句子 绝对经典语录 人生感悟格言(转)
  7. SAP S4 MM配置详解之一:全局设置-定义国家/货币汇率/计量单位/工厂日历
  8. 可伸缩性和重/轻量,谁是实用系统的架构主选
  9. 在阿里做了2个月后,我选择了裸辞···
  10. 触摸屏原理及程序框架