IDA 伪代码 = 天书?
CrackMe #1新手村入门
猜词游戏 + 破解 IDA 障眼法
N 键重命名 · strcmp 反直觉 · printf 可变参数 · IDA 伪代码瑕疵
CrackMe #1 · First Steps in Reverse Engineering

▲ CrackMe1 完整分析概览
这份代码是极其经典的新手村级别 CrackMe,用来给初学者建立信心。帮助新人消除对反编译代码的恐惧感。
IDA 反汇编逆向的核心策略是:猜词游戏与忽略障眼法。
01
PART
初窥门径——不要怕「无名函数」
GUESSING GAME · STRIPPED SYMBOLS
关键点:
很多同学刚拿到 IDA 伪代码,看到满屏幕的 sub_401C85、sub_4011EF 就会立刻头大,觉得这根本不是人能看懂的代码。其实,这只是因为程序在编译时被去除了符号表(Stripped),IDA 不知道这些函数原来的名字罢了。今天我们就来玩一个"猜词游戏",根据上下文把它们原本的名字还原出来!
一行行看
1. char Str1[64]; 这是一个长度为 64 字节的字符数组(缓冲区),顾名思义,这肯定是用来接收用户输入的。
2. SetConsoleTitleA(ConsoleTitle); 这是一个标准的 Windows API,看名字就知道是设置控制台黑框框的标题。不需要深究。
3. sub_401C85("CrackMe #1\n", Str1[0]); 和 sub_401C85("Enter password: ", Str1[0]);。引导思考:在黑框框程序里,打印字符串到屏幕上用的是什么函数?答案:printf。实操:直接在 IDA 中选中 sub_401C85,按 N 键重命名 为 printf。
4. sub_4011EF("%63s", Str1);。思考:有打印就有输入。它把用户的输入存到了我们刚才看到的 Str1 数组里,并且用 %63s 限制了最多只能输入 63 个字符(留 1 个字节给字符串结尾的 \0,防止缓冲区溢出)。这是什么函数?答案:scanf。实操:选中 sub_4011EF,按 N 重命名为 scanf。
5. sub_403CD3("pause");。看参数 pause,在 CMD 里敲 pause 是什么效果?"请按任意键继续"。所以这个就是执行系统命令的 system 函数。重命名为 system。
02
PART
直捣黄龙——破解核心逻辑
CORE LOGIC · STRCMP TRAP
经过第一步的重命名,代码已经变得非常阳间了。这时候我们看最核心的判断逻辑:
if ( !j__strcmp(Str1, "ixiaodi668") )
printf("Correct!\n", Str1[0]);
else
printf("Wrong!\n", Str1[0]);
要点:strcmp 的反直觉逻辑
初学者最容易死在这个 !(逻辑非) 上。
解释:strcmp 是 C 语言的字符串比较函数。如果两个字符串完全一样,它返回的是 0,而不是 1!
梳理:0 在 C 语言中代表 false。为了让 if 条件成立(变成 true),必须要在前面加一个 ! 把 0 变成 1。
结论:这段代码的意思是,如果你输入的 Str1 等于 ixiaodi668,就会打印 Correct!(正确)。这就是这个程序的明文密码!
03
PART
拔高(大师课)——破解 IDA 的障眼法
ADVANCED · PRINTF VARIADIC ARTIFACT
这时候肯定会有眼尖的同学提问:
老师,为什么 printf("CrackMe #1\n", Str1[0]); 后面会莫名其妙多出一个 Str1[0] 参数?正常的 printf("Hello") 明明只有一个参数啊!
原理解析
这是一个极其经典的 IDA 反编译瑕疵。大家回忆一下,printf 是一个可变参数函数(Variadic Function),意味着你可以给它传无限个参数,比如 printf("%d %s", a, b)。IDA 在分析可变参数函数时,有时候会"用力过猛"。在底层汇编中,调用 printf 之前可能恰好有一些残留的数据在栈顶(或者寄存器里),IDA 错误地认为这些残留数据也是传给 printf 的参数,于是强行把 Str1[0] 给塞了进去。逆向工程的第一法则:结合常识,忽略不合理的干扰项。既然前面的格式化字符串里没有 %d 或 %s,那后面的参数全是废话,直接无视即可!
∞
LAST
总结给新手的 Takeaway(课后复习点)
SUMMARY · TAKEAWAYS
识别特征 —— 遇到带 %d、%s 的无名函数,大胆猜测它是 scanf 或 sprintf;遇到直接跟字符串的,猜测是 printf 或 puts。
善用重命名 —— 边看边按 N 键改名,代码越改越清晰。
看破明文密码 —— 留意程序中的写死的字符串(硬编码),很多低级 CrackMe 的密码就大摇大摆地躺在 strcmp 旁边。
学会过滤 —— 伪代码不等于源码,遇到像 Str1[0] 这样多余的参数,要敢于用正向编程的经验去否定它。
逆向的第一步,不是看懂代码,而是消除恐惧
我是 {{小迪xiaodi老师}},一个热衷于分享逆向工程与安全技术的工程师。
既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。
THANKS FOR READING
夜雨聆风