17.安卓逆向-frida基础-调试实战1(有 spawn 模式实例)

server/2024/12/22 1:39:19/

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

内容参考于:图灵Python学院

本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要盲目相信。

工具下载:

链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3

提取码:6tw3

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:16.安卓逆向-frida基础-HOOK类方法2

然后接着继续Frida HOOK,现在的技术的叫Frida调试,Frida调试原理就是把所有方法全部HOOK然后逐个分析

首先连接adb shell,然后运行frida server(f14)

HOOK排序算法

有的app它会把参数进行一个封装(整合)丢到一个算法里去加密,加密算法如MD5、sha、mac等,然后在加密之前会把参数进行一个处理。

然后加密算法的特点:第一点明文不一样,加密的结果也不同(MD5、sha),第二点没有解密的钥匙加密完的结果不可逆,第三点加密完的结果长度一致

在app里面对参数加密时,会先对数据进行排序,加密的原因由于结果不可逆,服务端需要接收数据复现算法来对比加密结果,排序算法可以保证不会因为参数乱序而导致结果不同

然后开始,首先双击打开 jadx-gui-1.4.7.exe并且把apk文件拖到jadx-gui-1.4.7.exe里

然后Firda HOOK脚本代码

function showStacks(){console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()
));
}
function paixusuanfa(){
var Collections = Java.use('java.util.Collections');
// Hook sort() 方法
Collections.sort.overload("java.util.List").implementation = function(list) {console.log('Hooked Collections.sort()');
console.log('List: ' + list.toString());
// 可在此处对参数进行修改或记录
// 使用 Java.cast 进行类型转换 将list转换成ArrayList类型
var res = Java.cast(list,Java.use("java.util.ArrayList"))if(res.toString().includes("userPwd")){showStacks()}
console.log('List list-->',res)
// 调用原始的 sort() 方法
return this.sort(list);
}Collections.sort.overload("java.util.List","java.util.Comparator").implementation = function(a,b) {console.log("Hooked Collections.sort()22222");var res = Java.cast(a, Java.use("java.util.ArrayList"))if(res.toString().includes("userPwd")){showStacks()}console.log('Comparator list-->',res)return    this.sort(a,b);
}}Java.perform(function (){
paixusuanfa()})

效果图:然后根据打印的栈信息,去jadx-gui-1.4.7.exe里找

首先根据栈信息得到它调用了一个onClick方法,然后就从onClick方法入手

然后点击下图红框位置

搜索 LoginActivity类,通过栈可以看出onClick方法在LoginActivity类中,所以通过搜索 LoginActivity类名来找onClikck

如下图找的类

然后双击下图红框位置

进入类中

然后找onClick方法,如下图onClick方法,然后开始分析它

通过Firda hook脚本知道onClick里面调用了login方法,如下图源码也确实调用了,然后鼠标左键双击下图红框里的login进入login方法里

然后在login方法中调用了,下图红框的方法发送了登录请求,然后再进入requestNetwork方法里

然后下图蓝框可以看到它重写的响应处理

然后通过Frida hook看出入参是在红框里组装的

然后

然后,可以看出通过排序也是可以找到入参的

然后另一个栈,可以看出与上面的栈一样

hook string字符串

很多app在参数加密的时候会把字符串转成字节,一般stirng离着加密最近,也就是说stirng的内容是已经处理好的,所以在stirng的位置往上找,会找到一些蛛丝马迹

Frida hook脚本代码

function showStacks(){console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
function hookString(){var StringClass = Java.use('java.lang.String');// Hook String 类的构造函数StringClass.getBytes.overload().implementation = function () {console.log('Original Value');// 可在此处修改传入的字符串参数var res = this.getBytes();var newString = StringClass.$new(res)// 输出修改后的值console.log('Modified Value: ' + newString);return res;}}Java.perform(function (){
hookString()})

效果图:

打印堆栈的写法

function showStacks(){console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
function hookString(){var StringClass = Java.use('java.lang.String');// Hook String 类的构造函数StringClass.getBytes.overload().implementation = function () {console.log('Original Value');// 可在此处修改传入的字符串参数var res = this.getBytes();var newString = StringClass.$new(res)// 输出修改后的值console.log('Modified Value: ' + newString);if (newString.toString().includes('username')){// 字符串中包含 username 就打印堆栈showStacks()}return res;}}Java.perform(function (){
hookString()})

分析栈

通过上方的栈看源码,下图红框位置是md5加密

image-20241002140212571

然后进入md5方法,可以看到下图红框位置它调用了getBytes方法,在加密之前获取了字符串的字节(或者说是字符),基本上所有md5的都会这样写,md5要的参数就是字节,对于安全方面来说下图中的md5的写法需要改一下,自己实现字节转换,不要用它提供好的方法,避免被人用上方的Frida hook脚本拦截

Stirng还有一个静态的getByte方法,如下图红框

function showStacks(){console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
function hookString(){var StringClass = Java.use('java.lang.String');// Hook String 类的构造函数StringClass.getBytes.overload().implementation = function () {console.log('Original Value');// 可在此处修改传入的字符串参数var res = this.getBytes();var newString = StringClass.$new(res)// 输出修改后的值console.log('Modified Value: ' + newString);if (newString.toString().includes('username')){// 字符串中包含 username 就打印堆栈showStacks()}return res;}// Hook String 类的静态方法StringClass.getBytes.overload('java.lang.String').implementation = function(obj) {console.log('Hooked String.valueOf()');// 可在此处修改传入的对象参数showStacks()var res = this.getBytes(obj);var newString = StringClass.$new(res,obj)// 输出修改后的结果console.log('getBytes: ' + newString)return res}}Java.perform(function (){
hookString()})

效果图:可以看到它也是可以hook到请求入参的

hook StringBuilder字符串

StringBuilder也是一种数据存放的容器

Frida HOOK脚本代码

function showStacks(){console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()
));
}
function d(){
// 获取 StringBuilder 类并定义需要 Hook 的方法名
var stringBuilderClass = Java.use("java.lang.StringBuilder");
stringBuilderClass.toString.implementation = function (){var res = this.toString.apply(this,arguments)if (res == ""){showStacks()console.log('tostring is called ',res)}console.log('tostring is called ',res)return res
}}Java.perform(function (){
d()})

效果图:注意下图红框接口返回的是加密的数据(密文)现在它是明文,这样通过打印栈信息可以找到它解密的代码

然后还可以看到请求入参的明文和响应的密文,可以发现StringBuilder也可以覆盖很多东西,所以直接把所有方法所有类全HOOK掉就一定可以找到漏洞

HOOK点击按钮进行定位

Andriod sdk里有一个工具叫做 uiautomatorviewer.bat,如下图红框

双击上图红框里文件运行之后,会出现下图中的内容,然后点击下图红框里的按钮,会出错

下图出错的原因是,安装了多个Android SDK当前目录未配置环境变量,意思就是找错目录了

需要用环境变量里的那个目录,如下图是Path的环境变量的内容,需要在这里面打开 uiautomatorviewer.bat才行

然后下图的错是因为,uiautomatorviewer.bat不维护了正常版本的会有问题,网上有大神修改了,需要下载修改的uiautomatorviewer.bat才行,已经放到百度网盘了

如下图:下载下图红框里的东西

上图红框里的东西下载完,然后把里面的tool进行复制,然后把原本Android SDK里的tool删了(一定要删了或者改个名)然后把复制的tool粘贴过去,如下图

然后再次双击 uiautomatorviewer.bat 运行

然后再点下图红框按钮连接手机就可以了,它可以看组件的id,如何使用继续往下看

然后鼠标点击,下图红框位置后,就可以在下图蓝框位置看到它的id(下图也就是输入框组件的id)

主要是看它按钮的id,如下图按钮的id是btn_login,找到了它的id就可以对它进行hook

Frida Hook脚本代码:它是通过hook绑定事件的setOnClickListener方法来实现,它只能通过Frida重启app的方式来拦截

function showStacks(){console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
function d(){
var btn_login_id = Java.use("com.dodonew.online.R$id").btn_login.value;console.log('id:',btn_login_id)var View = Java.use('android.view.View');View.setOnClickListener.implementation = function(listener) {console.log(this.getId(),"22222222222")if (this.getId() === btn_login_id){showStacks()console.log("view.id-->" + this.getId())}// 调用原始的setOnClickListener方法return this.setOnClickListener(listener);};}Java.perform(function (){
d()})

下图通过红框里绑定了点击事件,处理点击事件的函数是通过实现下图蓝框里的接口来的,也就是setOnClickListener方法绑定的是当前类(this就是当前类)

然后在下图中可以看出 OnClickListener 接口只有一个onClick方法,所以源码中 LoginActivity类就一定会实现onClick方法并且在点击空间的时候会执行onClick方法

也就是会执行下图红框的代码,这就是通过id来hook看源码的思路

强制重启hook的Frida命令:frida -Uf com.dodonew.online -l ./xxx/js,也就是使用 spawn 模式,执行之后app会关闭重启,重启时会处于卡死状态,需要输入 %resume 让app运行起来

执行的指令

效果图:


img


http://www.ppmy.cn/server/126797.html

相关文章

【数据库】在 Java 中使用 MongoDB 进行数据聚合

MongoDB 的聚合框架允许对数据进行复杂的处理和计算,这是分析和报告数据的强大工具。本文将介绍如何在 Java 中使用 MongoDB 进行数据聚合。 1. 聚合框架简介 MongoDB 提供了多种聚合操作,包括: $match:过滤文档。$group&#x…

【Android】布局优化—include,merge,ViewStub的使用方法

引言 1.重要性 在Android应用开发中,布局是用户界面的基础。一个高效的布局不仅能提升用户体验,还能显著改善应用的性能。随着应用功能的复杂性增加,布局的优化变得尤为重要。优化布局能够减少渲染时间,提高响应速度&#xff0c…

docker 搭建minimalist-web-notepad

亲测可用 服务器 ubuntu sudo mkdir -p /root/docker/note# 切换到rootsu -chmod -R 755 /root/docker/notedocker pull carlosa/minimalist-web-notepad# 容器端口80 映射到 服务器7001端口,记得开防火墙 docker run -d --name notepad --restart always -p 7001…

k8s搭建双主的mysql8集群---无坑

《k8s搭建一主三从的mysql8集群---无坑-CSDN博客》通过搭建一主三从,我们能理解到主节点只有1个,那么承担增删改主要还是主节点,如果你在从节点上去操作增删改操作,数据不会同步到其他节点。本章我们将实现多主(双主&a…

【C++】多态(下)

个人主页~ 多态(上)~ 多态 四、多态的原理1、虚表的存储位置2、多态的原理3、动态绑定和静态绑定 五、单继承和多继承关系的虚函数表1、单继承中的虚函数表2、多继承中的虚函数表 六、多态中的一些小tips 四、多态的原理 1、虚表的存储位置 class A {…

选择更轻松:山海鲸可视化与PowerBI的深度对比

在数据分析与可视化的时代,选择合适的报表工具显得尤为重要。山海鲸可视化和PowerBI是市场上颇受欢迎的两款免费报表软件,各有特色。接下来,我们将从功能、优缺点等方面进行对比,帮助你找到最适合的工具。 山海鲸可视化 山海鲸可…

vue源码解析(源码解析学习大纲)

文章目录 Vue源码解析入手方向大纲1.核心概念1-1.响应式系统1-2. 组件1-3. 虚拟DOM1-4. 指令1-5. 生命周期钩子 2.虚拟DOM2-1. 概念2-2. 工作流程2-3. 示例2-4.总结 3.组件系统3-1. 组件的定义3-2. 组件的创建3-3. 组件的模板3-4. 生命周期3-5. 事件处理3-6. 插槽(S…

LeetCode热题100速通

一丶哈希 1、两数之和(简单) 给定一个整数数组 n u m s nums nums 和一个整数目标值 t a r g e t target target,请你在该数组中找出 和为目标值 t a r g e t target target 的那 两个 整数,并返回它们的数组下标。 你可以假设…