从APKiD看APK壳检测
字数 854 2025-08-22 12:22:48
APKiD工具详解:APK壳检测原理与实践
一、APKiD简介
APKiD是一款用于分析APK文件构建信息的工具,能够识别多种编译器、打包器、混淆器和其他特征。它类似于Windows平台上的PEiD工具,但专门针对Android APK文件。
项目特点:
- 参加过BlackHat会议(工具介绍和快速识别RASP SDK)
- 使用Yara规则进行特征匹配
- 开源项目,地址:https://github.com/rednaga/APKiD
二、环境搭建
安装方式
-
pip安装(最简单的方式):
pip install apkid 安装后可直接使用`apkid`命令 -
源码安装(适合调试和开发):
git clone https://github.com/rednaga/APKiD cd APKiD ./prep-release.py
基本使用示例
from apkid.apkid import Options, Scanner
def loader_apkid(apk_path):
options = Options(json=True)
rules = options.rules_manager.load()
scanner = Scanner(rules, options)
scanner.scan(apk_path)
if __name__ == '__main__':
loader_apkid("./tmp/litiaotiao.apk")
三、前置知识
APK文件结构
APK本质上是ZIP格式文件,主要包含以下部分:
META-INF/ # 数字签名信息
MANIFEST.MF
CERT.SF
CERT.(RSA|DSA)
res/ # 资源文件
assets/ # 运行时读取的原始资源
lib/ # 原生库文件(*.so),按CPU架构分类
AndroidManifest.xml # 清单文件
classes.dex # 可执行DEX字节码
resources.arsc # 编译后的资源表
Yara规则系统
Yara是一个开源工具,主要用于恶意软件识别和分类,但也可用于其他特征值识别。
Yara规则组成:
- meta:元数据(描述、作者等)
- strings:要匹配的字符串
- condition:匹配条件(布尔表达式)
示例规则(腾讯乐固壳检测):
rule tencent_legu : packer {
meta:
description = "Tencent's Legu"
url = "https://blog.quarkslab.com/a-glimpse-into-tencents-legu-packer.html"
sample = "9ff3a53f76c7a6d7e3de3b8567c9606f2cc08ec4aaaae596a27361018d839c58"
author = "Mert Arıkan"
strings:
$a = "assets/tosversion"
$b = "assets/0OO00l111l1l"
$c = "assets/0OO00oo01l1l"
$d = "assets/o0oooOO0ooOo.dat"
condition:
is_apk and $b and ($a or $c or $d)
}
is_apk基础规则:
rule is_apk : file_type {
meta:
description = "APK"
strings:
$zip_head = "PK"
$manifest = "AndroidManifest.xml"
condition:
$zip_head at 0 and $manifest and #manifest >= 2
}
四、APKiD工作原理
核心扫描流程
主要实现在scan_file_obj方法中:
def scan_file_obj(self, file: IO, file_path: str = '$FILE$'):
if file_path == '$FILE$':
file_name = file_path
else:
file_name = os.path.basename(file_path)
results: Dict[str, List[yara.Match]] = {}
if not self._should_scan(file, file_name):
return results
matches: List[yara.Matches] = self.rules.match(
data=file.read(),
timeout=self.options.timeout
)
if len(matches) > 0:
results[file_path] = matches
if self._is_zipfile(file, file_name):
with zipfile.ZipFile(file) as zf:
zip_results = self._scan_zip(zf)
for entry_name, entry_matches in zip_results.items():
results[f'{file_path}!{entry_name}'] = entry_matches
return results
文件扫描判断逻辑
def _should_scan(self, file: IO, name: str) -> bool:
if self.options.typing == 'magic':
file_type = Scanner._type_file(file)
return file_type is not None
elif self.options.typing == 'filename':
name = name.lower()
return name.startswith('classes') \
or name.startswith('AndroidManifest.xml') \
or name.startswith('lib/') \
or name.endswith('.so') \
or name.endswith('.dex') \
or name.endswith('.apk')
return True
五、与其他工具对比
传统APK扫描工具通常使用硬编码的字典进行匹配:
self.protectflag_dict = {
"libsecexe.so": u"该APK已加固=>梆梆梆梆加固",
"libAPKProtect.so": u"该APK已加固=>APKProtect加固",
"libprotectClass.so": u"该APK已加固=>360加固",
"libNSaferOnly.so": u"该APK已加固=>通付盾加固",
"libnqshield.so": u"该APK已加固=>网秦加固",
"libshell.so": u"该APK已加固=>腾讯加固",
"ijiami.dat": u"该APK已加固=>爱加密加固",
"libddog.so": u"该APK已加固=>娜迦加固",
"libmobisec.so": u"该APK已加固=>阿里加固",
"libbaiduprotect.so": u"该APK已加固=>百度加固"
}
APKiD的优势:
- 使用Yara规则,更加灵活
- 可以检测更复杂的特征组合
- 规则易于扩展和维护
六、扩展学习
-
Yara规则编写指南:
如何编写简单合理的Yara规则 -
APKiD规则目录:
项目中的rules文件夹包含所有检测规则,可以学习现有规则或添加新规则 -
BlackHat 2018演讲:
了解APKiD在BlackHat上的详细介绍和案例分析
七、实践建议
-
自定义规则开发:
- 研究目标加固方案的特征
- 编写针对性的Yara规则
- 测试规则的有效性
-
批量扫描:
可以结合Python脚本实现APK文件的批量扫描和分析 -
结果分析:
APKiD的输出结果可以与其他工具(如Jadx、Ghidra等)结合进行深入分析