IDA Pro 实战逆向破解入门到大师02:套娃函数追踪 + 双重密码

Pasted image 20260716203952

这是一个“进阶级”新手教学案例,如果说上一个代码是“新手村的小怪”,那么这个代码就是“带了迷宫机制的初级小怪”。

这个案例最大的教学价值在于:代码逻辑不再直白地写在主函数里,而是学会了“套娃”(函数封装),并且程序包含了“多重后门”逻辑。

我们可以按照以下四个阶段进行充分学习研究:

阶段一:温故知新(扫清外围障碍)

“拿到这段代码,我们先不要慌。先用上节课学到的‘猜词游戏’技巧,把主函数(main_0)里熟悉的面孔还原出来。”

我们快速过一遍 main_0 的上半部分:

  1. j__memset(String1, 0, sizeof(String1));:将 64 字节的输入缓冲区清零,防止内存中残留脏数据。
  2. sub_401C80sub_4011EF:根据里面的 %63s 和前面打印的提示语,闭着眼睛按 N 键,把它们分别重命名为 printfscanf。那个多余的 String1[0] 依然是 IDA 的反编译瑕疵,直接无视。

修复后,主函数的核心逻辑变得非常清爽:

  scanf("%63s", String1); // 获取用户输入的密码
  if ( sub_40478C(String1) )
  {
    printf("Success!\n");
    return 0;
  }
  else
  {
    if ( sub_4021B7(String1) )
      printf("Success!\n");
    else
      printf("Fail!\n");
    system("pause"); // sub_403CD3 重命名为 system
    return 0;
  }

阶段二:破解“套娃”函数(双击跟进技巧)

“现在我们遇到新问题了。上一个程序中,strcmp 明文比较直接写在 if 里面,我们一眼就能看到密码。但这次,条件变成了 if ( sub_40478C(String1) )。密码被藏起来了怎么办?很简单,在 IDA 中,双击这个函数名(或者光标选中按 Enter 键),我们要深入敌营!”

一起追踪第一条验证逻辑:

  1. 第一层套娃:进入 sub_40478C,发现里面只有一行代码:return sub_4088B0(lpString1);。程序把我们的输入又扔给了另一个函数。不要停,继续双击 sub_4088B0
  2. 第二层套娃:进入 sub_4088B0,终于看到了核心逻辑: return lstrcmpA(lpString1, "123456") == 0;

知识点科普 (lstrcmpA):

lstrcmpA 是 Windows API 提供的字符串比较函数(功能等同于 C 标准库的 strcmp)。如果两边的字符串相等,它会返回 0。所以 == 0 成立时,整个函数返回 1 (TRUE)。

结论得出:第一把钥匙(密码)是 "123456"

阶段三:分析逻辑分支(发现双重密码)

拿到第一把钥匙后,可以在 IDA 中按 Esc(后退),退回到主函数。

“通常情况下,输入正确的密码就通关了,输入错误就直接 Game Over。但大家仔细看这个程序的 else 分支,如果第一个密码验证失败,它并没有直接打印 Fail,而是又给了一次机会”

分析 else 里的逻辑:

    if ( sub_4021B7(String1) )
      printf("Success!\n");
    else
      printf("Fail!\n");

按照刚才的套路,追踪第二个验证函数:

  1. 双击 sub_4021B7,发现它调用了 sub_4088E0。(注意上面的注释 // attributes: thunk,这是编译器生成的跳板函数,不用深究,直接跟进)。
  2. 双击 sub_4088E0,发现最终比较逻辑: return lstrcmpA(lpString1, "xiaodiNB") == 0;

结论得出:程序有第二把钥匙(超级密码):"xiaodiNB"

阶段四:实战总结(给新手的通关秘籍)

最后,为大家的
IDA Pro逆向学习入门做一个方法论的拔高:

  1. 双密码/多重逻辑很常见:很多商业软件在验证注册码时,不仅会验证你购买的普通序列号,可能还藏着一个供开发者调试用的“万能密码”或“后门密码”。这个 CrackMe 完美模拟了这种架构。
  2. IDA 导航双键
    • Enter (回车) / 双击:步入函数,抽丝剥茧。
    • Esc (退出):返回上一层调用处,不迷路。
  1. 变量与函数重命名是核心战斗力:把 sub_40478CN 改名为 Check_Password_1,把 sub_4021B7 改名为 Check_Password_2。养成随手改名的好习惯,即便程序的逻辑套上十层,也能一眼看穿它的架构。
请登录后发表评论

    没有回复内容