文章目录
1. 简单签名校验
签名校验通常在 APP 启动阶段(Application 或 SplashActivity 的 onCreate() 中)执行,用于验证当前 APK 的签名是否与官方一致,防止应用被二次打包或篡改。
2. 涉及的核心类
| 类 | 作用 |
|---|---|
| Context | 保存应用环境信息,提供系统服务访问接口 |
| PackageManager | 获取安卓系统信息和已安装 APP 的信息 |
| Signature | 表示应用签名信息,用于签名验证 |
3. 核心 API
context.getPackageManager()
.getPackageInfo(context.getPackageName(), 64)
.signatures[0]
.hashCode()
3.1. 参数说明
| 参数 | 说明 |
|---|---|
context | 应用上下文,提供环境信息 |
getPackageManager() | 获取包管理器 |
getPackageName() | 获取当前应用的包名 |
64 | 等于 PackageManager.GET_SIGNATURES 常量 |
signatures[0] | 获取第一个签名(通常只有一个) |
hashCode() | 返回签名对象的哈希值(用于快速比较) |
4. 典型实现代码
public class SignCheck {
// 官方签名的 hashCode(预存值)
private static final int OFFICIAL_SIGN_HASH = 123456789;
public static boolean isSignatureValid(Context context) {
try {
PackageManager pm = context.getPackageManager();
PackageInfo packageInfo = pm.getPackageInfo(
context.getPackageName(),
PackageManager.GET_SIGNATURES
);
Signature[] signatures = packageInfo.signatures;
if (signatures != null && signatures.length > 0) {
int currentSignHash = signatures[0].hashCode();
return currentSignHash == OFFICIAL_SIGN_HASH;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
5. 签名校验调用时机
APP 启动
│
▼
Application.onCreate()
│
├── 执行签名校验
│ ├── 校验通过 → 继续启动
│ └── 校验失败 → 退出 APP
│
▼
SplashActivity.onCreate()
│
├── 执行签名校验(二次校验)
│
▼
MainActivity.onCreate()
6. 签名相关类关系图 ***
┌─────────────────────────────────────────────────────┐
│ Context │
│ (应用环境信息) │
│ │ │
│ ▼ │
│ getPackageManager() │
│ │ │
│ ▼ │
│ PackageManager │
│ (包管理器) │
│ │ │
│ ▼ │
│ getPackageInfo() │
│ │ │
│ ▼ │
│ PackageInfo │
│ (包信息) │
│ │ │
│ ▼ │
│ signatures[] │
│ │ │
│ ▼ │
│ Signature │
│ (签名对象) │
│ │ │
│ ▼ │
│ hashCode() / toByteArray() │
└─────────────────────────────────────────────────────┘
7. 逆向分析方法
根据现象正向分析代码流程:
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 定位签名校验代码 | 搜索 signatures、hashCode、PackageManager.GET_SIGNATURES 等关键字 |
| 2 | 分析校验逻辑 | 找到签名的对比值(硬编码或网络获取) |
| 3 | 分析校验失败后的行为 | 是否有弹窗、退出、崩溃等 |
| 4 | 定位调用链 | 从 Application.onCreate() 开始追踪 |
8. 拓展阅读
8.1. Context
- 保存应用环境信息,是 Android 四大组件和系统服务的桥梁
- https://www.jianshu.com/p/0599b060e074
- https://blog.csdn.net/bendan50/article/details/80142612
- https://developer.android.com/reference/kotlin/android/content/Context
8.2. PackageManager
- 包管理器,获取安卓系统信息和 APP 的信息
- https://www.cnblogs.com/travellife/p/3932823.html
- https://developer.android.com/reference/kotlin/android/content/pm/PackageManager
8.3. Signature
9. 重打包APK、签名
9.1. 反编译工具:Apktool
Apktool 是一款开源的 APK 反编译工具,主要用于解包和重新打包 APK 文件。
| 项目 | 说明 |
|---|---|
| 官方地址 | https://ibotpeaches.github.io/Apktool/ |
| 开发语言 | Java |
| 主要功能 | 反编译 APK → smali 代码 + 资源文件,并支持重新打包 |
| 适用场景 | 修改资源文件、Smali 代码注入、重打包签名 |
9.2. 基本使用命令
9.2.1. 反编译 APK
apktool d test.apk
| 参数 | 说明 |
|---|---|
d | decode,反编译命令 |
test.apk | 要反编译的 APK 文件路径 |
执行后会生成一个 test/ 目录,包含反编译后的文件结构。
9.2.2. 重打包成 APK
apktool b test
| 参数 | 说明 |
|---|---|
b | build,构建/重打包命令 |
test | 刚才反编译生成的文件夹路径 |
执行后会在 test/dist/ 目录下生成重新打包的 APK 文件。
9.3. 反编译后的文件结构
test/
├── AndroidManifest.xml # 清单文件(可读)
├── apktool.yml # 元信息
├── res/ # 资源文件(可修改)
├── smali/ # smali 代码(可修改)
│ └── com/example/app/
├── smali_classes2/ # 多 DEX 的 smali
├── lib/ # Native 库
├── assets/ # 原始资源
└── unknown/ # 其他未知文件
9.4. 优缺点分析
| 优点 ✅ | 缺点 ❌ |
|---|---|
| 支持重打包 APK | 仅命令行操作,无可视化界面 |
| 可以修改 smali 代码和资源文件 | 不方便分析 Java 代码逻辑 |
| 开源免费 | 对近一两年的新版 APK 反编译时容易报错 |
| 支持 AndroidManifest.xml 还原 | 难以理解复杂混淆逻辑 |
| 跨平台(Java 运行环境) | 需要额外配合其他工具(如 JADX)分析代码 |
9.5. 常见错误及解决
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
Exception in thread "main" | 资源解析失败 | 添加 -r 参数跳过资源 |
Could not decode arsc file | 新版资源格式 | 更新 Apktool 到最新版 |
No resource found | Framework 缺失 | 安装对应的 framework |
Invalid resource | 混淆资源 | 尝试 -r 或 -d 参数 |
9.6. 常用进阶参数
# 反编译时跳过资源(只提取 smali 代码)
apktool d test.apk -r
# 反编译时强制覆盖已存在的目录
apktool d test.apk -f
# 反编译时保留原始 AndroidManifest.xml
apktool d test.apk -p
# 安装 Framework(解决系统框架依赖)
apktool if framework-res.apk
9.7. 典型工作流程
原始 APK
│
▼
apktool d test.apk ──► 解包
│
▼
修改 smali / 资源文件
│
▼
apktool b test ──► 重打包
│
▼
生成 new.apk
│
▼
签名 + Zipalign
│
▼
安装测试
9.8. 反编译图形化工具Batch apktool 3.8.0
文章地址:https://www.52pojie.cn/thread-2016201-1-1.html
9.9. 总结
Apktool 是 APK 重打包场景下的核心工具,适合需要修改 smali 代码或资源的场景。但对于纯粹的代码分析,建议配合 JADX 等其他可视化工具一起使用。
10. frida定位签名校验
10.1. 列出所有运行中的应用
# 列出所有正在运行的应用
frida-ps -Ua
10.2. hook脚本
Java.perform(function() {
console.log('start hook...');
var Signature = Java.use("android.content.pm.Signature");
Signature.hashCode.implementation = function() {
// 此应用没有使用hashCode方法,所以hook不到
console.log('[Hook] hashCode...');
return this.hashCode();
};
Signature.toByteArray.implementation = function() {
// 使用此方法可hook到
console.log('[Hook] toByteArray...');
// 通过堆栈获取调用方
printStack();
return this.toByteArray();
};
// 打印调用堆栈
function printStack() {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()))
}
// 通过hook方式将签名验证方法强制返回true
var AA = Java.use("类的完整包名路径");
AA.a.overload('android.content.Context').implementation = function() {
return true;
};
});
10.3. 修改apk方式绕过签名校验
10.3.1. 修改smali代码,重新打包
.method static a(Landroid/content/Context;)Z
.locals 1
.prologue
# 直接返回 true,绕过签名校验
const/4 v0, 0x1
return v0
.end method
10.3.2. 重新打包后的apk

感谢关注【遇事不決洛必達】!欢迎点赞收藏和交流指正,我会持续分享我的学习经验和心得。
1494

被折叠的 条评论
为什么被折叠?



