BP函数断点检测:
bool CheckBp()
{
PDWORD funaddr = (PDWORD)MessageBoxA;
if (*(PBYTE)funaddr == 0xCC) //调试器下BP函数断点就是下INT 3(cc)断点
{
return true;
}
return false;
}
执行时间检测:
int main()
{
UINT64 timeA = GetTickCount64();//把需要检测的代码放在这两函数之间
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadCall, NULL, 0, NULL);
_asm {
push eax;
xor eax, eax;
and eax, 1;
add eax, 1;
pop eax;
}
UINT64 timeB = GetTickCount64();
if (timeB - timeA > 0x10)
{
printf("debug");
system("pause");
ExitProcess(0);
}
system("pause");
return 0;
}
即时调试器检测:
因为有的调试器再处理一些问题时,需把自己的调试器设置即时(当应用程序发生错误时,触发哪一个调试器)。
BOOL CheckRealTimeDebugger()
{
BOOL is_64;
IsWow64Process(GetCurrentProcess(), &is_64);//确定指定进程是否运行在64位操作系统的32环境(Wow64)下
HKEY hKey = NULL;
char key[] = "Debugger";
char reg_dir_32bit[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
char reg_dir_64bit[] = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug";
if (is_64)
{
RegCreateKeyA(HKEY_LOCAL_MACHINE, reg_dir_64bit, &hKey);//打开注册表项,hKey里面存放项的句柄
}
else
{
RegCreateKeyA(HKEY_LOCAL_MACHINE, reg_dir_32bit, &hKey);
}
char tmp[MAX_PATH];
DWORD len = 256;
DWORD type;
RegQueryValueExA(hKey, key, NULL, &type, (LPBYTE)tmp, &len);//获取注册表项的值,具体要获取哪个值放在key里面,获取的东西放在tmp里面
if (strstr(tmp, "X64dbg") != NULL|| strstr(tmp, "OllyDBG") != NULL|| strstr(tmp, "WinDbg") != NULL)
{
return TRUE;
}
else
{
return FALSE;
}
}
CRC32代码段检测:
第一次把代码段生成一个CRC32的校验值(保存起来),后面一直循环生成,如果改了代码段,两值一比较不对,就是调试了。
int crc32_table[256];
//生成具有256个元素的CRC32表
void Crc_Make_Table()
{
int crc = 0;
for (int i = 0; i < 256; i++)
{
crc = i;
for (int j = 0; j < 8; j++)
{
if (crc & 1)
crc = (crc >> 1) ^ 0XEDB88320; //CRC32多项式的值,也可以是04C11DB7
else
crc >>= 1;
}
crc32_table[i] = crc;
}
}
//根据CRC32数据表来计算字符串或者文件的CRC32值
int Calc_Crc32(char* data, int len)
{
int crc = 0XFFFFFFFF; //CRC初值是-1,即0XFFFFFFFF
for (int i = 0; i < len; i++)
{
crc = crc32_table[(crc ^ data[i]) & 0XFF] ^ (crc >> 8);
}
return !crc;
}
DWORD GetTextAddrAndSize(int* pTextSize)
{
HMODULE hModule = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS32 pNt = (PIMAGE_NT_HEADERS32)(pDos->e_lfanew + (DWORD)pDos);
int secNum = pNt->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER pSectionHeader = IMAGE_FIRST_SECTION(pNt);
for (size_t i = 0; i < secNum; i++)
{
if (strcmp((const char*)pSectionHeader->Name, ".text") == 0)
{
*pTextSize = pSectionHeader->Misc.VirtualSize;
return pSectionHeader->VirtualAddress + (DWORD)hModule;
}
pSectionHeader++;
}
}
BOOL bFrist = TRUE;
DWORD dwCrc32 = 0;
DWORD dwTextAddr = 0;
int dwTextSize = 0;
BOOL CheckCrc32()
{
if (bFrist)
{
dwTextAddr = GetTextAddrAndSize(&dwTextSize);
Crc_Make_Table();
dwCrc32 = Calc_Crc32((char*)dwTextAddr, dwTextSize);
bFrist = FALSE;
return FALSE;
}
else
{
int tmpdwCrc32 = Calc_Crc32((char*)dwTextAddr, dwTextSize);
if (tmpdwCrc32 != dwCrc32)
{
return TRUE;
}
else
{
return FALSE;
}
}
}
TLS检测:
#include <iostream>
#include <Windows.h>
#pragma comment(linker,"/INCLUDE:__tls_used")
//TLS 线程局部存储 Thread Local Save
//TLS执行时机是在main函数前面的
VOID
NTAPI TlsCallBack(
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
)
{
MessageBox(NULL, L"Tls", L"Success", MB_OK);
if (IsDebuggerPresent())
{
ExitProcess(0);
}
}
//注册TLS
//CRT 表示使用C Runtime 机制(运行时库)
//X表示名称随机
//L TLS CallBack
//X 随便 B-Y之间的任意字符
#pragma data_seg(".CRT$XLX")
PIMAGE_TLS_CALLBACK tlsCall = TlsCallBack;
#pragma data_seg();
int main()
{
std::cout << "Hello World!\n";
system("pause");
return 0;
}
自己调试自己检测:
#include <stdio.h>
#include <Windows.h>
int main()
{
HANDLE hMutext = OpenMutex(MUTEX_MODIFY_STATE, FALSE, L"Global\\MyMutex");
if (hMutext)
{
printf("run\r\n");
system("pause");
}
else
{
CreateMutex(NULL, FALSE, L"Global\\MyMutex");
TCHAR szPath[MAX_PATH] = {};
GetModuleFileName(NULL, szPath, MAX_PATH);
STARTUPINFO si = { sizeof(LPSTARTUPINFO) };
PROCESS_INFORMATION pi = { 0 };
//CreateProcess(szPath, NULL, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
CreateProcess(szPath, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
HWND hWnd = GetConsoleWindow();
ShowWindow(hWnd, SW_HIDE);
DebugActiveProcess(pi.dwProcessId);
DEBUG_EVENT DbgEvent = { 0 };
DWORD dwState = DBG_EXCEPTION_NOT_HANDLED;
BOOL bExit = FALSE;
while (!bExit)
{
WaitForDebugEvent(&DbgEvent, INFINITE);
if (DbgEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
{
bExit = TRUE;
}
ContinueDebugEvent(DbgEvent.dwProcessId, DbgEvent.dwThreadId, dwState);
}
exit(0);
}
system("pause");
return 0;
}