原理就是调用 CloseHandle 释放一个无效句柄,如果没有被调试,那么函数返回FALSE,GetLastError = ERROR_INVALID_HANDLE;但如果被调试,那么系统将抛出异常 C0000008H。
代码:
// Test_Console_1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <Windows.h>
using namespace std;
typedef NTSTATUS(WINAPI* pNtClose)(HANDLE);
int main()
{
// CloseHandle
__try {
CloseHandle(reinterpret_cast<HANDLE>(0x99999999));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
cout << "CloseHandle 发现调试器" << endl;
}
// NtClose
HMODULE h_ntdll = LoadLibrary(L"ntdll.dll");
if (h_ntdll == NULL) {
cout << "ntdll.dll LoadLibrary failed." << endl;
goto main_end;
}
pNtClose NtClose = (pNtClose)GetProcAddress(h_ntdll, "NtClose");
if (NtClose == NULL) {
cout << "NtClose GetProcAddress failed." << endl;
goto main_end;
}
__try {
NtClose(reinterpret_cast<HANDLE>(0x99999999));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
cout << "NtClose 发现调试器" << endl;
}
main_end:
getchar();
return 0;
}
效果图:
(1)正常情况
(2) 使用 VS 调试
方法二
HANDLE hMutex;
hMutex = CreateMutex(NULL, FALSE, _T("Random name"));
if (hMutex) {
// CloseHandle 后不关闭对象句柄
SetHandleInformation(hMutex, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE);
__try {
// 在调试模式中关闭这个句柄会引发异常,非调试模式不会
CloseHandle(hMutex);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
cout << "发现调试器!" << endl;;
}
}