Windows中一些常用的反调试记录
这里笔记会记录一些关于Windows中的反调试技术的汇编代码,方便后续分析程序时回来查看。反调试技术包括
- Windows APIs 调用
- 其他手段检测调试器
Windows APIs
IsDebuggerPresent
这个函数主要检测的是PEB
的IsDebugged
标志,如果返回非零值则表示被调试
CheckRemoteDebuggerPresent
这个函数和IsDebuggerPresent
函数一样也是检测PEB->IsDebugged
状态值, 不过还可以检测其他进程是否被调试,此时需要传入的是目标进程的句柄。
对抗方法:
1、找一些辅助插件过掉
2、动态调试阶段修改指令
**3、动态调试阶段改变状态寄存器 **
4、修改二进制的指令
NtQueryInformationProcess
这个ntdll.dll
内的一个原生API,目的是用来提取指定进程的信息
函数原型
__kernel_entry NTSTATUS NtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength
);
这里的ProcessInformatinoClass
是一个枚举量,当ProcessInformationClass=ProcessDebugport
,例如ProcessDebugport=0x70或者别的调试器端口号
就能判断指定的进程是否被调试,如果是则返回调试端口,否则返回0.
对抗方法:
1、找一些辅助插件过掉
2、动态调试阶段修改指令
**3、动态调试阶段改变状态寄存器 **
4、修改二进制的指令
OutputDebugString
函数的目的是在调试器中显示一个字符串以检测调试器是否存在。
使用方法:
- 调用SetLastError函数设置一个任意值,例如0x111
- 调用OutputDebugString 函数,如果这个函数调用失败,SetLastError函数就会被系统分配一个新的值
- 调用GetLastError来判断是否是设定的值,例如0x111
代码片段如下
DWORD errorValue=0x111;
SetLastError(errorValue);
OutputDebugString("Test for Debugger!");
if(GetLastError() == errorValue)
{
printf("Debugger was attached !\n");
ExistProcess();
}
printf("Normal procedure!!\n");
如下使用OD调试时的截图,检测出调试器附加
注:直接使用VisualStudio2015编译执行也是会提示debugger存在,估计是环境不对?
不过需要记住这个检测手段即可,再之后分析中遇到多注意。
对抗方法:
1、找一些辅助插件过掉
2、动态调试阶段修改指令
**3、动态调试阶段改变状态寄存器 **
4、修改二进制的指令
检测数据结构PEB
检测BeingDebugged
这个反调试检测或多或少都遇到了,例如
mov eax,dword ptr fs:[30];
mov ebx,byte ptr [eax+0x2];
test ebx,ebx;检测这个是否为零
jz NoDebuggerDetected
或者
push dword ptr fs:[30];
pop ebx;
cmp