Android逆向学习(七)绕过root检测与smali修改学习

Android逆向学习(七)绕过root检测与smali修改学习

一、写在前面

这是吾爱破解正己大大教程的第五个作业,然后我的系统还是ubuntu, 这个是剩下作业的完成步骤。

二、任务目标

现在我们已经解决了一些问题,现在剩下的问题有

  1. hash校验需要解决
  2. 关于root检测的
  3. 关于与smali学习的

1.解决hash校验的问题

老样子,我们先查看hash校验的代码,看一下这个代码的逻辑

直接把java代码给粘贴过来

public final boolean check_Hash(Context context) {String apkPath = getApkPath((Context) this);FileInputStream fileInputStream = null;try {try {MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");byte[] bArr = new byte[1024];Ref.IntRef intRef = new Ref.IntRef();FileInputStream fileInputStream2 = new FileInputStream(new File(apkPath));while (true) {try {int read = fileInputStream2.read(bArr);intRef.element = read;if (read <= 0) {break;}messageDigest.update(bArr, 0, intRef.element);} catch (Exception e) {e = e;fileInputStream = fileInputStream2;e.printStackTrace();if (fileInputStream != null) {try {fileInputStream.close();} catch (IOException e2) {e2.printStackTrace();}}return false;} catch (Throwable th) {th = th;fileInputStream = fileInputStream2;if (fileInputStream != null) {try {fileInputStream.close();} catch (IOException e3) {e3.printStackTrace();}}throw th;}}String bigInteger = new BigInteger(1, messageDigest.digest()).toString(16);Log.e("zj2595", "hash:" + bigInteger);boolean areEqual = Intrinsics.areEqual(bigInteger, this.ApkHash);try {fileInputStream2.close();} catch (IOException e4) {e4.printStackTrace();}return areEqual;} catch (Exception e5) {e = e5;}} catch (Throwable th2) {th = th2;}}

2.解决root检验的问题

这个一共有三个检测方法,用了一个或操作,然后我就简要总结一下这个三个方法

  1. 检查有没有test-keys

    检查发布的系统版本是测试版(test-keys)还是发布版(release-keys),这个不一定,因为有的系统发布版就是test-keys,而且这个很少有人用

  2. 检查相应目录下有没有su文件或者有没有superuser.apk这种只有root手机才有的信息

    这个方法经常使用,不过规避方法也很多

  3. 使用which命令来检测是否存在su

    这个其实也挺简单的,如果用hook的话

实际上如果一个手机被root之后也是很难被发现的,因为如果root后就可以使用xposed或者frida这些工具进行hook,hook的功能是非常的强大的。

然后这个的解决方法也是很多,比如:

  1. 直接修改smali代码,永远返回真(之前讲到过,不讲了)
  2. hook这个check代码,永远返回真(之前也讲到过,不讲了)
  3. 我想到的是使用frida做一个能够一劳永逸的hook代码

3.关于smali学习的题目

20240216180810

这里smali学习部分的作业,我们的目标就是通过修改smali代码,使vip和会员到期时间通过,并且修改钻石数量。

三、实现方法

问题一的实现

通过对代码的分析我们可以了解到。首先会读取apk的路径,然后计算出hash值,然后使用这个hash值和之前的hash值进行比对,就可以得到最终的正确的hash值。

这个的解决方法就太多了,我们就随便选择一个方式解决掉。

  1. 比如frida直接hook这个函数让他永远返回true。
  2. hook这个getApkPath((Context) this)的方法,然后修改这个路径到我们自己安装包的路径,不过在上一篇文章中这个方法有点问题(我怀疑是这个apk本身的bug)
  3. 修改this.ApkHash,让这里hash值和实际计算的hash值一样。

这些方法在上一篇博客中已经介绍过了,所以这里不再赘述了,直接使用第一个方法给他hook了

Java.perform(function () {Java.use("com.zj.wuaipojie.ui.ChallengeFifth").check_Hash.implementation = function (j) {var result = this.check_Hash(j);send(result);return true;}
})

这样就可以很轻松的通过(frida真厉害!)

20240216231624

问题二的实现

关于root的实现我们先看一下java代码(注:这个地方smali2java插件是有问题的,所以这一串代码我是通过jd-gui逆向得到的)

public final boolean check_root() {return (checkRootMethod1() || checkRootMethod2() || checkRootMethod3());}public final boolean checkRootMethod1() {String str = Build.TAGS;boolean bool2 = false;boolean bool1 = bool2;if (str != null) {bool1 = bool2;if (StringsKt.contains$default(str, "test-keys", false, 2, null))bool1 = true; } return bool1;}public final boolean checkRootMethod2() {for (byte b = 0; b < 10; b++) {(new String[10])[0] = "/system/app/Superuser.apk";(new String[10])[1] = "/sbin/su";(new String[10])[2] = "/system/bin/su";(new String[10])[3] = "/system/xbin/su";(new String[10])[4] = "/data/local/xbin/su";(new String[10])[5] = "/data/local/bin/su";(new String[10])[6] = "/system/sd/xbin/su";(new String[10])[7] = "/system/bin/failsafe/su";(new String[10])[8] = "/data/local/su";(new String[10])[9] = "/su/bin/su";if ((new File((new String[10])[b])).exists())return true; } return false;}public final boolean checkRootMethod3() {boolean bool1 = false;boolean bool2 = false;boolean bool3 = false;Process process = null;try {Process process1 = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" });process = process1;BufferedReader bufferedReader = new BufferedReader();process = process1;InputStreamReader inputStreamReader = new InputStreamReader();process = process1;this(process1.getInputStream());process = process1;this(inputStreamReader);process = process1;String str = bufferedReader.readLine();bool1 = bool3;if (str != null)bool1 = true; bool2 = bool1;if (process1 != null) {process = process1;} else {return bool2;} process.destroy();} finally {Exception exception = null;} return bool2;}

我们一共发现了三个检测的方法,这个在前面的分析已经讲过了,然后我们启动一下frida

20240219204805

之后我们写一个frida脚本然后运行一下hook,这个hook的主要目的就是把checkroot2里面的查找跟root有关文件的东西给屏蔽掉,就是如果一个手机是已经root了的,那么就会产生su等文件,我们就是通过frida hook避免这个程序发现这些文件,然后我之前以为camodroid比较全面可以完成这些东西,但是实际运行发现camodroid并不能完全屏蔽掉这些,所以我自己写了一个(在camodroid上改的)。

Java.perform(function () {Java.use('java.io.File')['$init'].overload('java.lang.String').implementation = function (pathString) {let map ={// Rootbeer"/system/xbin/busybox": "/system/xbin/busybo","/system/bin/su": "/system/bin/s","/system/xbin/su": "/system/bin/s","/system/app/Superuser.apk":"1","/sbin/su":"1","/data/local/xbin/su":"1","/data/local/bin/su":"1","/system/sd/xbin/su":"1","/system/bin/failsafe/su":"1","/data/local/su":"1","/su/bin/su":"1",};var retval;if (map[pathString] != null) {retval = this.$init("/system/bin/suasaadfghdfgh");}else {retval = this.$init(pathString);}return retval;};Java.use("com.zj.wuaipojie.ui.ChallengeFifth").checkRootMethod1.implementation = function () {var result = this.checkRootMethod1();send(result);send("check1")return result;}Java.use("com.zj.wuaipojie.ui.ChallengeFifth").checkRootMethod2.implementation = function () {var result = this.checkRootMethod2();send(result);send("check2")return result;}Java.use("com.zj.wuaipojie.ui.ChallengeFifth").checkRootMethod3.implementation = function () {var result = this.checkRootMethod3();send(result);send("check3")return result;}
})

结果如下图片

20240219213744

然后有个问题就是check3方法,这个方法本来就有问题

20240219213907

就是正常情况下就不应该使用只使用/system/xbin/which去检测是否有su文件,这个算是吾爱作业软件的一个小bug吧

问题三的实现

这个界面在smalilearn里面,我们直接smali2java插件给转了,这个代码不长,所以就直接粘贴到这里了

public final class SmaliLearn extends AppCompatActivity {private final int vip_coin;public final int isVip() {return 0;}public final long vipEndTime() {return 1671889481513L;}public final int getVip_coin() {return this.vip_coin;}protected void onCreate(Bundle bundle) {super.onCreate(bundle);setContentView(2131427364);((Button) findViewById(2131230819)).setOnClickListener(new SmaliLearn$.ExternalSyntheticLambda0(this, (TextView) findViewById(2131231219), (TextView) findViewById(2131231221), (TextView) findViewById(2131231220)));}/* JADX INFO: Access modifiers changed from: private *//* renamed from: onCreate$lambda-0  reason: not valid java name */public static final void m1onCreate$lambda0(SmaliLearn smaliLearn, TextView textView, TextView textView2, TextView textView3, View view) {int isVip = smaliLearn.isVip();if (isVip == 0) {textView.setText("非会员");} else if (isVip == 1) {textView.setText("会员");} else if (isVip == 4) {textView.setText("大会员");} else if (isVip == 16) {textView.setText("超级会员");} else if (isVip == 99) {textView.setText("至尊会员");}long time = new Date().getTime();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");if (smaliLearn.vipEndTime() < time) {textView2.setText("已过期");} else {textView2.setText(simpleDateFormat.format(Long.valueOf(smaliLearn.vipEndTime())));}int i = smaliLearn.vip_coin;if (i != 0) {textView3.setText(String.valueOf(i));}}
}

这个修改的部分有

原来的isVIp那个const/16 v0,0x63,就是把原来的v0修改成了99,关于smali这个东西,我是学过微机原理,对MIPS,X64等汇编语言有较多的使用经验,我建议如果你真的想学smali的话可以先去学学这些汇编,不然很难上手smali

20240219223057

这个是修改了时间,我就把第一位修改成了9

20240219223108

这个就是把调用返回值换成了直接进行赋值不调用

20240219223114

20240219223120

然后下面就是我们的运行结果,完结撒花!!!

20240219223650

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

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

相关文章

matplotlib图例使用案例1.1:在不同行或列的图例上添加title

我们将图例进行行显示或者列显示后&#xff0c;只能想继续赋予不同行或者列不同的title来进行分类。比较简单的方式&#xff0c;就是通过ax.annotate方法添加标签&#xff0c;这样方法复用率比较低&#xff0c;每次使用都要微调ax.annotate的显示位置。比较方便的方法是在案例1…

基于jieba、TfidfVectorizer、LogisticRegression的垃圾邮件分类,模型平均得分为0.98左右(附代码和数据集)

基于jieba、TfidfVectorizer、LogisticRegression的垃圾邮件分类,模型平均得分为0.98左右(附代码和数据集)。 垃圾邮件分类识别是一种常见的文本分类任务,旨在将收件箱中的邮件分为垃圾邮件和非垃圾邮件。以下是一些常用的技术和方法用于垃圾邮件分类识别: 基于规则的过…

探索设计模式的魅力:迭代器模式让你轻松驾驭复杂数据集合

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;并且坚持默默的做事。 文章目录 一、&#x1f4a1; 引言二、原理与结构 &#x1f4da;&#x1f465; 迭代器模式的关…

处理MIGO 采购订单过账报错:物料账簿货币被更改

同事操作MIGO 采购订单过账报错&#xff1a;物料账簿货币被更改。 跟据查资料检查一下OKKP的配置。进去后发现了另一个报错&#xff1a; 然后再查资料&#xff0c;让检查一下SCC4的配置。经查看&#xff0c;发现是顾问copy client是忘记填写client的货币了。我维护好后&#xf…

Eclipse - Makefile generation

Eclipse - Makefile generation References right mouse click on the project -> Properties -> C/C Build -> Generate Makefiles automatically 默认会在 Debug 目录下创建 Makefile 文件。 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

数据结构-哈夫曼树

介绍 哈夫曼树&#xff0c;指带权路径长度最短的二叉树&#xff0c;通常用于数据压缩中 什么是带权路径长度&#xff1f; 假设有一个结点&#xff0c;我们为它赋值&#xff0c;这个值我们称为权值&#xff0c;那么从根结点到它所在位置&#xff0c;所经历的路径&#xff0c;…

无穷绕八双纽线

目录&#xff09; 前言双纽线双纽线工程化双纽线应用参考文献 前言 今天是初八&#xff0c;在中国某些地方初八有拜财神的习俗&#xff0c;“八”谐音“发”&#xff0c;等同于恭喜发财的“发”&#xff0c;寓意着在新的一年里红红火火发大财&#xff0c;三叔首先祝福各位读者…

如何使用HTTP隧道在Linux环境下构建内网穿透解决方案

你是否曾经遇到过这样的尴尬场景&#xff1a;身处内网环境&#xff0c;却想要让外部世界的朋友访问你的某个服务&#xff0c;却发现那堵墙——防火墙&#xff0c;如同一座不可逾越的山峰&#xff0c;挡住了你的去路&#xff1f;别担心&#xff0c;今天我们就来聊聊如何在Linux环…

Python:变量与数据类型

目录 一、变量 1.1 强数据类型与弱数据类型 1.2 全局函数 1.3 变量的命名规范 二、数据类型 2.1 基本数据类型 2.2 复合数据类型&#xff08;引用数据类型&#xff09; 三、数据类型转换 一、变量 变量&#xff1a;顾名思义&#xff0c;变化的量。在python中代指运行时…

【大厂AI课学习笔记】【2.2机器学习开发任务实例】(6)特征分析

今天来学习特征分析。 通过图分析每个特征与结果的对应关系。 例如上方&#xff0c;使用散点图&#xff0c;将各个特征和价格的关系&#xff0c;绘制出来&#xff0c;观察是否具有较大的相关性。 散点图可以帮助找出现有特征中&#xff0c;与价格的关联度&#xff08;正数正相…

Vue3+vite搭建基础架构(6)--- 使用vue-router

Vue3vite搭建基础架构&#xff08;6&#xff09;--- 使用vue-router 说明官方文档安装vue-router使用vue-router测试vue-router 说明 这里记录下自己在Vue3vite的项目使用vue-router的过程&#xff0c;不使用ts语法&#xff0c;方便以后直接使用。这里承接自己的博客Vue3vite搭…

[ linux网络 ] 网关服务器搭建,综合应用SNAT、DNAT转换,dhcp分配、dns分离解析,nfs网络共享以及ssh免密登录

实验准备工作&#xff1a; 网关服务器安装&#xff1a;dhcp bind &#xff08;yum install -y dhcp bind bind-utlis&#xff09; server1安装&#xff1a;httpd (yum install -y httpd) 没有网络就搭建本地yum仓库或者配置网卡使其能够上网。 ( 1&#xff09;网关服务器…

源聚达科技:抖音店铺2024年卖什么好

随着时代的变迁和科技的进步&#xff0c;消费者的购物习惯与偏好也在不断演变。展望2024年&#xff0c;抖音作为新兴的电商平台&#xff0c;其店铺销售策略需紧跟潮流&#xff0c;才能在激烈的市场竞争中脱颖而出。那么&#xff0c;哪些产品将成为抖音店铺的新宠呢? 首当其冲&…

STM32CubeMax(使用7步)新建工程

现在有时间学习一下STM32用CubeMX新建一个工程的步骤&#xff0c;特此记录一下&#xff1a; 第一步打开STM32CubeMax 第二步搜索芯片型号&#xff1a; 第三步配置时钟&#xff1a; 第四步点选配置时钟源&#xff1a; 第五步填写工程相关的名称路径信息&#xff1a; 第六步选择…

基于SpringBoot3从零配置SpringDoc

基于SpringBoot3从零配置SpringDoc 一、SpringFox二、SpringDoc三、Open API 规范四、SpringBoot3配置Knife4j1.官方参考文档2.添加依赖3.添加配置项4.设置文档首页5.编写控制器6.文档展示 一、SpringFox github SpringFox 已经停止更新了。SpringFox 对 SpringBoot3.0 不适配…

微信小程序开发之Vant组件库

文章目录 环境Vant介绍示例 微信小程序的npm支持安装npm包构建npm 在微信小程序开发中使用Vant准备安装和配置一&#xff1a;安装二&#xff1a;修改app.json三&#xff1a;修改project.config.json四&#xff1a;构建npm包 使用Button组件Calendar组件 参考 环境 Windows 11 …

【开源】基于JAVA+Vue+SpringBoot的就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…

把Llama2封装为API服务并做一个互动网页

最近按照官方例子&#xff0c;把Llama2跑起来了测试通了&#xff0c;但是想封装成api服务&#xff0c;耗费了一些些力气 参考&#xff1a;https://github.com/facebookresearch/llama/pull/147/files 1. 准备的前提如下 按照官方如下命令&#xff0c;可以运行成功 torchrun -…

程序员怎么利用chatgpt提高效率

在当今这个数字化时代&#xff0c;AI 技术以各种形式融入到我们的生活和工作中&#xff0c;对于程序员而言&#xff0c;AI 可以成为他们的得力助手。特别是 OpenAI 的 ChatGPT&#xff0c;其深度学习模型在编程领域具有很大潜力。 首先&#xff0c;我们介绍一下 GitHub Copilo…

【Larry】英语学习笔记语法篇——非谓语动词和从句是一回事

目录 非谓语动词和从句是一回事 不定式&#xff1a;名词/形容词/副词 1、不定式 名词属性的不定式&#xff1a;作为主语、表语、宾语 形容词属性的不定式&#xff1a;作后置定语 副词属性的不定式&#xff1a;作状语 副词属性的不定式&#xff1a;作插入语 不定式的逻辑…