首页
社区
课程
招聘
未解决 [求助]硬件断点没有生效 10雪币
发表于: 2024-8-8 23:07 1437

未解决 [求助]硬件断点没有生效 10雪币

2024-8-8 23:07
1437

硬件断点没生效,帮我看看,谢谢。

#include <windows.h>
#include <stdio.h>

//系统断点
BOOL isSystemInt3 = TRUE;
//被调试进程
HANDLE debugProcess = NULL;
//被调试线程
HANDLE debugThread = NULL;
//被int3覆盖的原数据
CHAR oldData = 0;
//旧的页属性
DWORD oldProtect = 0;
DWORD Protect = 0;

BOOL WaitForUserCommand()
{
	BOOL ret = FALSE;
	CHAR cmd;
	printf("COMMAND>");
	cmd = getchar();
	switch (cmd)
	{
	case 't':
		ret = TRUE;
		break;
	case 'p':
		ret = TRUE;
		break;
	case 'g':
		ret = TRUE;
		break;
	default:
		break;
	}
	getchar();
	return ret;
}

VOID SetInt3BreakPoint(PUCHAR addr)
{
	CHAR data = 0xCC;

	ReadProcessMemory(debugProcess, addr, &oldData, 1, NULL);

	WriteProcessMemory(debugProcess, addr, &data, 1, NULL);
}

VOID SetMemBreakPoint(PUCHAR addr)
{
	//访问断点
	VirtualProtectEx(debugProcess, addr, 0x1000, PAGE_NOACCESS, &oldProtect);
	//写入断点
	//VirtualProtectEx(debugProcess, addr, 0x1000, PAGE_EXECUTE_READ, &oldProtect);
}

VOID SetHardBreakPoint(PUCHAR addr)
{
	CONTEXT threadContext = { 0 };

	SuspendThread(debugThread);
	threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
	BOOL ret = GetThreadContext(debugThread, &threadContext);

	printf("GetThreadContext = %d \r\n", ret);

	//设置断点位置
	threadContext.Dr0 = (DWORD64)addr;
	threadContext.Dr7 |= 0x1;  // 启用 Dr0

	ret = SetThreadContext(debugThread, &threadContext);
	ResumeThread(debugThread);

	printf("SetThreadContext = %d \r\n", ret);
}

BOOL Int3ExceptionHandler(EXCEPTION_DEBUG_INFO* info)
{
	CONTEXT threadContext = { 0 };
	BOOL ret = FALSE;

	//1、将INT3修复为原来的数据,如果是系统断点,不用修复
	if (isSystemInt3)
	{
		isSystemInt3 = FALSE;
		return TRUE;
	}
	else
	{
		WriteProcessMemory(debugProcess, info->ExceptionRecord.ExceptionAddress, &oldData, 1, NULL);
	}

	//2、显示断点位置
	printf("int3断点 => 0x%p \r\n", info->ExceptionRecord.ExceptionAddress);

	//3、获取线程上下文
	SuspendThread(debugThread);
	threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
	GetThreadContext(debugThread, &threadContext);

	//4、修正EIP
	threadContext.Rip--;
	SetThreadContext(debugThread, &threadContext);
	ResumeThread(debugThread);

	//设置硬件断点
	SetHardBreakPoint((PUCHAR)info->ExceptionRecord.ExceptionAddress + 1);

	//5、显示反汇编代码

	//6、等待用户命令
	while (ret == FALSE)
	{
		ret = WaitForUserCommand();
	}

	return ret;
}

BOOL AccessExceptionHandler(EXCEPTION_DEBUG_INFO* info)
{
	CONTEXT threadContext = { 0 };
	BOOL ret = FALSE;

	//1、获取异常信息,修改内存属性
	ULONG_PTR flag = info->ExceptionRecord.ExceptionInformation[0]; //访问类型 0读 1写
	ULONG_PTR addr = info->ExceptionRecord.ExceptionInformation[1]; //访问地址

	printf("内存断点 %llx %llx \r\n", flag, addr);

	VirtualProtectEx(debugProcess, (LPVOID)addr, 0x1000, oldProtect, &Protect);

	//2、获取线程上下文
	SuspendThread(debugThread);
	threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
	GetThreadContext(debugThread, &threadContext);

	printf("Rip => 0x%llx \r\n", threadContext.Rip);

	SetThreadContext(debugThread, &threadContext);
	ResumeThread(debugThread);

	while (ret == FALSE)
	{
		ret = WaitForUserCommand();
	}

	return ret;
}

BOOL SingleExceptionHandler(EXCEPTION_DEBUG_INFO* info)
{
	CONTEXT threadContext = { 0 };
	BOOL ret = FALSE;

	//获取线程上下文
	SuspendThread(debugThread);
	threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
	GetThreadContext(debugThread, &threadContext);

	//判断是否是硬件断点导致的异常
	if (threadContext.Dr6 & 0xF)
	{
		printf("硬件断点 %llx %llx \r\n", threadContext.Dr7 & 0x00030000, threadContext.Dr0);

		//将断点去除
		threadContext.Dr0 = 0;
		threadContext.Dr7 &= ~1;
	}
	else
	{

	}

	SetThreadContext(debugThread, &threadContext);
	ResumeThread(debugThread);

	while (ret == FALSE)
	{
		ret = WaitForUserCommand();
	}

	return ret;
}

BOOL exceptionHandler(DEBUG_EVENT* debugEvent)
{
	BOOL ret = TRUE;
	EXCEPTION_DEBUG_INFO* info = &debugEvent->u.Exception;

	//得到线程句柄,后面要用
	debugThread = OpenThread(THREAD_ALL_ACCESS, FALSE, debugEvent->dwThreadId);

	switch (info->ExceptionRecord.ExceptionCode)
	{
	//int3异常
	case EXCEPTION_BREAKPOINT:
	{
		ret = Int3ExceptionHandler(info);
	}
	break;
	//访问异常
	case EXCEPTION_ACCESS_VIOLATION:
	{
		ret = AccessExceptionHandler(info);
	}
	break;
	//单步处理
	case EXCEPTION_SINGLE_STEP:
	{
		ret = SingleExceptionHandler(info);
	}
	break;
	default:
		break;
	}

	return ret;
}

int main()
{
	BOOL isContinue = TRUE;
	DEBUG_EVENT debugEvent = { 0 };
	BOOL ret = TRUE;
	DWORD dwContinue = DBG_CONTINUE;

	STARTUPINFO si = { 0 };
	PROCESS_INFORMATION pi = { 0 };

	GetStartupInfo(&si);

	//1、创建调试进程
	ret = CreateProcess(TEXT("C:\\Windows\\notepad.exe"), NULL, NULL, NULL, TRUE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi);
	if (!ret)
	{
		printf("CreateProcess %d \r\n", GetLastError());
		return 0;
	}

	debugProcess = pi.hProcess;

	//2、调试循环
	while (isContinue)
	{
		ret = WaitForDebugEvent(&debugEvent, INFINITE);
		if (!ret)
		{
			printf("WaitForDebugEvent %d \r\n", GetLastError());
			return 0;
		}

		switch (debugEvent.dwDebugEventCode)
		{
		case EXCEPTION_DEBUG_EVENT:
		{
			ret = exceptionHandler(&debugEvent);
			if (!ret)
			{
				dwContinue = DBG_EXCEPTION_NOT_HANDLED;
			}
		}
		break;
		case CREATE_THREAD_DEBUG_EVENT:
		{
		}
		break;
		case CREATE_PROCESS_DEBUG_EVENT:
		{
			//进程创建的时候,在OEP处设置断点
			SetInt3BreakPoint((PUCHAR)debugEvent.u.CreateProcessInfo.lpStartAddress);

			//进程创建的时候,在OEP处设置内存访问断点
			//SetMemBreakPoint((PUCHAR)debugEvent.u.CreateProcessInfo.lpStartAddress);
		}
		break;
		case EXIT_THREAD_DEBUG_EVENT:
		{
		}
		break;
		case EXIT_PROCESS_DEBUG_EVENT:
		{
		}
		break;
		case LOAD_DLL_DEBUG_EVENT:
		{
		}
		break;
		case UNLOAD_DLL_DEBUG_EVENT:
		{
		}
		break;
		}

		//DBG_CONTINUE 表示调方式器已经处理了异常
		//DBG_EXCEPTION_NOT_HANDLED 表示调试器没有处理该异常,转回到用户态中执行,寻找可以处理该异常的异常处理器
		ret = ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, dwContinue);
	}

	return 0;
}



[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//