第二关和第一关,大同小异。不过采取了两次验证的方式,第一次验证把字符串输入内存,第二次验证调用AfxMessageBox,
在查找关键代码的时候,使用内存访问断点比较方便,设断点的时候可以拖一块内存来设断点,有时程序会断在系统领空,这时使用Alt+F9返回,向上找应该会发现
关键代码,每次调试只能设一个内存断,重新运行后断点消失。
关键代码如下。
红色的地方,原本为test,test类似于and,吧每一位做与运算,但是结果不保存,只修改状态位,下面的JNZ根据状态位转跳。
一般情况,是把转跳语句改为nop,不过下面AfxMessageBox输入参数时,使用了eax,这里的messageBox是MFC封装的版本,
有三个参数,函数定义如下,第一个为显示内容,标题为应用名称,第二个为按钮风格,第三个貌似没啥用,省略也可。
汇编下,从第三个开始倒着push参数入栈,再call AfxMessageBox。
int AfxMessageBox( LPCTSTR lpszText, UINT nType = MB_OK, UINT nIDHelp = 0 );
所以,如果单纯的把转跳nop掉,MessageBox函数也会因为参数不正确而不能正确输出。
所以这里把所有的test比较语句改为xor,这样既可以把eax清零,又可以把状态位至零,使jnc的转跳不生效。
(上图红色行为修改行)
还有一种修改方法就是nop法,不过没有上文的方法简洁。
使用了AfxMessgeBox的另一种重载,不过不如上面方法美观。
最后破解后,效果如下