Android逆向学习(六)绕过app签名校验,通过frida,io重定向(上)

Android逆向学习(六)绕过app签名校验,通过frida,io重定向(上)

一、写在前面

这是吾爱破解正己大大教程的第五个作业,然后我的系统还是ubuntu,建议先看一下上一个博客,关于动态调试的,因为我这才发现动态调试是真的有很大用处,然后我们开始今天的教程(拖更很久了,最近真的很忙事情好多,抽空出一期博客,这一节博客问题其实挺多的,如果有不对的地方请指出,不胜感激)

二、任务目标

  1. 破解签名,使程序可以正常运行

三、实现方法

1. 破解签名防止闪退

我们先简单看一下这个反编译之后的java文件

20231004205012

这里有个check,以及system终结的一个代码

解决方法具体有两种,一种简单的方法就是直接更改函数的返回值,让他只返回true

我们分析一下checkSign的代码

20231004205325

最主要就是修改这个地方,把false改成true

我们发现areEqual调用后有一个分支,就说明改变这个分支就可以了

20231004205711

我们直接修改smali代码后就是这样的

20231004211445

然后我们就可以看到这个页面是什么样子的了

20231004211546

然后还有一种方式就是我们动态调试一下,然后我们直接改变这个hash值

20231004211853

就是这个hash值,这个就是这个软件原来的hash,因为我们对这个软件进行了很多修改,所以现在的hash和原来的hash已经不一样了,所以我们需要改成和现在一样

我们直接在areEqual上面这里打一个断点,然后开始一步一步往下走,就可以看到这样:

20231004213430

这很明显就是要进行比较的两个值,然后我们把这个修改一下就可以了

20231004213554

然后我们打包运行一下(上一个方法的 add-int/lit8 v1, v1, 0x1 代码已经去除了 )

发现是可以进行运行的

20231004213918

2.关于剩余的签名

然后我这里一直有一些bug就是我点击验证总是会出问题,就是程序直接卡死,讲道理不应该这样才对,然后我直接debug动态调试发现是so校验的时候会卡死,讲道理不应该呀,我用真机测试也会出现这种情况,通过JEB进行动态调试之后发现就是在loadLibrary的时候会出现这个问题

搞了好久都不知道怎么回事,就只能把这个签名校验直接干掉了(字面意义上的干掉)

20231005160820

就是这三行直接全部消灭掉,当然这样一般肯定是有问题的,so文件里面一般都会有一些可能其他进程需要的函数,所以我建议最好不要用这个方法,我是实在没办法了才这样,要是不这样我可能连着好几天都没法更新新的blog,所以请大家见谅

但是不管如何我都会遇到这个问题,难不成因为版本问题?算了不管了先这样。

20240108204430

后来我想了想,不如反编译so文件看看,说不定可以看到哪里有问题,然后我们反编译后是这样

20240108211748

突然间想到,说不定是因为我把名称改成了东北往事,然后load的时候名称对不上

重新把东北往事换成了wuaipojie,结果还是完蛋,点击验证还是闪退,看来跟这个没关系,问题只有天知道了,就删掉继续吧,这样我们需要面对的就是API签名校验,CRC校验和hash校验

3.新API校验

我们同样进行一个逆向,直接看源代码

private final boolean useNewAPICheck() {
        String str;
        Signature[] signatureArr;
        try {
            if (Build.VERSION.SDK_INT >= 28) {
                signatureArr = getPackageManager().getPackageInfo(getPackageName(), 134217728).signingInfo.getApkContentsSigners();
            } else {
                signatureArr = getPackageManager().getPackageInfo(getPackageName(), 64).signatures;
            }
            str = MD5Utils.INSTANCE.MD5(Base64Utils.INSTANCE.encodeToString(signatureArr[0].toByteArray()));
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            str = "";
        }
        Log.e("zj2595", "newsign:" + str);
        return Intrinsics.areEqual("074f64af5821ae6aa1ac1779ad5687ad", str);
    }

这个就是新API校验的函数,当然按照正己大大的教程,我们是可以得到这个Log.e中的这个信息,那我们就先按照正己大大的教程,查看一下这个log就行了,我采用的方法是直接用adb看

首先打开终端,adb连接后打开shell,然后使用logcat关键词查询,就可以看到这个

20240108220253

这个然后复制过去,替换掉就可以了,就像这样

20240108220314

但是这就有一个问题了,一半正常情况下是不会有人专门log出来,所以这个方法在实战中是没有用处的,所以一般来说,我们的操作有

  1. 动态调试找到这个str
  2. 直接强行修改返回值,永远返回一个true

这两招是比较实用的

20240108220447

4.CRC校验(有问题,请先看完再实际操作)

这个方法也差不多,首先看一下crc校验的代码

    public final boolean check_crc(long j) {
        try {
            ZipEntry entry = new ZipFile(getPackageCodePath()).getEntry("classes.dex");
            Log.e("zj2595", "dexCrc:" + entry.getCrc());
            return entry.getCrc() == j;
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
    }

关于这个j我也看到了,我把相关代码摘出来

我们可以看到相关的代码有一个j

textView5.setText(challengeFifth.check_crc(j) ? "通过" : "不通过");

然后我们找到这个函数的参数
(TextView textView, ChallengeFifth challengeFifth, TextView textView2, TextView textView3, TextView textView4, TextView textView5, long j, TextView textView6, TextView textView7, View view)

顺藤摸瓜往上找,找到了

long parseLong = Long.parseLong(getString(2131755055));

button.setOnClickListener(new ChallengeFifth$.ExternalSyntheticLambda0(textView, this, textView2, textView3, textView6, textView4, parseLong, textView5, textView7));

这时候就比较难办了,修改也不好修改(强行修改返回值我不讲了,这个方法算作弊了,我们就学习一种新的破解方法)

原教程io重定向写的有点简略了,然后这个其实用frida可以很方便,我们在后面会详细讲到frida,这里我觉得我们就直接写,先对frida有个了解。

frida的安装我在之前的博客写过了,就是camodroid和tracedroid那篇,这里我们就直接使用,根据代码分析是getPackageCodePath()获得的地址,我们查看一下这个代码

20240109120111

这个是在android.content.ContextWrapper下面,之后我们就hook一下试一试

import sys
import frida

def on_message(messages, data):
    if messages["type"] == "send":
        print("[+] {}".format(messages["payload"]))
        print("[+] {}".format(messages))
    else:
        for name in messages:
            print("[+] {}".format(messages[name]))

process = frida.get_usb_device().attach('东北往事')
with open("frida.js") as f:
    script = process.create_script(f.read())
    # 这是将frida 的脚本给读取进来了
script.on("message", on_message)
script.load()
sys.stdin.read()

下面是frida的js脚本

Java.perform(function () {
    Java.use("android.content.ContextWrapper").getPackageCodePath.implementation=function () {
        var result = this.getPackageCodePath();
        send(result);
        return result;
    }
})

我们运行的结果是

‘/data/app/~~VEf27Hz4Vx9zDMiZ-UPXZQ==/com.zj.wuaipojie-Qpx1v_KIH3iiBblSp6vvtg==/base.apk’

这就是运行的路径了

所以我们目前的思路就是更改这个获取路径方法的返回值,将它定位到其他地方,我们当然可以直接hook check_crc的函数,但是这样还是一种作弊的方式吧,因为我写这个博客不是为了完成52的作业,而是学习更多的技术,如果是hook check_crc方法的话用下面这个脚本。

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

如果按我们之前的思路,那就开始更改路径

我们的方法就是,将这个返回值,给修改成我们放入原始包的地址,这样它检测的地址就是我们没有修改的包,说干就干.

我们还是首先把这个的apk包,用adb工具给发送到手机上

adb push 52demo.apk /data/local/tmp
cp /data/local/tmp/base.apk /data/user/0/com.zj.wuaipojie/files/

然后我们修改返回值为这个地址加apk文件名

Java.perform(function () {
    Java.use("android.content.ContextWrapper").getPackageCodePath.implementation=function () {
        var result = this.getPackageCodePath();
        send(result);
        var javaString = Java.use("java.lang.String")
        var newstring = javaString.$new("/data/user/0/com.zj.wuaipojie/files/base.apk")
        send(newstring)
        return newstring;
    }
})

然后扯淡的地方来了,这个始终不会出现crc校验通过,我不知道为什么会这样,按照道理来说应该是没问题的才对啊,这个就直接跳过了,不过这个思路是完全没有问题的,我感觉可能是因为版本对不上导致的,所以我直接hook crc函数算了,如果大家知道这个问题的话请联系我(可能是因为我用的第13节课的课件?最多只到7关的那个,可能是这个原因,等以后我换换试试)

这个就先这样过了吧

20240109214318

三、结尾

20240109214942

还是虎哥镇楼,作为我csdn博客的封面

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

强化学习求解TSP(二):Qlearning求解旅行商问题TSP(提供Python代码)

一、Qlearning简介 Q-learning是一种强化学习算法,用于解决基于奖励的决策问题。它是一种无模型的学习方法,通过与环境的交互来学习最优策略。Q-learning的核心思想是通过学习一个Q值函数来指导决策,该函数表示在给定状态下采取某个动作所获…

Linux【C编程】 信号以及信号的处理方式

文章目录 1.什么是信号?1.1信号是内容受限的一种异步通信机制1.2信号由谁发出的?1.3信号由谁处理,如何处理 2.常见的信号3.进程对信号的处理3.1用signal函数处理SIGINT信号3.2使用sigaction 函数 4.alarm 和pause函数4.1 alarm函数详解4.2 pa…

CDN的介绍以及加速内容传输原理

目前在公司的开发过程中,发现很多存储在oss的静态资源(图片,安装包)的链接中域名都使用了cdn域名,后面了解到这个cdn域名的主要作用是加速资源的访问,于是抽空了解了一下CDN加速原理。 目前使用得比较多的是…

CCSC,一种CPU架构

core-circuit-separate-computer 核与执行电路的分离,最初是为了省电。 用寄存器实现这种分离。 V寄存器控制着执行电路的供电,V0则不供电,进入省电模式;V1则供电,进入工作模式。 P寄存器是parameter-register&#xf…

3. SPSS数据文件的基本加工和处理

如何获取SPSS自带的案例数据文件? 首先找到SPSS的安装目录,然后找到Samples文件夹 可以看到有不同语言版本,选择简体中文 就能看到很多.sav文件 数据文件的整理 个案排序 单值排序 例:对于下面的数据集,将工资按…

【leetcode 2707. 字符串中的额外字符】动态规划 字典树

2707. 字符串中的额外字符 题目描述 给你一个下标从 0 开始的字符串 s 和一个单词字典 dictionary 。你需要将 s 分割成若干个 互不重叠 的子字符串,每个子字符串都在 dictionary 中出现过。s 中可能会有一些 额外的字符 不在任何子字符串中。 请你采取最优策略分割…

Developer Tools for Game Creator 1

插件包含: 持久世界时间管理系统 单击以生成对象或预设 游戏内调试控制台 游戏内事件控制台 控制台管理控制 命令模板脚本 游戏内屏幕截图 低分辨率和高分辨率图像 缩略图生成 移动支持 使用Game Creator Action或拖放来激活和控制组件,无需编码。 通过此资产,您可以获得: …

ESP32_ADC(Arduino)

ADC模数转换 ESP32集成了12位的逐次逼近式ADC,分别为ADC1模块ADC2模块,共支持18个模拟输入通道: ADC1模块:8个通道,32~39ADC2模块:10个通道,0,2,4,12 ~ 15,…

Linux网络配置概述

目录 一.查看网络配置 1.ifconfig 2.ip a 3.hostname 4.route 5.netstat和ss (1)netstat (2)ss (3)区别 6.ping 7.traceroute 8.nslookup 9.dig 二.网卡配置 三.域名解析配置文件 1.文件所…

用React给XXL-JOB开发一个新皮肤(一):环境搭建和项目初始化

目录 一. 简述二. Fork 项目三. 搭建开发环境四. 初始化皮肤项目五. 添加相关依赖六. 预览 一. 简述 大名鼎鼎的 xxl-job 任务调度中心我们应该都使用过,项目地址:xxl-job。它是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单…

【MySQL】导出导入(两种方式),远程备份

目录 前言: 一 navcat导入导出 1.1 导入 1.2 导出 二 mysqldump 导入导出 2.1 导入 2.2 导出 三 load data infile命令导入导出 3.1 导入 3.2 导出 四 远程备份 五 思维导图 前言: 随着当今企业发展,数据库的数据越来越多&…

vulhub中的Nginx漏洞的详细解析

Nginx漏洞 1.cd到nginx_parsing_vulnerability cd /opt/vulhub/nginx/nginx_parsing_vulnerability 2.执行docker-compose up -d 3.查看靶场是否开启成功 dooker ps 4.访问浏览器 因为这里是80端口所以直接使用ip就能访问成功 5.上传图片 注意这里的图片是含有一句话木马的图…

【大数据架构】日志采集方案对比

整体架构 日志采集端 Flume Flume的设计宗旨是向Hadoop集群批量导入基于事件的海量数据。系统中最核心的角色是agent,Flume采集系统就是由一个个agent所连接起来形成。每一个agent相当于一个数据传递员,内部有三个组件: source: 采集源&…

回顾 | AI 浪潮下的创业故事(一)—— Jina AI

点击蓝字 关注我们 编辑:Alan Wang 排版:Rani Sun 微软 Reactor 为帮助广开发者,技术爱好者,更好的学习 .NET Core, C#, Python,数据科学,机器学习,AI,区块链, IoT 等技术&#xff0…

论文阅读1---OpenCalib论文阅读之factory calibration模块

前言 该论文的标定间比较高端,一旦四轮定位后,可确定标定板与车辆姿态。以下为本人理解,仅供参考。 工厂标定,可理解为车辆相关的标定,不涉及传感器间标定 该标定工具不依赖opencv;产线长度一般2.5米 Fa…

SpiderFlow爬虫平台 前台RCE漏洞复现(CVE-2024-0195)

0x01 产品简介 SpiderFlow是新一代爬虫平台,以图形化方式定义爬虫流程,以流程图的方式定义爬虫,不写代码即可完成爬虫,是一个高度灵活可配置的爬虫平台。 0x02 漏洞概述 SpiderFlow爬虫平台src/main/java/org/spiderflow/controller/FunctionController.java文件的Functi…

CMake入门教程【核心篇】设置和使用缓存变量

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 概述设置缓存变量使用缓存变量更改缓存变量完整代码示例实战使用技巧注意事项总结与分析

python第三方模块之yaml模块

安装: pip install PyYamlPyYaml 5.1之后,通过禁止默认加载程序(FullLoader)执行任意功能,该load函数也变得更加安全。 使用: config.yaml - 10 - 20 - 30 - 40 - 50 --- name: cc age:<

关于git使用的tips

前言 这里是一些git指令使用的tips&#xff0c;如果你作为初学者的话&#xff0c;我认为它将对你有所帮助。 常见指令 常见问题处理 1、使用git clone下载【huggingface.co】资源超时或无法请求问题 绝大多数情况是网络问题&#xff0c;首先如果是比较大的资源&#xff0c;你需…

计算机网络-各层协议

大家在搞嵌入式开发的时候基本都了解过七层网络协议、五层网络协议、四层网络协议&#xff0c;那么今天让我们更加的深入了解一下&#xff1a; 历史发展介绍 OSI七层模型由ISO国际标准化组织提出的通信标准。TCP/IP四层模型是OSI七层模型的简化版&#xff0c;OSI在它被官方完…
最新文章