记录一次某某虚拟机的逆向

news2024/11/17 15:30:44

导语

学了一段时间的XPosed,发现XPosed真的好强,只要技术强,什么操作都能实现...
这次主要记录一下我对这款应用的逆向思路

apk检查

  1. 使用MT管理器检查apk的加壳情况

  1. 发现是某数字的免费版本

  2. 直接使用frida-dexdump

  3. 脱下来后备用

应用分析

  1. 进入应用之后会发现里边含有登录 会员等模块
  2. 我们先不管登录的部分,先检查会员的使用场景,一般在会员的使用场景或者显示场景中都会有检查是否是VIP的业务逻辑,根据这个来加载显示不同的资源

会员分析

  1. 通过对应用的检查发现在添加虚拟机设备的时候用到了会员权限

 同时弹出一个对话框,应用也贴心的告诉我们VIP的使用场景

  • 打开算法助手,算法助手对应用进行了常见功能的Hook,最重要的是支持免费加固的Hook

  • 将这3项勾选

  • 重复1、2步,在日志中检查OnClick和弹窗是否有用的信息

  • 很幸运,在这一步就获取有关的逻辑

  • 且函数名称并没有被混淆,能够从调用堆栈读出以下逻辑:点击下载按钮->检查是否VIP->用户没有登录->显示购买VIP的弹窗

  • 打开jadx将脱壳后的dex文件载入,搜索checkVip

 选择第一个函数,发现无有用信息,继续进入checkVip函数

在此函数中发现getUserConf,即获取用户的配置 

通过对此函数的阅读,得出此函数的返回值为UserBean 

然后检查
UserBean 

  1. 很明显,有关VIP的数据都在此,使用XPosed来修改这些成员变量,即可达到对显示UI的修改,即使服务器对这些数据有校验也不影响,至少在UI层面已经成功了

抓包分析

  1. 使用抓包工具检查网络请求,当点击底部的导航栏的时候,应用会发送网络请求

 

通过检查getInfo,获取一个Post请求的链接对此链接进行引用查询,发现有关用户的逻辑 

 对此链接进行引用查询,发现有关用户的逻辑阅读此函数,网络请求库可能为Retrofit,当请求成功的时候会将用户的信息保存起来并移除广告?同样也能得到UserBean,这个关键的信息

 

编写插件

思路

  1. 通过对应用的分析可以得出一个关键的信息getUserConf
  2. getUserConf函数右键->复制为XPosed片段

 

1

2

3

4

5

6

7

8

9

10

XposedHelpers.findAndHookMethod("com.vmos.pro.account.AccountHelper", classLoader, "getUserConf", new XC_MethodHook() {

    @Override

    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

        super.beforeHookedMethod(param);

    }

    @Override

    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

        super.afterHookedMethod(param);

    }

});

  1. 可以看到jadx为我们一键生成了有关的Hook代码,但是这样就行了吗?我可以告诉你,不行。别忘了,这是一个加壳的应用,即使它是一款免费加壳

加壳应用Hook

通过对网上公开资料的查询,发现即使应用加固也需要在运行时进行还原修复,使用jadx打开加固的apk文件,找到attachBaseContext

1

2

3

4

5

6

7

8

9

XposedHelpers.findAndHookMethod("com.stub.StubApp", param.classLoader, "attachBaseContext", android.content.Context.class, new XC_MethodHook() {

    @Override

    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

        super.afterHookedMethod(param);

        Context context = (Context) param.args[0];//获取运行时的Context

        ClassLoader classLoader = context.getClassLoader()//获取真正的ClassLoader

        //在此添加Hook VIP等操作,使用classLoader

    }

});

继续编写

  1. 获取到正确的ClassLoader后,对getUserConf函数的返回值进行遍历

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

XposedHelpers.findAndHookMethod("com.vmos.pro.account.AccountHelper", classLoader, "getUserConf", new XC_MethodHook() {

    @Override

    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

        Object UserBean = param.getResult();

        for (Field field : UserBean.getClass().getDeclaredFields()) {

            //设置可访问, 极其重要, 不然会崩溃

            field.setAccessible(true);

            //使用反射来获取运行时的数据

            var name = field.getName();

            var type = field.getType();

            var value = field.get(UserBean);

            Log.i("HookTag", name + ": " + value);

        }

        super.afterHookedMethod(param);

    }

});

  1. Hook完成后,能够发现nickName是正确的,能够对应上UI的显示
     

 

  1. 接下来只需要对循环里的数据进行判断赋值,然后返回即可

1

2

3

4

5

6

7

8

9

10

//修改名称,其他自行测试

for (Field field : UserBean.getClass().getDeclaredFields()) {

    ......

    if (name.equals("nickName")) {

        field.set(UserBean, "测试文字");

    } else if(......) {

        ......

    }

}

param.setResult(UserBean);//设置返回值,替换掉param.getResult()获取的

  1. UI显示和下载功能

 

 

 

插件下载破解

获取到VIP后,发现还有一个插件下载的逻辑没有效果

下载逻辑分析

  1. 当点击Root或者XPosed的时候,会提示加载失败 

  • 但是点击谷歌服务的时候却有效果,猜测是网络请求

  • 打开抓包工具,通过对两者的对比,发现是其中少了一些数据,所以才会加载失败

 

在jadx中搜索getPluginUrl,通过阅读此函数发现有2个匿名函数,failuresuccess 

  1. 使用jadx默认给我们的参数Hook不太行,这时候需要使用其他函数来获取vu

1

2

3

4

5

6

7

8

9

10

11

//vu<jo4>.class 无法获取

//使用loadClass来获取,在参数中填写vu即可

Class<?> vu = classLoader.loadClass("vu");

XposedHelpers.findAndHookMethod("com.vmos.pro.activities.main.fragments.PluginHelper$getPluginDownloadBean$2$1", classLoader, "success", vu, new XC_MethodHook() {

    @Override

    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

        Log.i("HookTag", "success: " + Arrays.toString(param.args));

        super.beforeHookedMethod(param);

    }

});

//或者使用XposedBridge.hookAllMethods

  1. 通过对这两者的Hook,当点击Root插件按钮时会进入success且参数为:

1

2

谷歌服务按钮:success: [CommonResult{code=0, msg='OK', data=RespPlugin{systemPluginResult=RespPluginInfo{pluginUrl='http://xxx/xxx/plugin/android71gp_plugin-64bit3.zip', pluginMd5='62c38ec6b509e546e9fe9566969f7c49', version=0}}}]

Root按钮:success: [CommonResult{code=0, msg='OK', data=RespPlugin{systemPluginResult=null}}]

  1. 可以明显发现其中确实是少了一些数据,接下来只需要补齐下载链接即可,但是如何获取这个链接呢?
  • 充值VIP获取其中的链接
  • 扫描网站链接?或者找到一个函数获取?
  • 猜测
  1. 上面2点显然不是我能够解决的,2333,那就通过对链接的猜测吧,根据能够下载的谷歌服务链接来看,root和xposed可能为:
  • http://xxx/xxx/plugin/android71root_plugin-64bit.zip'
  • http://xxx/xxx/plugin/android71xposed_plugin-64bit.zip'
  • 通过一系列猜测,得出来正确的下载链接,MD5的话只需要在终端输入md5 file即可得到
  1. 阅读函数,检查参数发现具体的链接在vu中的data,但是返回类型是T,这就比较麻烦了

 

  1. 这里采用一种比较麻烦的方法来修改:
  • Hookvu类的m49633函数获取返回结果
  • 遍历返回结果的Fields
  • 找到含有systemPluginResult的field
  • 使用field.getType()获取到Class<?> jo4
  • 使用jo4.newInstance()创建一个实例ret
  • 再次遍历ret.getDeclaredFields()
  • 根据pluginMd5pluginUrl分别赋值到ret
  • 最后使用field.set(data, ret);赋值即可
  • 具体代码截图,pluginMd5pluginUrl是我获取的正确链接,就不公布了

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1200590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【ATTCK】MITRE Caldera - 测试数据泄露技巧

CALDERA是一个由python语言编写的红蓝对抗工具&#xff08;攻击模拟工具&#xff09;。它是MITRE公司发起的一个研究项目&#xff0c;该工具的攻击流程是建立在ATT&CK攻击行为模型和知识库之上的&#xff0c;能够较真实地APT攻击行为模式。 通过CALDERA工具&#xff0c;安全…

Git版本控制系统之分支与标签(版本)

目录 一、Git分支&#xff08;Branch&#xff09; 1.1 分支作用 1.2 四种分支管理策略 1.3 使用案例 1.3.1 指令 1.3.2 结合应用场景使用 二、Git标签&#xff08;Tag&#xff09; 2.1 标签作用 2.2 标签规范 2.3 使用案例 2.3.1 指令 2.3.2 使用示例 一、Git分支&…

55基于matlab的1.高斯噪声2.瑞利噪声3.伽马噪声4.均匀分布噪声5.脉冲(椒盐)噪声

基于matlab的1.高斯噪声2.瑞利噪声3.伽马噪声4.均匀分布噪声5.脉冲&#xff08;椒盐&#xff09;噪声五组噪声模型&#xff0c;程序已调通&#xff0c;可直接运行。 55高斯噪声、瑞利噪声 (xiaohongshu.com)

“第六十六天”

这个我记得是有更优解的&#xff0c;不过还是明天发吧&#xff0c;明天想一想&#xff0c;看看能不能想起来 #include<string.h> int main() {char a[201] { 0 };char b[201] { 0 };scanf("%s %s", a, b);int na strlen(a);int nb strlen(b);int i 0, j …

基于SpringBoot+Vue的在线学习平台系统

基于SpringBootVue的在线学习平台系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 用户界面 登录界面 管理员界面 摘要 本文设计并实现了一套基于Spri…

C语言——贪吃蛇

一. 游戏效果 贪吃蛇 二. 游戏背景 贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯⽅块&#xff0c;扫雷等游戏位列经典游戏的⾏列。 贪吃蛇起源于1977年的投币式墙壁游戏《Blockade》&#xff0c;后移植到各种平台上。具体如下&#xff1a; 起源。1977年&#xff0c;投币式…

Leetcode421. 数组中两个数的最大异或值

Every day a Leetcode 题目来源&#xff1a;421. 数组中两个数的最大异或值 解法1&#xff1a;贪心 位运算 初始化答案 ans 0。从最高位 high_bit 开始枚举 i&#xff0c;也就是 max⁡(nums) 的二进制长度减一。设 newAns ans 2i&#xff0c;看能否从数组 nums 中选两个…

数据结构—二叉树的模拟实现(c语言)

目录 一.前言 二.模拟实现链式结构的二叉树 2.1二叉树的底层结构 2.2通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 2.3二叉树的销毁 2.4二叉树查找值为x的节点 2.5二叉树节点个数 2.6二叉树叶子节点个数 2.7二叉树第k层节点个数 三.二叉树的遍历 3.1…

基于SpringMVC模式的电器网上订购系统的设计

大家好我是玥沐春风&#xff0c;今天分享一个基于SpringMVC模式的电器网上订购系统的设计&#xff0c;项目源码以及部署相关请联系我&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 本系统利用现在比较广泛的JSP结合后台SpringMybatisAjax编写程序的方式实现的。 在…

深度学习基于python+TensorFlow+Django的花朵识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 花朵识别系统&#xff0c;基于Python实现&#xff0c;深度学习卷积神经网络&#xff0c;通过TensorFlow搭建卷积神经…

Think-on-Graph:基于知识图的大型语言模型的深层可靠推理11.12

Hink-on-Graph&#xff1a;基于知识图的大型语言模型的深层可靠推理 摘要1 引言2 方法2.1图上思考2.1.1图的初始化2.1.2 探索2.1.3推理 2.2 基于关系的Think on graph 摘要 尽管大型语言模型&#xff08;LLM&#xff09;在各种任务中取得了巨大的成功&#xff0c;但它们经常与…

jupyter lab配置列表清单

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【 第十章】软件设计师 之 软件工程概述

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 备考资料导航 软考好处&#xff1a;软考的…

“总线仲裁”——以CAN总线为例

总线仲裁 1.什么是总线仲裁2.为什么要总线仲裁3.怎么进行总线仲裁&#xff08;总线仲裁机制&#xff09;3.1 如何确定冲突3.1.1 确定冲突前提3.1.2 同时冲突3.1.3 延时冲突 3.2 冲裁逻辑3.2.1 避免延时冲突3.2.1 避免同时冲突 1.什么是总线仲裁 提到总线仲裁的概念&#xff0c…

基于Qt 多线程(继承自QThread篇)

# 简介 我们写的一个应用程序,应用程序跑起来后一般情况下只有一个线程,但是可能也有特殊情况。比如我们前面章节写的例程都跑起来后只有一个线程,就是程序的主线程。线程内的操作都是顺序执行的。恩,顺序执行?试着想一下,我们的程序顺序执行,假设我们的用户界面点击有某…

leetcode-链表经典题

1.反转单链表 206. 反转链表https://leetcode.cn/problems/reverse-linked-list/这里我们使用创建一个变量cur来遍历原链表&#xff0c;再创建一个新节点newnode&#xff0c;首先使用一个循环来遍历原链表&#xff0c;cur为NULL是循环结束&#xff0c;每次进入循环将cur的下一…

nRF5 SDK 入门(三、理解 nRF5 SDK 应用与协议栈分开烧录)

说明一下 Nordic nRF5 SDK 软件 应用程序 和 协议栈分开烧录的理解前言 上一篇文章我们了解了 Nordic nRF5 SDK 目录结构&#xff0c;在那之前我们也已经搭建好了开发环境&#xff0c;实际上我们就已经可以进入我们的开发之旅了&#xff0c;但是如果刚接触 Nordic 蓝牙开发的小…

DeCLIP 论文阅读

DeCLIP:supervision exists everywhere:a data efficient contrastive language-image pre-training paradigm 贡献&#xff1a; 论文是为了充分利用单模态和多模态&#xff0c;充分利用单模态特征用自监督&#xff08;SIMSAM和MLM&#xff09;&#xff0c;多模态用图像文本对…

Vue简单使用Echart图表柱形图 vue使用柱形图 vue使用 echart图表柱形图 vue使用柱形图

Vue简单使用Echart图表柱形图 vue使用柱形图 vue使用 echart图表柱形图 vue使用柱形图 1、安装依赖2、页面Demo使用3、效果图 1、安装依赖 官方文档&#xff1a;https://echarts.apache.org/zh/option.html#title 官方在线示例&#xff1a;https://echarts.apache.org/exampl…

windows系统winget一键安装和使用

winget命令概述 用户可以在 Windows 10 和 Windows 11 计算机上使用 winget 命令行工具来发现、安装、升级、删除和配置应用程序。 此工具是 Windows 程序包管理器服务的客户端接口 在 Windows 沙盒上安装 winget Windows 沙盒提供了一个轻型桌面环境&#xff0c;可以安全地独…