// // Hardware breakpoint support // // www.catch22.net // #include inline void SETBITS(unsigned long& dw, int lowBit, int bits, int newValue) { int mask = (1 << bits) - 1; dw = (dw & ~(mask << lowBit)) | (newValue << lowBit); } #define DBG_COND_EXECUTE 0 #define DBG_COND_WRITE 1 #define DBG_COND_READWRITE 3 // // Address - address to break on. // Length - must be 0, 1, 2 or 4 // Condition - must be 0, 1 or 3 // BOOL SetHardwareBP(PROCESS_INFORMATION *ppi, DWORD Address, DWORD Length, int Condition) { CONTEXT context = { CONTEXT_DEBUG_REGISTERS }; int i; // get contents of every debug register if(!GetThreadContext(ppi->hThread, &context)) return -1; // find available hardware register for(i = 0; i < 4; i++) { if((context.Dr7 & (1 << (i * 2))) == 0) { *(&context.Dr0 + i) = Address; SETBITS(context.Dr7, 16 + i*4, 2, Condition); SETBITS(context.Dr7, 18 + i*4, 2, Length); SETBITS(context.Dr7, i * 2, 1, 1); if(!SetThreadContext(ppi->hThread, &context)) return -1; return i; } } return -1; } BOOL ClearHardwareBP(PROCESS_INFORMATION *ppi, int DbgRegister) { CONTEXT context = { CONTEXT_DEBUG_REGISTERS }; // get contents of every debug register if(!GetThreadContext(ppi->hThread, &context)) return FALSE; SETBITS(context.Dr7, DbgRegister*2, 1, 0); if(!SetThreadContext(ppi->hThread, &context)) return FALSE; return TRUE; } BOOL SingleStep(PROCESS_INFORMATION *ppi) { CONTEXT context = { CONTEXT_CONTROL }; if(!GetThreadContext(ppi->hThread, &context)) return FALSE; context.EFlags |= 0x100; // set the "trap" flag for single step if(!SetThreadContext(ppi->hThread, &context)) return FALSE; return TRUE; }