lesson27的学以致用(花指令与SMC)
拉进IDA中看一眼,有SMC
首先先跑一下程序,根据input flag字符串找到主程序部分
这是程序主代码,可以看到在1094地址处有call调用,单步步入这个函数
进来看到比较像花指令的部分,第一条sub esp, 20 这条指令的作用是在栈上为局部变量开辟空间,程序后续用一系列 mov 指令写入的参考字符(如 'x', 'u', 'a' 等),就是存放在这块刚刚开辟出来的32字节内存空间里的。然后是比较像花指令的部分,利用互补条件跳转保证无论情况如何一定会跳转到900008处
去除花指令,在x32dbg中直接点这个01340008地址也能看到相当于去除花指令的部分,但是上下一滑动就会恢复原样:
后面到第一个cmp与je这两条指令组合在一起,构成了一个输入有效性检查,目的是判断用户输入的字符串是否为空。
选区部分的功能是计算用户输入字符串的长度,然后检查这个长度是否正好等于16个字符。
这里开始是校验部分,首先是花指令部分,这里只是为了保存 eax 的值,然后跳转到程序的下一部分,其余全是垃圾指令。
进入到9000CB后进行初始化和地址计算,为循环的指针操作做好准备。
完整的校验逻辑:
1.取输入字符A (存入ebp)。
2.取参考字符B ('x') (存入ebx)。
3.计算:计算结果 = 你的输入字符A - 参考字符B (结果存入ebp)。
4.取参考字符C (1),并用它覆盖掉ebx。
5.最终校验:if (计算结果 == 参考字符C)
参考字符B和C都可以在内存中找到,选中在转储中跟随该地址:
就能看到参考字符实际上是xuanyuan-zhifeng
参考字符C是01 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01
逆向获得flag的公式则是flag[n-1] = 参考字符C_n + 参考字符B_n
另外失败处理代码部分则是