Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Toggle hardware data/read/execute breakpoints programmatically

, 23 Jul 2008 CPOL
Simple code to introduce a hardware breakpoint mechanism.
// Hardware Breakpoint Functions

#define _WIN32_WINNT _WIN32_WINNT_WINXP
#include <windows.h>
#include "hwbrk.h"

class HWBRK
	{
	public:
		void* a;
		HANDLE hT;
		HWBRK_TYPE Type;
		HWBRK_SIZE Size;
		HANDLE hEv;
		int iReg;
		int Opr;
		bool SUCC;

		HWBRK()
			{
			Opr = 0;
			a = 0;
			hT = 0;
			hEv = 0;
			iReg = 0;
			SUCC = false;
			}
	};


void SetBits(DWORD_PTR& dw, int lowBit, int bits, int newValue)
	{
	DWORD_PTR mask = (1 << bits) - 1; 
	dw = (dw & ~(mask << lowBit)) | (newValue << lowBit);
	}

static DWORD WINAPI th(LPVOID lpParameter)
	{
	HWBRK* h = (HWBRK*)lpParameter;
	int j = 0;
	int y = 0;

	j = SuspendThread(h->hT);
    y = GetLastError();

	CONTEXT ct = {0};
	ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
	j = GetThreadContext(h->hT,&ct);
    y = GetLastError();

	int FlagBit = 0;

	bool Dr0Busy = false;
	bool Dr1Busy = false;
	bool Dr2Busy = false;
	bool Dr3Busy = false;
	if (ct.Dr7 & 1)
		Dr0Busy = true;
	if (ct.Dr7 & 4)
		Dr1Busy = true;
	if (ct.Dr7 & 16)
		Dr2Busy = true;
	if (ct.Dr7 & 64)
		Dr3Busy = true;

	if (h->Opr == 1)
		{
		// Remove
		if (h->iReg == 0)
			{
			FlagBit = 0;
			ct.Dr0 = 0;
			Dr0Busy = false;
			}
		if (h->iReg == 1)
			{
			FlagBit = 2;
			ct.Dr1 = 0;
			Dr1Busy = false;
			}
		if (h->iReg == 2)
			{
			FlagBit = 4;
			ct.Dr2 = 0;
			Dr2Busy = false;
			}
		if (h->iReg == 3)
			{
			FlagBit = 6;
			ct.Dr3 = 0;
			Dr3Busy = false;
			}

		ct.Dr7 &= ~(1 << FlagBit);
		}
	else
		{
		if (!Dr0Busy)
			{
			h->iReg = 0;
			ct.Dr0 = (DWORD_PTR)h->a;
			Dr0Busy = true;
			}
		else
		if (!Dr1Busy)
			{
			h->iReg = 1;
			ct.Dr1 = (DWORD_PTR)h->a;
			Dr1Busy = true;
			}
		else
		if (!Dr2Busy)
			{
			h->iReg = 2;
			ct.Dr2 = (DWORD_PTR)h->a;
			Dr2Busy = true;
			}
		else
		if (!Dr3Busy)
			{
			h->iReg = 3;
			ct.Dr3 = (DWORD_PTR)h->a;
			Dr3Busy = true;
			}
		else
			{
			h->SUCC = false;
			j = ResumeThread(h->hT);
			y = GetLastError();
			SetEvent(h->hEv);
			return 0;
			}
		ct.Dr6 = 0;
		int st = 0;
		if (h->Type == HWBRK_TYPE_CODE)
			st = 0;
		if (h->Type == HWBRK_TYPE_READWRITE)
			st = 3;
		if (h->Type == HWBRK_TYPE_WRITE)
			st = 1;
		int le = 0;
		if (h->Size == HWBRK_SIZE_1)
			le = 0;
		if (h->Size == HWBRK_SIZE_2)
			le = 1;
		if (h->Size == HWBRK_SIZE_4)
			le = 3;
		if (h->Size == HWBRK_SIZE_8)
			le = 2;

		SetBits(ct.Dr7, 16 + h->iReg*4, 2, st);
		SetBits(ct.Dr7, 18 + h->iReg*4, 2, le);
		SetBits(ct.Dr7, h->iReg*2,1,1);
		}



	ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
	j = SetThreadContext(h->hT,&ct);
    y = GetLastError();

	ct.ContextFlags = CONTEXT_DEBUG_REGISTERS;
	j = GetThreadContext(h->hT,&ct);
    y = GetLastError();

	j = ResumeThread(h->hT);
    y = GetLastError();

	h->SUCC = true;

	SetEvent(h->hEv);
	return 0;
	}

HANDLE SetHardwareBreakpoint(HANDLE hThread,HWBRK_TYPE Type,HWBRK_SIZE Size,void* s)
	{
	HWBRK* h = new HWBRK;
	h->a = s;
	h->Size = Size;
	h->Type = Type;
	h->hT = hThread;


	if (hThread == GetCurrentThread())
		{
		DWORD pid = GetCurrentThreadId();
		h->hT = OpenThread(THREAD_ALL_ACCESS,0,pid);
		}

	h->hEv = CreateEvent(0,0,0,0);
	h->Opr = 0; // Set Break
	HANDLE hY = CreateThread(0,0,th,(LPVOID)h,0,0);
	WaitForSingleObject(h->hEv,INFINITE);
	CloseHandle(h->hEv);
	h->hEv = 0;

	if (hThread == GetCurrentThread())
		{
		CloseHandle(h->hT);
		}
	h->hT = hThread;

	if (!h->SUCC)
		{
		delete h;
		return 0;
		}


	return (HANDLE)h;
	}






bool RemoveHardwareBreakpoint(HANDLE hBrk)
	{
	HWBRK* h = (HWBRK*)hBrk;
	if (!h)
		return false;

	bool C = false;
	if (h->hT == GetCurrentThread())
		{
		DWORD pid = GetCurrentThreadId();
		h->hT = OpenThread(THREAD_ALL_ACCESS,0,pid);
		C = true;
		}

	h->hEv = CreateEvent(0,0,0,0);
	h->Opr = 1; // Remove Break
	HANDLE hY = CreateThread(0,0,th,(LPVOID)h,0,0);
	WaitForSingleObject(h->hEv,INFINITE);
	CloseHandle(h->hEv);
	h->hEv = 0;

	if (C)
		{
		CloseHandle(h->hT);
		}

	delete h;
	return true;
	}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Michael Chourdakis
Engineer
Greece Greece
I'm working in C++, PHP , Flash and DSP Programming, currently experimenting with Windows 7 technologies and professional audio applications.
 
I 've a PhD in Digital Signal Processing.
 
My home page: http://www.michaelchourdakis.com

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 24 Jul 2008
Article Copyright 2008 by Michael Chourdakis
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid