第二课:先看它说什么——字符串的秘密
对应原书第 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 ./程序 # 看它干了哪些"坏事"
本课口诀
先听它说话,再看它表演。答案往往就写在脸上。
动手做
- 找一个带密码验证的小程序(不会写就让 AI 帮你写一个),用
strings找到它的密码。 - 用
ltrace跑它,看"旁白"有没有泄露答案。 - 想一想:如果程序把密码加密了,
strings还找得到吗?(下节课见)
想学更深的
见原书 第 4 章《静态分析》 和 第 5 章《动态分析》。