image-20231218165503263

鸽子我回来了!
本篇文章全部参考:https://ctf-wiki.org/reverse/platform/windows/anti-debug/example/

反调试

题目也是里面的bin.exe
三十二位反编译之后发现整整齐齐的一坨反调试代码:
image-20240121154416802

在ctfwiki的界面上介绍了每一个反调试的原理和应用,在这里就不多说,因为其实这些反调试技术说白了也只是一些代码,在汇编层面也只是一个call去调用,然后jz或者jmp去调整的判断,所以只需要在汇编方面使用keypatch去修改一些关键数据或者数值就可以达到目的了。

image-20240121154725162

函数的主体外层逻辑就是一个判断输入是不是 “I have a pen.”,如果是的话就会进行下面哪些的反调试函数
image-20240121154935947

简单的看一下第一个反调试代码为例:
image-20240121155033258

简单读一下IsDebuggerPresent部分:
首先就是调用IsDebuggerPresent函数去判断是不是调试模式,然后把返回的数值放到a8(不是精确位置,着指的是:[ebp+var_A8])位置(据猜测,肯定返回值是一个1)然后使用cmp的指令判断a8位置的数值是不是1,如果是的话,就不跳转,如果不是的话就跳过下面的代码。

当然下面的代码就是弹退出然后提示错误的代码。|
image-20240121155348999

_exit就跳出去了。
这里也是不难解决,把jnz的条件调整判断改成jmp强制跳转就行了,或者找到寄存器中a8位置的数值然后

改成0也是,都差不多.
随后就成功跳过去了:
image-20240121155805653

来到了第二段 NtGlobalFlag!这里了
这里逻辑差不多,都是可以直接改成jmp跳过的。
image-20240121185405125

都这样去修改就都可以跳过判断了,大概的调试都这样过就可以了,再或者去使用lazyida的插件去修改数值也行,都很简单。

我这里根据下面的汇编直接跳转到loc_4015B8
image-20240121192304897
这里是一个比较基本的seh

seh

看一下伪代码方面:
image-20240121192604409

之前直接nop掉的代码,在伪代码界面也会改变原来代码的逻辑。
再看这里代码就是一个很明显的除零异常。(关于异常的话,应该下一篇就会更新一篇简单理解seh的做题和出题思路)
虽然能猜到,这里的异常函数肯定是 跳出程序的,跟进一下异常处理函数:loc_40160A
image-20240121194513107

是进一步判断是否是调试状态。一样的,这里也可以直接nop掉。

一步跳转到flag

直接分析下面的汇编代码,可以看到过掉了这些反调试之后,会直接弹出flag的弹窗,找到位置
image-20240121195236288

这里注意把那个jnz给nop就行了

image-20240121195653836

然后一步步跟进,转到MessageBoxA,函数,随后就出弹窗得到了flag