逆向工程实战手册 第 2 课

第二课:先看它说什么——字符串的秘密

对应原书第 4 章《静态分析》的"快速捡漏"部分


第二天清早,小林到铺子的时候,陈师傅正对着一台旧电脑发愁。屏幕上是一个黑色的窗口,光标一闪一闪。

"师傅,这又是什么?"

"一件委托。"陈师傅推了推眼镜,"有人送来一个程序,说里面藏着一句话——'找到它,给你五十块'。这程序你跑一下试试。"

小林在键盘上敲了一下回车,屏幕上弹出一行字:

请输入钥匙:

小林随便打了几个字,回车。屏幕又弹出一行:

不对!再想想。

"就这么简单?"小林问,"程序就问你一句,然后说不对?"

"对。现在,你觉得'钥匙'藏在哪里?"

小林歪头想了想:"……藏在程序里?"

"聪明。那怎么找?难道把它大卸八块?"

"对啊!"小林撸起袖子。

"等等——"陈师傅笑了,"记住我的话:先听它说话,再拆它骨头。 程序已经说了两句'人话'了,我们得先听听,它还有没有别的'心里话'。"

陈师傅在键盘上敲了一个命令:

strings 程序 | more

屏幕上哗啦啦滚出一大片字。小林看得眼花缭乱,但里面有几行特别扎眼:

请输入钥匙:
不对!再想想。
正确!你找到我了。
s3cr3t_k3y_2024

小林愣住了:"……钥匙就写在里面?"

"就写在里面。"陈师傅慢悠悠地说,"写程序的人以为把答案藏在一个'看不见的地方',其实它只是把话藏进了自己的肚子里。而我们,是给机器'听诊'的人。"


课程正文

字符串(string):程序里所有"给人类看的话",比如提示语、错误消息、网址、路径、甚至密码和密钥。

strings 命令:把程序里像"人话"的片段统统抓出来给你看。它不运行程序,只"读"文件——这就是静态分析里最快的一招。

strings 程序                    # 全部字符串
strings 程序 | grep -i key      # 只找 key 相关的
strings 程序 | grep -iE "http|/api"   # 找网址

为什么字符串是金矿

写程序的人要跟用户说话,就得把话写进程序里。这些"话"包括:

□ 提示语:"请输入密码" → 附近就有密码校验
□ 错误消息:"验证失败" → 顺着它就能找到判断逻辑
□ 网址 / IP:程序的"家"在哪
□ 密钥 / 口令:有时直接明文躺在里面
□ 报错信息:泄露内部结构

口诀:字符串是程序的"嘴"。嘴不会撒谎——至少先听听它怎么说。

第二个工具:让程序"表演"给你看

除了听它说话,还可以让它当场表演。在命令行里直接运行:

ltrace ./程序          # 跟踪它调用了哪些库函数
strace ./程序          # 跟踪它调用了哪些系统函数

这两个命令会像"旁白"一样,把程序背地里干的事念出来。有时候,密码就藏在旁白里。

$ ltrace ./程序
printf("请输入钥匙:") = 7
scanf("%s", buf) = 1
strcmp("123", "s3cr3t_k3y_2024") = -1    ← 旁白泄露了答案!
puts("不对!再想想。")

小林盯着屏幕:"它……它把比较的对象都说出来了?"

"说了。这就是'让程序表演'的好处——有些程序很会藏,但你一让它'跑起来',它就忍不住把真话带出来。"

本课的工具箱(就三样)

strings 程序                # 听它说话
ltrace ./程序               # 看它请了哪些"外援"
strace ./程序               # 看它干了哪些"坏事"

本课口诀

先听它说话,再看它表演。答案往往就写在脸上。

动手做

  1. 找一个带密码验证的小程序(不会写就让 AI 帮你写一个),用 strings 找到它的密码。
  2. ltrace 跑它,看"旁白"有没有泄露答案。
  3. 想一想:如果程序把密码加密了,strings 还找得到吗?(下节课见)

想学更深的

见原书 第 4 章《静态分析》第 5 章《动态分析》