第一次尝试做题,参考了众多大神的讲解,终于把这题解出来了。
我们先运行一下replace.exe,出现下面的框,什么都不输或输错点击check会异外终止。这题估计就是要让Wrong变成correct或right
我们先进行一下静态分析,通过ida打开,在String window中找目标字符串
可以看到是"Correct!"。然后单击这一行,会跳到下面这个界面
鼠标右键correct那行,点击list cross references to,会有一个弹窗xrefs to String,选定后点击ok,就会跳到下面这张图
我们可以看到流程图中没有一个流程是可以到我们要显示的字符串。
接下来我们进行动态分析,打开OllyDbg
我们先定位到correct字符串所在地址,在ida方框左下角可以看到是401073
我们可以看到在401073的指令前有两条jmp指令,说明肯定不会执行401073这条指令,和ida中流程图显示的一样。
在图上的地方按下F2设置断点(40104C是输入开始的地方)
现在开始运行程序,按F9,输入123(7bh),点check,然后F8单步执行
当执行完40105A的指令后,EAX=7B,说明输入的数据被放到了EAX中
单步执行到jmp replace.404609,程序会跳转到404609继续执行
这里还有一个改变,EAX的值变为了60160646
注意40469F这条指令,它将C39000C6这条机器码放入了40466F中
这是40466F中的指令,4046A9这条指令调用了存放在40466F中的子程序,这条语句是将90这个机器码放入DS:[EAX]中。(90是nop的机器码),也就是改变ds:[eax]中的指令,使之变为nop。
接着你会发现已经单步执行不了,程序出现异常停止。做到现在会发现仍然没有头绪。
我们换一个输入重新按照上面的步骤再做一遍,这次我们输入0
这次我们发现最后的EAX变为601605CB,改变是在mov eax,dword ptr ds:[4084d0]后,我们跳转到4084d0去看一下
我们看前面的十六进制数(注意一定要看的是前面的机器码,要不然会找不到flag),是将601605CB放入EAX。我们回头看一下输入123的情况
我们将两个数相减刚好可以得到7B,说明4084d0中的数是由601605CB+输入的数得到的。
这里就是需要我们思考的地方:要如何才能把jmp这条指令给跳过呢,结合上面运行(40466F处的子程序),我们其实可以很容易想到,我们将nop指令放到401071的位置就可以了,那EAX的值又是由我们输入的值加601605CB得到,所以我们输入的数是401071-601605CB=A02A 0AA6(将它转换成十进制数是2687109798)
输入正确答案后401071和401072都变成了nop(因为404609处的子程序调用了两次40466F处的字程序,中间还将EAX+1,所以401072也变成了nop)
运行成功截图