Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Help removing hardware breakpoint

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
igoticecream
Grandmaster Cheater Supreme
Reputation: 0

Joined: 23 Apr 2006
Posts: 1807
Location: 0x00400000

PostPosted: Tue Nov 02, 2010 2:19 pm    Post subject: Help removing hardware breakpoint Reply with quote

Hi everyone. Here's my problem:

I have been working in a function for setting hardware breakpoints and a VEH for handling them. Now, when the exception EXCEPTION_SINGLE_STEP occurs (I'm setting a breakpoint on execute) I know it must disable the breakpoint to avoid getting into an infinite loop when I try to continue execution. I do call my function of remove breakpoint, inside this function, both Get/SetThreadContext do their work alright, but for some mystical reason, i do enter into this infinite loop.

I have printed Dr0 and Dr7 at the beginning and end on my remove breakpoint function and seems to do it work good, but when i print Dr0 and Dr7 before and after (at VEH) the remove breakpoint function, i get the same results (meaning my remove breakpoint fail).

I will leave my code, and i hope you can help me fix this

Code:

#include "stdafx.h"

#pragma auto_inline(off)

PVOID pExceptionHandler;
HANDLE hThread;

void function()
{
   printf_s("function executes\n");
   _getch();
}

BOOL SetBreakpoint(HANDLE hThread, PVOID lpAddr, DWORD dwDRX, DWORD dwLevel, DWORD dwCondition, DWORD dwLength)
{
   CONTEXT lpContext;
   
   if (GetThreadContext(hThread, &lpContext))
    {
      lpContext.ContextFlags = CONTEXT_DEBUG_REGISTERS;
      switch (dwDRX)
      {
      case DEBUG_REGISTER_0:
         lpContext.Dr0 = (DWORD)lpAddr;
         lpContext.Dr7 |= BREAKPOINT_LOCAL_EXACT | dwLevel | dwCondition | dwLength;
         break;
      case DEBUG_REGISTER_1:
         lpContext.Dr1 = (DWORD)lpAddr;
         lpContext.Dr7 |= BREAKPOINT_LOCAL_EXACT | dwLevel | dwCondition | dwLength;
         break;
      case DEBUG_REGISTER_2:
         lpContext.Dr2 = (DWORD)lpAddr;
         lpContext.Dr7 |= BREAKPOINT_LOCAL_EXACT | dwLevel | dwCondition | dwLength;
         break;
      case DEBUG_REGISTER_3:
         lpContext.Dr3 = (DWORD)lpAddr;
         lpContext.Dr7 |= BREAKPOINT_LOCAL_EXACT | dwLevel | dwCondition | dwLength;
         break;
      }
      return SetThreadContext(hThread, &lpContext);
   }
   return 0;
}

BOOL RemoveBreakpoint(HANDLE hThread, PVOID lpAddr, DWORD dwDRX, DWORD dwLevel, DWORD dwCondition, DWORD dwLength)
{
   CONTEXT lpContext;
   
   if (GetThreadContext(hThread, &lpContext))
    {
      lpContext.ContextFlags = CONTEXT_DEBUG_REGISTERS;
      switch (dwDRX)
      {
      case DEBUG_REGISTER_0:
         lpContext.Dr0 = (DWORD)0;
         lpContext.Dr7 ^= dwLevel | dwCondition | dwLength;
         break;
      case DEBUG_REGISTER_1:
         lpContext.Dr1 = (DWORD)0;
         lpContext.Dr7 ^= dwLevel | dwCondition | dwLength;
         break;
      case DEBUG_REGISTER_2:
         lpContext.Dr2 = (DWORD)0;
         lpContext.Dr7 ^= dwLevel | dwCondition | dwLength;
         break;
      case DEBUG_REGISTER_3:
         lpContext.Dr3 = (DWORD)0;
         lpContext.Dr7 ^= dwLevel | dwCondition | dwLength;
         break;
      }
      return SetThreadContext(hThread, &lpContext);
   }
   return 0;
}

DWORD WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
   if (pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
   {
      printf_s("[VEH] Breakpoint hit\n");
      RemoveBreakpoint(hThread, (PVOID)function, DEBUG_REGISTER_0, DR0_BREAKPOINT_LOCAL, DR0_EXECUTE, DR0_ONE_BYTE);
      return EXCEPTION_CONTINUE_EXECUTION;
   }
   return EXCEPTION_CONTINUE_SEARCH;
}

int main(int argc, char* argv[])
{
   UNREFERENCED_PARAMETER(argc);
   UNREFERENCED_PARAMETER(argv);

   hThread = GetCurrentThread();
   pExceptionHandler = AddVectoredExceptionHandler(1,(PVECTORED_EXCEPTION_HANDLER)VectoredExceptionHandler);

   SetBreakpoint(hThread, (PVOID)function, DEBUG_REGISTER_0, DR0_BREAKPOINT_LOCAL, DR0_EXECUTE, DR0_ONE_BYTE);
   
   function();

   RemoveVectoredExceptionHandler(pExceptionHandler);
   return EXIT_SUCCESS;
}


Code:

#pragma once

#include "targetver.h"

#include <Windows.h>
#include <stdio.h>
#include <conio.h>

// TODO: reference additional headers your program requires here
// Macros
#define DEBUG_REGISTER_0         0x00000001
#define DEBUG_REGISTER_1         0x00000002
#define DEBUG_REGISTER_2         0x00000004
#define DEBUG_REGISTER_3         0x00000008

// Macros for DR0
#define DR0_BREAKPOINT_LOCAL      0x00000001
#define DR0_BREAKPOINT_GLOBAL      0x00000002

#define DR0_WRITE               0x00010000
#define DR0_ACCESS               0x00030000
#define DR0_EXECUTE               0x00000000

#define DR0_ONE_BYTE            0x00000000
#define DR0_TWO_BYTE            0x00040000
#define DR0_FOUR_BYTE            0x000C0000

//Macros for DR1
#define DR1_BREAKPOINT_LOCAL      0x00000004
#define DR1_BREAKPOINT_GLOBAL      0x00000008

#define DR1_WRITE               0x00100000
#define DR1_ACCESS               0x00300000
#define DR1_EXECUTE               0x00000000

#define DR1_ONE_BYTE            0x00000000
#define DR1_TWO_BYTE            0x00400000
#define DR1_FOUR_BYTE            0x00C00000

// Macros for DR2
#define DR2_BREAKPOINT_LOCAL      0x00000010
#define DR2_BREAKPOINT_GLOBAL      0x00000020

#define DR2_WRITE               0x01000000
#define DR2_ACCESS               0x03000000
#define DR2_EXECUTE               0x00000000

#define DR2_ONE_BYTE            0x00000000
#define DR2_TWO_BYTE            0x04000000
#define DR2_FOUR_BYTE            0x0C000000

// Macros for DR3
#define DR3_BREAKPOINT_LOCAL      0x00000040
#define DR3_BREAKPOINT_GLOBAL      0x00000080

#define DR3_WRITE               0x10000000
#define DR3_ACCESS               0x30000000
#define DR3_EXECUTE               0x00000000

#define DR3_ONE_BYTE            0x00000000
#define DR3_TWO_BYTE            0x40000000
#define DR3_FOUR_BYTE            0xC0000000

//Macros for general DR
#define BREAKPOINT_LOCAL_EXACT      0x00000100
#define BREAKPOINT_GLOBAL_EXACT      0x00000200
#define RESERVED_BIT_10            0x00000400
#define GENERAL_DETECT            0x00002000


Thanks for you time. Very Happy

_________________
+~


Last edited by igoticecream on Tue Jul 21, 2015 12:51 pm; edited 1 time in total
Back to top
View user's profile Send private message
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Tue Nov 02, 2010 2:35 pm    Post subject: Reply with quote

Code:
lpContext.Dr7 ^= dwLevel | dwCondition | dwLength;

You xor the Dr7 with those values, that means that you FLIP the flags Level, Condition and Length. You might wanna try '&=' to turn them off instead of flipping them. So:
Code:
lpContext.Dr7 &= dwLevel | dwCondition | dwLength;
Back to top
View user's profile Send private message
igoticecream
Grandmaster Cheater Supreme
Reputation: 0

Joined: 23 Apr 2006
Posts: 1807
Location: 0x00400000

PostPosted: Tue Nov 02, 2010 5:09 pm    Post subject: Reply with quote

even if i set the 32bits of Dr7 to 0, i cannot leave the infinite loop Crying or Very sad

EDIT: problem solve, but know it looks "hackish"

Code:

#define DISABLE_BREAKPOINT(Dr7,Dr)   Dr7 &= ~Dr
#define ENABLE_BREAKPOINT(Dr7,Dr)   Dr7 |= Dr;
#define TRACEFLAG_ON(EFlag)         EFlag |= 0x00000100;
#define TRACEFLAG_OFF(EFlag)      EFlag &= ~0x00000100;

...

DWORD WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
   if ((pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) && (pExceptionInfo->ContextRecord->Dr6 & DEBUG_REGISTER_0))
   {
      DISABLE_BREAKPOINT(pExceptionInfo->ContextRecord->Dr7,DR0_BREAKPOINT_LOCAL);
      TRACEFLAG_ON(pExceptionInfo->ContextRecord->EFlags);
      return EXCEPTION_CONTINUE_EXECUTION;
   }
   else if (pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
   {
      ENABLE_BREAKPOINT(pExceptionInfo->ContextRecord->Dr7,DR0_BREAKPOINT_LOCAL);
      TRACEFLAG_OFF(pExceptionInfo->ContextRecord->EFlags);
      return EXCEPTION_CONTINUE_EXECUTION;
   }
   return EXCEPTION_CONTINUE_SEARCH;
}

_________________
+~
Back to top
View user's profile Send private message
tombana
Master Cheater
Reputation: 2

Joined: 14 Jun 2007
Posts: 456
Location: The Netherlands

PostPosted: Tue Nov 02, 2010 5:33 pm    Post subject: Reply with quote

I don't know if its the solution to your problem, but you have an error with GetThreadContext: MSDN
MSDN wrote:
The value of the ContextFlags member of this structure specifies which portions of a thread's context are retrieved.

The following line should also be placed BEFORE GetThreadContext. It will tell GetThreadContext what info it should retrieve.
Code:
lpContext.ContextFlags = CONTEXT_DEBUG_REGISTERS;


EDIT: Oh you solved it.
Back to top
View user's profile Send private message
igoticecream
Grandmaster Cheater Supreme
Reputation: 0

Joined: 23 Apr 2006
Posts: 1807
Location: 0x00400000

PostPosted: Fri Nov 05, 2010 2:01 pm    Post subject: Reply with quote

Lol i was reading about RF (Resume flag) at intel's manual vol 3... and is what i need to solve the problem

Quote:

Resume flag for breakpoint fault suppression: When the RF bit (resume flag) in the processor's EFLAGS register is set, then hardware breakpoint faults are suppressed for the next instruction. This enables the debug exception handler to resume program execution from the breakpointed instruction without having it generate a breakpoint fault again on the same instruction.


now it looks like:

Code:

DWORD WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
   if (pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
   {
      pExceptionInfo->ContextRecord->Eip = (DWORD)hackish; //<- detour to my function
      pExceptionInfo->ContextRecord->EFlags |= 0x10000;

      return EXCEPTION_CONTINUE_EXECUTION;
   }
   return EXCEPTION_CONTINUE_SEARCH;
}


doing this i do not need anymore to removebreakpoint->single step->setbreakpoint again Razz

_________________
+~
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 471

Joined: 09 May 2003
Posts: 25848
Location: The netherlands

PostPosted: Fri Nov 05, 2010 4:46 pm    Post subject: Reply with quote

RF flag will only work in windows vista and windows 7
the RF flag is 'sanitized' by XP before returning

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites