某直装外挂卡密校验逆向分析

2023-11-08

前言

最近分析了一款外挂软件的卡密校验,过程挺有趣的,故记录下来。

正文

该软件的界面如下图:

在这里插入图片描述

登录卡密是该界面的一个按钮,首先是获取该界面的类名,如下:

在这里插入图片描述

该界面所在的类是com.app.batman.MainActivity,获取到该界面所在的类之后,下一步的目标是定位到发送请求的方法,这一次我的定位方法不同于以往,以前我的定位方法是搜索字符串或者hook关键函数打印调用栈,这一次我所采用的方法是trace,那么什么是trace呢?hook了大量的函数就是trace,使用的脚本是r0trace(项目地址)。我trace了MainActivity类下的所有的函数,从而定位到SignUp这个关键函数,如下图:

在这里插入图片描述

在jadx中反编译的代码如下:

在这里插入图片描述

该方法是一个native方法,所以要找到注册该函数的so文件,首先我们假设它是动态注册的,因此可以使用frida hook RegistNatives,这里使用yang神的脚本(项目地址),运行结果如下:

在这里插入图片描述

发现找不到SignUp函数,那么该函数大概率是静态注册的,那么静态注册的方法该如何定位so文件呢?可以使用frida-trace,还需要注意,静态注册的函数命名是有规则的:Java_ + 包名 + 类名 + 方法名,并且".“都替换成”_",运行结果如下:

在这里插入图片描述

可以看到,静态注册该函数的so文件是ban,命名很奇怪,在jadx中找到该so文件的加载位置,如下:

在这里插入图片描述

ban文件是经过System.load进行动态加载的,一般都是把该文件进行加密,然后在动态加载是进行解密,先把cache目录下的ban文件放在IDA中看一眼,如下:

在这里插入图片描述

我采取的对抗手段是dump出内存中的ban文件,因为程序已经运行起来了,这时候内存中的ban文件是已经解密了的,frida dump脚本如下:

function dumpso(so_name){
    var libso = Process.findModuleByName(so_name);
    if (libso == null) {
        return -1;
    }
    Memory.protect(ptr(libso.base), libso.size, 'rwx');
    var libso_buffer = ptr(libso.base).readByteArray(libso.size);
    libso.buffer = libso_buffer;
    var f = new File("/data/data/com.tencent.tmgp.pubgmhd/cache/ban.so","wb")
    f.write(libso.buffer)
    f.flush()
    f.close()
    console.log("success dump ban.so")
    console.log("ban.so base address --> " + libso.base)
}
function main(){
    dumpso("ban")
}
setImmediate(main)

在这里插入图片描述

但这个时候的so是不能分析的,还需要修复一下,修复工具使用的是elf-dump-fix(项目地址),把修复后的so文件放进IDA中进行反编译,SignUp的伪代码如下:

在这里插入图片描述

发现已经能够正常识别了,下面就是找到发送请求的逻辑,关键代码如下:

在这里插入图片描述

上面图中标注的很清楚了,核心逻辑就是判断响应体中的内容的长度是否为32,如果长度为32位,则卡密校验成功,否则卡密校验失败。卡密校验成功之后调用了MainActivity类下面的TOAC方法,下面看看该函数的逻辑:

在这里插入图片描述

代码很简单,就是开启了一个服务,那么有没有什么办法看到服务开启后的效果呢?很简单,使用frida进行主动调用就行了,脚本代码及运行效果如下:

在这里插入图片描述

在这里插入图片描述

在主动调用了TOAC方法之后,外挂的功能模板就弹出来了。那么我们只要修改登录卡密之后的逻辑,让其不论校验成功还是校验失败都调用TOAC方法,这样也就绕过了卡密的校验,具体的过程不再展示。

修改并重打包之后,功能一切正常,但在点开绘制初始化开关之后软件直接闪退了,因此可以判断该软件有签名校验。那么我判断的依据是什么呢?很简单,就是之前我使用frida进行主动调用过卡密校验的时候软件并没有闪退,开关也能正常打开,但是在重打包之后打开开关就闪退。

下面开始绕过签名校验,首先尝试在jadx中搜索signatures,如下:

在这里插入图片描述

直接根据包名进行过滤,在java层中并没有我们想要的结果,那么在ban这个so文件里面进行搜索,如下:

在这里插入图片描述

可以看到,程序调用了android.content.pm.Signature类下的hashcode方法获取了签名的hash值,并且拿该值与一个特定的值进行比较,如果不相等则直接退出程序,因此这里就是签名校验的关键点。

既然找到了程序校验签名的逻辑,那么我们该如何绕过呢?起初我想的是直接修改so文件,把exit的调用直接nop掉,但是别忘了这个so文件是从内存中dump出来的,其原本的状态是加密的,所以是没办法直接进行修改。那么就可以写xposed模块,去hook hashcode这个方法,让其返回那个正确的hash值,这样也能绕过检验。但是考虑到使用Xposed的环境要求比较苛刻,需要手机进行root,因此我也抛弃了这个方案。

其实即使不root也是能够去hook的,这个方案也被许多知名的软件应用了,比如太极、VirtualXposed、应用转生等等,这也就是我采用的方案,我使用的AOP框架是epic(项目地址),核心代码如下:

在这里插入图片描述

然后把编译好的dex文件添加进软件中,并主动调用这段代码也就实现了非root下的hook。

重打包后程序正常运行,至此逆向分析结束。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

某直装外挂卡密校验逆向分析 的相关文章

随机推荐

  • 无锁和偏向锁有什么区别?

    无锁和偏向锁是 Java 中的两种轻量级锁实现 它们和重量级锁相比 具有更高的性能和更低的开销 它们之间的区别如下 无锁 CAS 自旋锁 无锁是一种不需要使用锁的同步技术 它的实现依赖于 CAS Compare And Swap 操作 通过
  • ARM:分散加载

    1 GCC编译器下的分散加载 ld文件 SECTIONS ram text flash start LOADADDR ram text ram text ram text start user iic o text ALIGN 4 All
  • AdaBoost算法实例详解

    提升树Boosting Tree算法实例详解 程大海的博客 CSDN博客 从提升树Boosting Tree过度到梯度提升Gradient Boosting 程大海的博客 CSDN博客 GBDT梯度提升之回归算法个人理解 程大海的博客 CS
  • Centos7.6安装docker

    一 环境准备 Docker 支持以下的 64 位 CentOS 版本 CentOS 7 CentOS 8 更高版本 二 安装步骤 1 如果是重装 则需要卸载旧版本 sudo yum remove docker docker client d
  • k8s flannel划分子网方案

    目标 对宿主节点划分子网 同时实现对不同应用划分子网 实现说明 部署k8s时 划分宿主节点ip 对每个节点配置不同net conf json 这样pod调度到宿主节点时 根据net conf json内的network配置分配ip 实现po
  • git基本使用

    1 git init 初始化本地仓库 2 git add 或文件名 暂存 3 git commit m 自己定名字 4 git status 查看 5 git remote add origin https github com xxx 6
  • 强化学习之混合动作空间

    强化学习之混合动作空间 基本介绍 在强化学习的动作空间设定中有连续动作空间 离散动作空间和混合动作空间 在大多数的论文中研究的都是连续动作空间和离散动作空间 而混合动作空间研究的比较少 在游戏ai 自动驾驶等一些领域中有时动作空间可以是混合
  • 安装Elasticsearch

    gt 安装 1 创建基础环境 环境 centos7 9 es版本 7 13 3 按照如下的步骤一步步走 就可以正常完成安装 groupadd es useradd es g es p es123 cd home mkdir p elk es
  • nuxt.js局部引用quill富文本编辑器

    想在nuxt js中使用quill富文本编辑器 按照网上常见的方法 将css js 添加到 nuxt config js 这是全局调用了quill的css js 文件 在每个页面的源码中 都可以看到quill 的css js 这是没有必要的
  • 老板让你做性能优化,第一步你应该做什么?

    前言 项目的性能决定了用户对项目的整体感观度 优秀的性能可以保证项目的流畅与自然给用户愉快的体验感受 当我们开发完成一个项目以后最重要的环节就是要保证项目拥有一个良好的性能 所以开发完成以后需要我们针对项目做好性能优化 那么 要使一个项目拥
  • 大模型杀手级场景到底什么会到来

    大模型大潮之下 熙熙攘攘 皆为利来 皆为利往 所以很多人观望之后发现到现在还没有杀手级落地场景 便有些不耐烦了 觉得可能又是一股泡沫 但究竟是不是泡沫 需要从宏观角度分析下当前大模型的现状 笔者认为这种不耐烦其实来源于两个原因 1 天下事
  • 最适合零基础的爬虫教程,从零开始教你爬取十万表情包。非常简单。

    前言 事情要从几天前说起 我有一个朋友 他在和他喜欢的小姐姐聊天时 聊天的气氛一直非常尬 这时他就想发点表情包来缓和一下气氛 但一看自己的表情包收藏都是这样的 这发过去 基本就直接和小姐姐说拜拜了 然后他就向我求救问我有没有表情包 表情包我
  • 1、TCP三次握手、四次挥手;2、ADSL定义

    1 TCP三次握手 四次挥手详解 1 建立连接协议 三次握手 1 客户端发送一个带SYN标志的TCP报文到服务器 这是三次握手过程中的报文1 2 服务器端回应客户端的 这是三次握手中的第2个报文 这个报文同时带ACK标志和SYN标志 因此它
  • Appium 全新 2.0 全新跨平台生态,版本特性抢鲜体验!

    关于Appium V2 Appium V2 beta版本在2021年发布 从2022年1月1号开始 Appium核心团队不会再维护Appium 1 x版本了 所有近期官方发布的平台驱动 如Android平台的UIAutomator IOS平
  • W801上电自动重连wifi并通过蓝牙更新账号密码

    一 项目流程 项目整体思路比较简单 W801上电后读取内部flash中保存在固定位置的Wifi账号密码 同时开始蓝牙 每当蓝牙接收到命令后 就对其进行解析 如果为连接wifi命令 则断开当前wifi 并进行新的wifi连接 连接成功后将账号
  • 使用pkg打包Node.js应用:跨平台运行你的应用程序!

    使用pkg打包Node js应用 跨平台运行你的应用程序 你是否曾经遇到过在不同操作系统中运行同一个Node js应用程序时出现的问题 这是因为Node js不具备跨平台能力 所以需要一个打包工具来解决这个问题 幸运的是 有一个名为pkg的
  • 颜色、形状和纹理:使用 OpenCV 进行特征提取

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 如何从图像中提取特征 第一次听说 特征提取 一词是在 YouTube 上的机器学习视频教程中 它清楚地解释了我们如何在大型数据集中提取特征 很简单 数据集的列就是特征 然
  • Error: Command failed: C:\windows\system32\cmd.exe /s /c "E:\programfiles\androidSDK\platform-tools\...

    问题 appium等自动化环境都安装配置号后 遇到如下问题 Error Command failed C windows system32 cmd exe s c E programfiles androidSDK platform too
  • 基于深度学习的指针式仪表图像智能读数方法

    针对传统图像处理的仪表识别方法鲁棒性较差 难以满足复杂环境下的指针式仪表图像读数 而深度学习的方法通过样本的训练能够适应更多的复杂场景 越来越多的仪表读数解决方案更偏向于使用深度学习的方法 而现在的基于深度学习的方法在仪表识别的解决方案中主
  • 某直装外挂卡密校验逆向分析

    前言 最近分析了一款外挂软件的卡密校验 过程挺有趣的 故记录下来 正文 该软件的界面如下图 登录卡密是该界面的一个按钮 首先是获取该界面的类名 如下 该界面所在的类是com app batman MainActivity 获取到该界面所在的