许多软件为防止被破解,阻止调试器的分析,会使用反调试技术来检测自身是否正在被调试,或采取一系列手段让调试器失效,从而增加调试分析时间和复杂度。常见的反调试手段大致可以分为检测、干扰、权限清零三种。
下面主要介绍Windows操作系统中调用API的反调试技术。
Windows操作系统中提供了一些可用于检测自身是否正在被调试的API,最常用的有以下两种
调用 IsDebuggerPresent 来确定调用进程是否由用户模式调试器进行调试,如果当前进程运行在调试器环境中,返回值为非零值,如果没有运行在调试器环境中,则返回值是零。
BOOL CheckDebug()
{
return IsDebuggerPresent();
}
2.2、CheckRemoteDebuggerPresent
调用CheckRemoteDebuggerPresent 来检测一个进程是否正在被另一个独立进程调试,它不仅可以探测系统其他进程是否被调试,通过传递自身进程句柄还可以探测自身是否被调试。
BOOL CheckDebug()
{
BOOL ret;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &ret);
return ret;
}
拿大佬的一个MFC程序来反反调试
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
DIE查壳可知是由MFC编写的64位无壳程序,而由MFC编译的程序是默认开启ASLR的,ASLR即地址空间配置随机化,当我们利用调试器进行调试时会出现地址空间随机分配的情况,无法使用固定的地址进行定位,不利于调试。
这里我们用010editor将随机地址修改为固定地址,关闭ASLR。将程序拖入010中,执行EXE.bt模板
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
在右侧窗口中找到"WORDIMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE",并将其值"1"改为"0",或在左侧的十六进制窗口对应的hex值"6081"改为"2081"。
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
这时我们再将程序载入x64dbg,Alt+F9 运行至程序入口点,观察到此时 EntryPoint 地址为00000001400025A8(关闭ASLR之前载入x64dbg时,地址是00007FF639F825A8)。
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
结合前面DIE查壳得到的信息可以知道正确的入口点地址为 00000001400025A8,与上述地址一致,说明ASLR已被关闭。
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
当我们在x64dbg中F9想使程序跑起来时,发现程序直接退出了,于是推测程序调用了系统API反调试,检测到了当前正在被调试。
退出程序一般会调用 ExitProcess() 这个Windows API,所以我们可以以这个为突破口去进行定位。
接下来对 ExitProcess() 函数下断点,在x64dbg下面的命令行输入bp ExitProcess
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
设置完断点后,F9运行程序至断点处,观察堆栈区,选中下面这行,回车转到对应的反汇编区域。
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
可以很清楚地看到调用了 IsDebuggerPresent 这个API来探测调试器,记录下这个函数的地址
0000000140001734,方便后续使用IDA分析程序。
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
将程序载入IDA,按G跳转地址,地址就是上面 IsDebuggerPresent 函数的地址
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
选中函数头部,Ctrl+Alt+K 将其Patch
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
最后将结果导出到文件就OK了
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
我们来验证一下现在程序能否被调试,将其再次载入x64dbg,F9让程序跑起来
![xdbg + IDA过Windows API反调试 xdbg + IDA过Windows API反调试]()
显然此时程序正常运行,接下来就可以愉快地进行调试啦!
https://www.52pojie.cn/thread-1432590-1-1.html#38357779_x64dbg
原文始发于微信公众号(火炬木攻防实验室):xdbg + IDA过Windows API反调试
评论