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

news2024/11/25 6:35:42

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.coloradmin.cn/o/1457245.html

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

相关文章

【C语言】长篇详解,字符系列篇2-----受长度限制的字符串函数,字符串函数的使用和模拟实现【图文详解】

欢迎来CILMY23的博客喔&#xff0c;本期系列为【【C语言】长篇详解&#xff0c;字符系列篇2-----“混杂”的字符串函数&#xff0c;字符串函数的使用和模拟实现【图文详解】&#xff0c;图文讲解各种字符串函数&#xff0c;带大家更深刻理解C语言中各种字符串函数的应用&#x…

小型医院医疗设备管理系统|基于springboot小型医院医疗设备管理系统设计与实现(源码+数据库+文档)

小型医院医疗设备管理系统目录 目录 基于springboot小型医院医疗设备管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、职员信息管理 2、设备信息管理 3、库房信息管理 4、公告信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、…

【性能测试入门必看】性能测试理论知识

一、性能测试理论知识 1、常用的七种性能测试方法 (1) 后端性能测试&#xff1a;其实&#xff0c;你平时听到的性能测试&#xff0c;大多数情况下指的是后端性能测试&#xff0c;也就是服务器端性能测试。后端性能测试&#xff0c;是通过性能测试工具模拟大量的并发用户请求&…

20240219画图程序

1. PTZ在惯性态时&#xff0c;不同视场角下的【发送】角速度和【理论响应】角速度 1.1 优化前 import numpy as np import matplotlib.pyplot as plt# PTZ在惯性态时&#xff0c;不同视场角下的【发送】角速度和【理论响应】角速度 ATROffset_x np.linspace(0, 60, 120) y2 …

OpenAI 全新发布文生视频模型 Sora,支持 60s 超长长度,有哪些突破?将带来哪些影响?

Sora大模型简介 OpenAI 的官方解释了在视频数据基础上进行大规模训练生成模型的方法。 我们下面会摘取其中的关键部分罗列让大家快速get重点。 喜欢钻研的伙伴可以到官网查看技术报告&#xff1a; https://openai.com/research/video-generation-models-as-world-simulator…

【图论经典题目讲解】CF786B - Legacy 一道线段树优化建图的经典题目

C F 786 B − L e g a c y \mathrm{CF786B - Legacy} CF786B−Legacy D e s c r i p t i o n \mathrm{Description} Description 给定 1 1 1 张 n n n 个点的有向图&#xff0c;初始没有边&#xff0c;接下来有 q q q 次操作&#xff0c;形式如下&#xff1a; 1 u v w 表示…

GO和KEGG富集分析

写在前面 我们《复现SCI文章系列教程》专栏现在是免费开放&#xff0c;推出这个专栏差不多半年的时间&#xff0c;但是由于个人的精力和时间有限&#xff0c;只更新了一部分。后续的更新太慢了。因此&#xff0c;最终考虑后还是免费开放吧&#xff0c;反正不是什么那么神秘的东…

关于数据结构的定义以及基本的数据结构

在计算机科学中&#xff0c;数据结构是指用于组织和存储数据的方式或方法。它涉及到在计算机内存中存储、管理和操作数据的技术和原则。数据结构不仅仅是简单地存储数据&#xff0c;还可以提供高效的数据访问和操作方式&#xff0c;以满足特定的需求。 以下是每个数据结构的详细…

mkcert安装教程

1、下载 官方文档&#xff1a;https://github.com/FiloSottile/mkcert#mkcert 下载链接&#xff1a;https://github.com/FiloSottile/mkcert/releases 2、安装&#xff0c;该文件目录下打开cmd&#xff08;可以把文件复制到别的文件夹&#xff09;&#xff0c;执行命令 //命令…

开源模型应用落地-工具使用篇-向量数据库进阶(四)

一、前言 通过学习"开源模型应用落地"系列文章&#xff0c;我们成功地建立了一个完整可实施的AI交付流程。现在&#xff0c;我们要引入向量数据库&#xff0c;作为我们AI服务的二级缓存。本文将继续基于上一篇“开源模型应用落地-工具使用篇-向量数据库&#xff08;三…

FreeRTOS移植到GD32

目录 一、GD32基础工程创建&#xff1a; 1、创建如下文件夹 2、在keil5创建工程 3、在工程添加相关.c文件和头文件路径 4、实例&#xff1a;实现LED闪烁功能 二、在基础工程添加FreeRTOS&#xff1a; 1、FreeRTOS中的文件: 2、添加的源文件: 3、添加的头文件路径: 4、…

机器人常用传感器分类及一般性要求

机器人传感器的分类 传感技术是先进机器人的三大要素&#xff08;感知、决策和动作&#xff09;之一。根据用途不同&#xff0c;机器人传感器可以分为两大类&#xff1a;用于检测机器人自身状态的内部传感器和用于检测机器人相关环境参数的外部传感器。 内部传感器 内部传感…

【JavaEE】_HTML常用标签

目录 1.HTML结构 2. HTML常用标签 2.1 注释标签 2.2 标题标签&#xff1a;h1~h6 2.3 段落标签&#xff1a;p 2.4 换行标签&#xff1a;br 2.5 格式化标签 2.6 图片标签&#xff1a;img 2.7 超链接标签&#xff1a;a 2.8 表格标签 2.9 列表标签 2.10 表单标签 2.10…

航班进出港|航班进出港管理系统|基于springboot航班进出港管理系统设计与实现(源码+数据库+文档)

航班进出港管理系统目录 目录 基于springboot航班进出港管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 5、航班信息管理 &#xff08;1&#xff09; 航班信息管理 &#xff08;2&#xff09;起飞降落申请管理 &#xff08;3&#xff09;公告管理 &…

辽宁博学优晨教育科技有限公司视频剪辑培训专业之选

随着数字时代的到来&#xff0c;视频剪辑技术已成为各行各业不可或缺的一项技能。为了满足市场需求&#xff0c;辽宁博学优晨教育科技有限公司&#xff08;以下简称“博学优晨”&#xff09;推出了专业的视频剪辑培训课程&#xff0c;旨在为广大学员提供系统、高效的学习机会。…

AMD FPGA设计优化宝典笔记(4)复位桥

高亚军老师的这本书《AMD FPGA设计优化宝典》&#xff0c;他主要讲了两个东西&#xff1a; 第一个东西是代码的良好风格&#xff1b; 第二个是设计收敛等的本质。 这个书的结构是一个总论&#xff0c;加上另外的9个优化&#xff0c;包含的有&#xff1a;时钟网络、组合逻辑、触…

面试系列之《Spark》(持续更新...)

1.job&stage&task如何划分&#xff1f; job&#xff1a;应用程序中每遇到一个action算子就会划分为一个job。 stage&#xff1a;一个job任务中从后往前划分&#xff0c;分区间每产生了shuffle也就是宽依赖则划分为一个stage&#xff0c;stage这体现了spark的pipeline思…

picker选择器-年月日选择

从底部弹起的滚动选择器。支持五种选择器&#xff0c;通过mode来区分&#xff0c;分别是普通选择器&#xff0c;多列选择器&#xff0c;时间选择器&#xff0c;日期选择器&#xff0c;省市区选择器&#xff0c;默认是普通选择器。 学习一下日期选择器 平台差异说明 日期选择默…

k8s学习(RKE+k8s+rancher2.x)成长系列之简配版环境搭建(三)

3.19.切换RKE用户,并做免密登录(三台机器相互免密) su rke cd~ ssh-keygen[rke@master.ssh]$ssh-copy-id rke@slaver2 [rke@master.ssh]$ssh-copy-id rke@slaver1 [rke@master.ssh]$ssh-copy-id rke@master3.20.搭建RKE集群 为了方便理解,我们把通RKE部署的Kubernetes集群称…

浏览网页记录工具,企业如何查看员工网页浏览记录

随着信息技术的飞速发展&#xff0c;网络已成为企业日常运营和员工工作中不可或缺的一部分。然而&#xff0c;随之而来的是网络安全和员工上网行为管理的挑战。在这种情况下&#xff0c;浏览网页记录工具成为了企业监控员工上网行为的重要手段之一。 一、浏览网页记录工具的重要…