攻防世界之梅津美治郎
考察知识点
逆向、__debugbreak()断点
题目链接https://adworld.xctf.org.cn/task/answer?type=reverse&number=4&grade=1&id=5478&page=3
解题步骤
首先在IDAPRO32位中查看伪代码,有main函数
主体部分为上面的字段,可以发现存在scanf,接下来是比较输入和v8的大小,可以判断v8对应的r0b0RUlez!即是第一个密码
在通过第一部分后,有 sub_4015EA(0)函数,进入查看
该函数内部为一个递归,之后遇到了debugbreak函数
debugbreak函数相当于一个int 3指令,引发一个中断,把执行权移交给调试器,如果没有调试器,那就移交给其他异常处理回调函数,如果都没有,那么程序就自己断下来,这里就是为了触发回调函数,如果没有调试器附加,那么debugbreak产生的异常会被AddVectoredExceptionHandler添加的回调函数捕获来处理
AddVectoredExceptionHandler
两个系统函数GetModuleHandleA和GetProcAddress作用分别是获取模块名和获取模块名内函数。v5((HMODULE)1, (LPCSTR)sub_40157F);捕抓异常然后给第一个处理函数sub_40157F处理。
进入sub_40157F查看,发现有通过sub_401547的比较函数
进入sub_401547查看有
a1 是用户输入, a2 是一段数据,应该是要求输入的数据与 a2 的数据 ^ 2相等,接下来获取 dword_40AD98 的数据
注意到调用dword_40AD98的地址为00401AC7
使用ollydbg打开,在00401AC7处下断点,运行到该位置
在跟随此时EAX的0060FDAC的数据,继续运行
输入第一段密码后寄存器出现的前8个字符为dword_40AD98 的数据,且后面出现please enter the second password!
编写脚本解析密码得到答案w3lld0ne
key1="u1nnf2lg"
flag2=""
for i in key1:
flag2+=chr(ord(i)^2)
print(flag2)
两段密码用_
连接因此最后的flag为flag{r0b0RUlez!_w3lld0ne}。