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

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

文章目录

    • 1. 简单签名校验
    • 2. 涉及的核心类
    • 3. 核心 API
      • 3.1. 参数说明
    • 4. 典型实现代码
    • 5. 签名校验调用时机
    • 6. 签名相关类关系图 ***
    • 7. 逆向分析方法
    • 8. 拓展阅读
      • 8.1. Context
      • 8.2. PackageManager
      • 8.3. Signature
    • 9. 重打包APK、签名
      • 9.1. 反编译工具:Apktool
      • 9.2. 基本使用命令
        • 9.2.1. 反编译 APK
        • 9.2.2. 重打包成 APK
      • 9.3. 反编译后的文件结构
      • 9.4. 优缺点分析
      • 9.5. 常见错误及解决
      • 9.6. 常用进阶参数
      • 9.7. 典型工作流程
      • 9.8. 反编译图形化工具Batch apktool 3.8.0
      • 9.9. 总结
    • 10. frida定位签名校验
      • 10.1. 列出所有运行中的应用
      • 10.2. hook脚本
      • 10.3. 修改apk方式绕过签名校验
        • 10.3.1. 修改smali代码,重新打包
        • 10.3.2. 重新打包后的apk

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. 典型实现代码

publicclassSignCheck{// 官方签名的 hashCode(预存值)privatestaticfinalintOFFICIAL_SIGN_HASH=123456789;publicstaticbooleanisSignatureValid(Contextcontext){try{PackageManagerpm=context.getPackageManager();PackageInfopackageInfo=pm.getPackageInfo(context.getPackageName(),PackageManager.GET_SIGNATURES);Signature[]signatures=packageInfo.signatures;if(signatures!=null&&signatures.length>0){intcurrentSignHash=signatures[0].hashCode();returncurrentSignHash==OFFICIAL_SIGN_HASH;}}catch(Exceptione){e.printStackTrace();}returnfalse;}}

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

  • 保存应用环境信息,是 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

  • 签名信息类
  • https://developer.android.com/reference/kotlin/android/content/pm/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 btest
参数说明
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.xmlapktool d test.apk-p# 安装 Framework(解决系统框架依赖)apktoolifframework-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...');varSignature=Java.use("android.content.pm.Signature");Signature.hashCode.implementation=function(){// 此应用没有使用hashCode方法,所以hook不到console.log('[Hook] hashCode...');returnthis.hashCode();};Signature.toByteArray.implementation=function(){// 使用此方法可hook到console.log('[Hook] toByteArray...');// 通过堆栈获取调用方printStack();returnthis.toByteArray();};// 打印调用堆栈functionprintStack(){console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()))}// 通过hook方式将签名验证方法强制返回truevarAA=Java.use("类的完整包名路径");AA.a.overload('android.content.Context').implementation=function(){returntrue;};});

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


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