MASTG-TECH-0019: 检索字符串
在执行任何类型的二进制分析时,字符串可以被认为是最有价值的起点之一,因为它们提供了上下文。例如,像“数据加密失败”这样的错误日志字符串会给我们一个提示,即相邻的代码可能负责执行某种加密操作。
Java 和 Kotlin 字节码¶
正如我们已经知道的,Android 应用程序的所有 Java 和 Kotlin 字节码都会被编译成 DEX 文件。每个 DEX 文件都包含一个 字符串标识符列表 (strings_ids),其中包含二进制文件中使用的所有字符串标识符,包括内部命名(例如,类型描述符)或代码引用的常量对象(例如硬编码的字符串)。您可以使用诸如 Ghidra(基于 GUI)或 Dextra(基于 CLI)之类的工具来简单地转储此列表。
使用 Ghidra,可以通过简单地加载 DEX 文件并在菜单中选择 Window -> Defined strings 来获取字符串。
直接将 APK 文件加载到 Ghidra 中可能会导致不一致。因此,建议通过解压缩 APK 文件来提取 DEX 文件,然后将其加载到 Ghidra 中。
使用 Dextra,您可以使用以下命令转储所有字符串
dextra -S classes.dex
可以使用标准 Linux 命令来操作 Dextra 的输出,例如,使用 grep
搜索某些关键字。
重要的是要知道,使用上述工具获得的字符串列表可能非常大,因为它还包括应用程序中使用的各种类和包名称。浏览完整列表,特别是对于大型二进制文件,可能会非常麻烦。因此,建议从基于关键字的搜索开始,并且仅当关键字搜索没有帮助时才浏览列表。一些通用的关键字可能是很好的起点 - password、key 和 secret。在使用应用程序本身时,可以获得其他有用的特定于应用程序上下文的关键字。例如,假设该应用程序有一个登录表单,您可以记下输入字段的显示占位符或标题文本,并将其用作静态分析的入口点。
本地代码¶
为了从 Android 应用程序中使用的本地代码中提取字符串,您可以使用诸如 Ghidra 或 iaito 之类的 GUI 工具,或者依赖于基于 CLI 的工具,例如 strings Unix 实用程序(strings <path_to_binary>
)或 radare2 的 rabin2 (rabin2 -zz <path_to_binary>
)。当使用基于 CLI 的工具时,您可以利用其他工具(例如 grep)(例如,与正则表达式结合使用)来进一步过滤和分析结果。