安卓逆向入门四
关键词:apk签名、apk校验及对抗方法、PM代理、io重定向
学习链接:https://www.52pojie.cn/thread-1731181-1-1.html
0x00 APK签名
校验是开发者在数据传送时采用的一种校正数据的一种方式 常见的校验有:签名校验(最常见)、dexcrc校验、apk完整性校验、路径文件校验等
什么是APK签名?
我建议直接去看 Android 官方文档 中关于 APK签名 的安全特性介绍。
- APK签名是开发者使用私钥对安卓应用进行数字签名的过程,确保应用的完整性和来源,防止被篡改。只有经过签名的应用才能在安卓设备上安装和运行,签名还帮助系统识别应用的开发者,并确保应用在独立的沙盒环境中安全运行。
- Android 目前支持以下四种应用签名方案: v1 方案:基于 JAR 签名。 v2 方案:APK 签名方案 v2(在 Android 7.0 中引入) v3 方案:APK 签名方案 v3(在 Android 9 中引入) v4 方案:APK 签名方案 v4(在 Android 11 中引入)
| 签名方案 | 推出版本 | 校验范围 | 安全优势 | 局限性 | 适用场景 |
|---|---|---|---|---|---|
| v1(JAR 签名) | Android 1.0 | 仅校验 APK 内单个文件(META-INF 下签名文件) | 兼容所有安卓版本 | 可篡改未签名文件(如新增文件) | 需兼容 Android 6.0 及以下设备 |
| v2 | Android 7.0 | 校验整个 APK(通过 “签名块” 校验 APK 完整性) | 更高效(无需解压)、防篡改新增文件 | 不兼容 Android 6.0 及以下 | 目标设备为 Android 7.0+ |
| v3 | Android 9.0 | 在 v2 基础上支持 “签名轮换”(更换签名无需卸载旧版) | 支持签名更新(如企业应用换证书) | 依赖 Android 9.0+ | 需要签名更新的应用(如企业级 APP) |
| v4 | Android 11.0 | 生成单独的签名文件(.apksig),支持增量更新校验 | 优化大文件安装效率(仅校验变更部分) | 依赖 Android 11.0+ | 大型应用(如游戏)的增量更新 |
- v4签名生成的
.apksig文件必须配合adb install --incremental使用,常规APK安装不会触发此校验。逆向中较少遇到,主要用于Google Play增量更新。 - 一次让你搞懂Android应用签名 这篇文章讲了签名步骤和原理相关知识,值得一看
APP 的签名检验
系统更多的只是对 APK 做完整性校验,身份校验很容易通过卸载方式来解决,因此许多 APP 为了防止自身被修改和破解,会对自身进行额外的校验,确保没有被修改。
我们一般称此类检查自身是否被修改的保护技术为签名校验,其校验原理几乎也都是基于文件完整性检验与签名身份信息验证。
|
|
普通获取签名校验代码:
|
|
系统将应用的签名信息封装在PackageInfo中,调用 PackageManager 的getPackageInfo(String packageName, int flags)即可获取指定包名的签名信息.
0x01 签名校验对抗
方法一:核心破解插件,不签名安装应用 方法二:一键过签名工具,例如MT、NP、ARMPro、CNFIX、Modex的去除签名校验功能 方法三:具体分析签名校验逻辑(手撕签名校验) 方法四:io重定向–VA&SVC:ptrace+seccomp SVC的TraceHook沙箱的实现&无痕Hook实现思路 方法五:去作者家严刑拷打拿到.jks文件和密码
0x02 手动实现PM代{过}{滤}理
1.什么是PMS
思路源自:Android中Hook 应用签名方法
PackageManagerService(简称PMS),是Android系统核心服务之一,处理包管理相关的工作,常见的比如安装、卸载应用等。
核心原理
- 安卓应用获取签名的流程:
应用调用PackageManager.getPackageInfo()→ 系统通过PMS(PackageManagerService)查询签名信息并返回; - PM 代理的本质:通过 Hook 替换
PMS的返回结果 —— 当应用查询签名时,返回原始合法签名(而非修改后 APK 的签名),从而绕过校验。
使用条件与限制
- 环境要求:需要 root 权限(修改系统服务)或通过 Xposed/LSPosed 框架(无需 root,但需模块支持);
- 局限性:仅对通过
PackageManager获取签名的校验有效,若应用直接读取 APK 文件计算签名(如读取/data/app/xxx.apk的签名),则 PM 代理无效(需结合IO重定向,将应用访问的APK路径(如/data/app/包名/base.apk)重定向到保留原始签名的伪造APK文件(仅包含签名所需文件,如META-INF/)。
2.实现方法以及原理解析
HOOK PMS代码:
|
|
ActivityThread的静态变量sPackageManager
ApplicationPackageManager对象里面的mPM变量
0x03 IO重定向
什么是IO重定向?
I/O重定向是指改变程序的标准输入(stdin)、标准输出(stdout)和标准错误输出(stderr)的默认设备,将其与其他设备或文件进行关联。通过I/O重定向,我们可以将程序的输入从键盘转向文件或其他设备,将程序的输出和错误信息输出到文件或其他设备而不是屏幕上。
例:在读A文件的时候指向B文件
平头哥的核心代码 Virtual Engine for Android(Support 12.0 in business version)
IO重定向可以干嘛?
1,可以让文件只读,不可写
2,禁止访问文件
3,路径替换
具体实现: 过签名检测(读取原包) 风控对抗(例:一个文件记录App启动的次数) 过Root检测,Xposed检测(文件不可取)
|
|
|
|
0x04 其他常见校验
root检测:
反制手段 1.算法助手、对话框取消等插件一键hook 2.分析具体的检测代码 3.利用IO重定向使文件不可读 4.修改Andoird源码,去除常见指纹
|
|
定义了一个 isDeviceRooted() 函数,该函数调用了三个检测 root 的方法:checkRootMethod1()、checkRootMethod2() 和 checkRootMethod3()。
checkRootMethod1() 方法检查设备的 build tags 是否包含 test-keys。这通常是用于测试的设备,因此如果检测到这个标记,则可以认为设备已被 root。
checkRootMethod2() 方法检查设备是否存在一些特定的文件,这些文件通常被用于执行 root 操作。如果检测到这些文件,则可以认为设备已被 root。
checkRootMethod3() 方法使用 Runtime.exec() 方法来执行 which su 命令,然后检查命令的输出是否不为空。如果输出不为空,则可以认为设备已被 root。
模拟器检测
|
|
通过检测系统的 Build 对象来判断当前设备是否为模拟器。具体方法是检测 Build.FINGERPRINT 属性是否包含字符串 "generic"。
反调试检测
- 安卓系统自带调试检测函数
|
|
- debuggable属性
|
|
- ptrace检测
|
|
每个进程同时刻只能被1个调试进程ptrace ,主动ptrace本进程可以使得其他调试器无法调试
- 调试进程名检测
|
|
- frida检测
0x05 smali语法—–赋值
1.Int型赋值
|
|
const/4和const/16的区别?
-
const/4 最大只允许存放4个二进制位(4bit),
-
const/16 最大值允许存放16个二进制位(16bit), 第一位(即最高位)默认为符号位。单位换算 1byte=8bit 举例说明下寄存器的取值范围: # 以下数据定义高位默认为符号位
-
const/4 v0,0x2 # 最大只允许存放半字节数据 取值范围为 -8 and 7
-
const/16 v0 , 0xABCD # 定义一个寄存器变量,最大只允许存放16位数据 比如short类型数据 取值范围为-32768~32767
-
const v0 , 0xA# 定义一个寄存器, 最大只允许存放32位数据,比如int类型数据 将数字10赋值给v0 取值范围-2147483647~2147483647
-
const/high16 #定义一个寄存器, 最大只允许存放高16位数值 比如0xFFFF0000末四位补0 存入高四位0XFFFF
2.Long型赋值
const-wide vx, lit32 表示将一个 32 位的常量存储到 vx 与 vx+1 两个寄存器中 —— 即一个 long 类型的数据
|
|
-会员到期时间就是2022年12月24日。那么1854460ef29L 怎么来的呢?也就是(2022年12月24日-1970年1月1日)×365天×24小时×60分钟×60秒×1000毫秒,转换成16进制就大概是那个数了
3.变量赋值(正则)
|
|
- *. ** 这个表示任意寄存器,什么寄存器都能匹配,所以你正则查找的时候只需把寄存器替换成这个就可以了
- (.*) 这里多了个英文小括号,框哪个就是对哪个寄存器赋值。
参考文章:
APK 签名:v1 v2 v3 v4 如何把签名校验做到极致 Android PMS HOOK [实战破解]白描-动态代{过}{滤}理Hook签名校验 [原创]对安卓反调试和校验检测的一些实践与结论 新版MT去签及对抗 【小白教程】正则匹配的写法 多行匹配 批量赋值 smali逆向 简单实用