反调试—3

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值