apk加固工具探究系列——Obfuscapk
字数 2173 2025-08-22 12:22:24
Obfuscapk APK加固工具深入解析与教学指南
一、Obfuscapk概述
Obfuscapk是一个基于Python实现的模块化APK混淆工具,采用插件系统架构设计,具有以下核心特点:
- 模块化设计:每个混淆器都是一个独立插件,继承自抽象基类(obfuscator_category.py)
- 易于扩展:添加新混淆器只需在src/obfuscapk/obfuscators目录中添加实现代码和元数据文件
- 处理流程:
- 命令行参数处理(cli.py)
- 主逻辑(main.py中的perform_obfuscation函数)
- 创建obfuscation对象存储所有信息(obfuscation.py)
- 依次调用各插件对APK进行处理
二、核心混淆技术详解
1. 基础处理模块
- NewAlignment:重新对齐APK
- NewSignature:重新签名APK
- Rebuild:重新构建APK
- VirusTotal:将混淆前后APK发送至VirusTotal检测
2. 简单混淆技术
- Nop:在smali代码中添加nop指令
- DebugRemoval:删除调试信息
- RandomManifest:重新排列AndroidManifest.xml文件
- Goto:在方法开头和结尾添加互跳的goto指令
- Reorder:反转分支条件并重新排列代码
- MethodOverload:利用Java重载特性创建同名方法,添加随机参数和算术指令
3. 高级混淆技术
(1) ArithmeticBranch - 算术分支混淆
- 实现原理:
- 插入形式如
(a+b)%b >= 0的永真条件 - 添加永远不会执行的分支跳转
- 插入形式如
- 示例:
# 原始代码 invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String; # 混淆后 add-int v1, v2, v3 rem-int v1, v1, v3 if-gez v1, :cond_0 invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String; goto :cond_1 :cond_0 nop :cond_1
(2) AssetEncryption/LibEncryption - 资源加密
- 实现原理:
- 对asset/lib文件进行AES加密
- 替换
assetManager.open为自定义解密函数 - 自动添加解密相关的smali代码
- 加密流程:
- 检测assetManager.open调用
- 加密目标asset文件
- 替换原始调用为解密函数
- 添加解密函数实现(如不存在)
(3) ConstStringEncryption - 字符串加密
- 实现原理:
- 加密字符串常量,运行时解密
- 添加解密函数调用
- 处理场景:
- const-string指令:
# 原始 const-string v0, "plaintext" # 混淆后 const-string/jumbo v0, "ciphertext" invoke-static {v0}, Lcom/decryptstringmanager/DecryptString;->decryptString(Ljava/lang/String;)Ljava/lang/String; move-result-object v0 - 静态字符串字段:
# 原始 .field static string_name:Ljava/lang/String; = "plaintext" # 混淆后 .field static string_name:Ljava/lang/String; # 在static constructor中添加 const-string/jumbo v0, "ciphertext" invoke-static {v0}, Lcom/decryptstringmanager/DecryptString;->decryptString(Ljava/lang/String;)Ljava/lang/String; move-result-object v0 sput-object v0, Lcom/example/Class;->string_name:Ljava/lang/String;
- const-string指令:
(4) 重命名混淆系列
ClassRename - 类名重命名
- 实现流程:
- 获取所有类名和smali文件映射
- 重命名包名(MD5前8位+"p")
- 重命名类定义(MD5前8位+"p")
- 处理内部类注解
- 更新smali和xml文件中的类引用
- 特殊处理:
- 跳过R类
- 处理AndroidManifest.xml中的String Chunk
MethodRename - 方法重命名
- 实现流程:
- 读取Android系统类名(android_class_names_api_27.txt)
- 获取需要忽略的方法(构造方法、native方法、抽象方法等)
- 重命名方法定义(MD5前8位+"m")
- 更新方法调用
- 忽略规则:
- 系统类中的方法
- 构造方法(
) - native方法
- 抽象方法
FieldRename - 字段重命名
- 实现流程:
- 识别SDK类(Landroid/, Ljava/)
- 处理multidex情况
- 重命名字段定义(MD5前8位+"f")
- 随机添加1-4个垃圾字段
- 更新字段引用
- 特殊处理:
- 可重命名SDK类中的字段(如有声明)
(5) CallIndirection - 方法间接调用
- 实现原理:
- 将直接方法调用改为通过中间方法间接调用
- 实现流程:
- 处理multidex情况
- 修改原始调用指向新方法
- 添加中间方法声明
- 在中间方法中调用原始方法
- 示例:
# 原始调用 invoke-direct {p0}, Lcom/example/Class;->targetMethod()V # 混淆后 invoke-direct {p0}, Lcom/example/Class;->m12345678()V # 添加的方法 .method private m12345678()V invoke-direct {p0}, Lcom/example/Class;->targetMethod()V return-void .end method
三、扩展开发指南
1. 开发新混淆器步骤
- 在
src/obfuscapk/obfuscators目录创建新插件 - 继承
obfuscator_category.py中的抽象基类 - 实现
obfuscate方法 - 添加插件元数据文件(
obfuscator-name.obfuscator)
2. 关键API说明
- obfuscation对象:存储APK反编译结果和混淆过程数据
decode_apk():调用apktool反编译APK- 包含AndroidManifest.xml、resources、assets、so文件等信息
- 通过正则匹配获取smali中的方法、变量、类等信息
3. 最佳实践建议
- 组合使用:多种混淆技术组合效果更佳
- 性能考量:注意ArithmeticBranch等混淆可能影响运行时性能
- 兼容性测试:重命名类/方法后需确保反射调用等仍能正常工作
- 二次开发:可在现有混淆基础上增强:
- 增加ArithmeticBranch复杂度
- 实现新型字符串加密
- 添加native层混淆
四、总结
Obfuscapk提供了Java层常见的全套混淆技术,包括:
- 字符串/资源加密
- 结构重命名(类/方法/字段)
- 控制流混淆(分支/跳转)
- 方法间接调用
通过模块化设计和清晰的扩展接口,开发者可以基于此工具快速实现定制化的APK保护方案或开发相应的反混淆工具。