11、字符串与资源分析:字符串编码识别、资源提取与修改、硬编码字符串定位

字符串分析,说白了就是跟程序里的文本打交道。我做了这么多年逆向,发现很多关键信息都藏在字符串里——协议地址、密钥片段、错误提示、甚至开发者留下的“彩蛋”。你想想看,一个程序跑起来,总得跟用户交互吧?那交互的文本,就是我们的突破口。

这一章,我带你系统地过一遍字符串与资源分析的核心技能。包括怎么识别编码、怎么提取和修改资源、以及怎么定位那些硬编码的字符串。嗯,都是实战中高频用到的。

11.1 字符串编码识别——别被乱码骗了

拿到一个二进制文件,第一件事就是看字符串。但直接搜出来的东西,经常是乱码。为什么会这样?因为编码不对。

常见的字符串编码有这么几种:

编码类型 特点 常见场景
ASCII 单字节,0x00-0x7F 老程序、配置文件
UTF-8 变长,兼容ASCII 现代跨平台软件
UTF-16LE 双字节,小端序 Windows原生API
GBK/GB2312 双字节,中文编码 国内老软件

我个人习惯,先用 strings 命令扫一遍,看看有没有明显的英文关键词。如果全是乱码,那就换 -e l 参数试试 UTF-16LE。我在项目中遇到过好几次,明明是个中文软件,字符串却用 UTF-16 存,用 ASCII 模式搜出来全是“烫烫烫”。

小技巧: 用 IDA 或 Ghidra 打开文件时,注意看字符串窗口的编码选项。IDA 默认会尝试多种编码,但有时候需要手动指定。我习惯在“Options”->“String literals”里把 UTF-16 和 UTF-8 都勾上。

11.2 资源提取与修改——动刀子的地方

资源文件,比如 PE 文件里的 .rsrc 段,或者 Android APK 里的 resources.arsc,都是字符串的“大本营”。提取资源,说白了就是把它们从二进制里“抠”出来。

常用的工具有:

  • Resource Hacker:Windows 上改 PE 资源的老牌工具,界面直观。
  • 7-Zip:可以直接打开 .exe 或 .msi 文件,提取内部资源。
  • apktool:反编译 APK,把 resources.arsc 解成 XML。
  • radare2:命令行下用 izizz 列出所有字符串。

修改资源时,有个坑要注意:长度限制。比如 PE 文件里的字符串资源,如果新字符串比原来的长,直接替换会破坏文件结构。我曾经在改一个软件的对话框文本时,把“确定”改成了“确认并继续”,结果程序直接崩溃了。后来才发现,资源表里每个字符串都有固定长度,超了就得重新调整 RVA 偏移。

警告: 修改资源前,一定要备份原文件。尤其是 PE 和 ELF 格式,资源表的结构很脆弱,改错了整个文件就打不开了。我建议先用十六进制编辑器(比如 010 Editor)看看资源段的布局,再动手。

11.3 硬编码字符串定位——找到那些“写死”的东西

硬编码字符串,就是程序员直接写在代码里的文本。比如 IP 地址、数据库连接串、加密密钥。这些东西不会出现在资源表里,而是直接嵌在代码段(.text)或数据段(.data)里。

定位硬编码字符串,我一般分三步走:

  1. 全盘扫描:用 strings -n 6 列出所有长度大于等于6的字符串,肉眼扫一遍。
  2. 交叉引用:在 IDA 里选中一个字符串,按 Ctrl+X 看哪些代码引用了它。这一步很关键,能帮你找到字符串的使用逻辑。
  3. 动态断点:如果字符串是运行时生成的,比如拼接出来的 URL,那就得用调试器下断点,看内存里的内容。

举个例子,我之前逆向一个恶意软件,它在内存里动态解密了一段字符串。静态扫描根本看不到明文。我是在 OD 里下了一个 CreateFileA 的断点,然后看堆栈里的参数,才抓到那个 C2 地址的。

核心思路: 硬编码字符串不一定都是明文。很多程序会用 XOR、Base64、甚至自定义算法加密。遇到这种情况,先找解密函数,再定位字符串。我习惯在 IDA 里搜索 xor 指令,或者找循环里带 0x20-0x7E 范围的代码,那往往是解密逻辑。

11.4 知识体系图

下面这张图,是我梳理的字符串与资源分析的整体流程。你可以把它当作一个检查清单:

字符串与资源分析流程 1. 编码识别 ASCII / UTF-8 / UTF-16 / GBK 2. 资源提取 Resource Hacker / apktool / 7-Zip 3. 硬编码定位 交叉引用 / 动态断点 资源修改(注意长度限制) 备份 → 调整RVA → 替换 加密字符串(XOR/Base64) 找解密函数 → 动态分析 动态生成字符串 API断点 → 内存快照 最终目标 提取关键信息(IP、密钥、协议、逻辑分支) 修改行为(汉化、破解、功能定制)

11.5 实战中的几个坑

最后,分享几个我踩过的坑,希望能帮你少走弯路:

  • 别信静态扫描的“全部结果”:有些字符串是编译时优化的结果,比如常量折叠。你看到的“Hello”可能根本不是字符串,而是某个指令的操作数。我习惯用 IDA 的“Make String”功能手动确认。
  • 注意 Unicode 的 BOM 头:UTF-16 文件开头有 0xFFFE 或 0xFEFF,如果直接跳过,解析会错位。我遇到过好几次,因为没注意 BOM,把整个字符串表读歪了。
  • 资源修改后要校验签名:如果你改了 PE 或 APK 的资源,数字签名会失效。有些程序会校验签名,改了资源直接闪退。这时候要么重签,要么 patch 掉校验逻辑。
我的习惯: 每次分析一个新样本,我都会先跑一遍 strings 并保存结果。然后对照 IDA 的字符串窗口,把不一致的地方标记出来。这样能快速发现那些“隐藏”的字符串——比如被 XOR 加密的,或者通过指针间接引用的。

字符串分析,说白了就是跟程序里的文本斗智斗勇。编码、资源、硬编码,这三块拿下了,大部分程序的“话”你都能听懂。嗯,今天就到这儿,你回去可以找个自己常用的软件练练手,看看能不能挖出点有意思的东西。

公众号:蓝海资料掘金营,微信deep3321