Click here to Skip to main content
13,404,806 members (37,124 online)
Click here to Skip to main content

Stats

108.6K views
3.5K downloads
81 bookmarked
Posted 23 Jul 2008

Toggle hardware data/read/execute breakpoints programmatically

, 23 Jul 2008
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 , Java, Windows, iOS and Android.

I 've a PhD in Digital Signal Processing and I specialize in Pro Audio applications.

My home page: http://www.michaelchourdakis.com

You may also be interested in...

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