【安卓逆向】Apk反编译和Frida定位签名校验

1. 简单签名校验

签名校验通常在 APP 启动阶段ApplicationSplashActivityonCreate() 中)执行,用于验证当前 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定位签名校验代码搜索 signatureshashCodePackageManager.GET_SIGNATURES 等关键字
2分析校验逻辑找到签名的对比值(硬编码或网络获取)
3分析校验失败后的行为是否有弹窗、退出、崩溃等
4定位调用链Application.onCreate() 开始追踪

8. 拓展阅读

8.1. Context

8.2. 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
参数说明
ddecode,反编译命令
test.apk要反编译的 APK 文件路径

执行后会生成一个 test/ 目录,包含反编译后的文件结构。

9.2.2. 重打包成 APK
apktool b test
参数说明
bbuild,构建/重打包命令
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 foundFramework 缺失安装对应的 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

在这里插入图片描述


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遇事不決洛必達

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值