View previous topic :: View next topic |
Author |
Message |
toffler Cheater Reputation: 0
Joined: 27 Sep 2012 Posts: 38
|
Posted: Fri Jan 19, 2018 5:23 am Post subject: [Win32 C++] How to set a hardware breakpoint? |
|
|
I wrote a small debugger that attaches to a process and receives debugger events, the code in general goes like this:
Code: | DebugActiveProcess(pidDbg);
...
while(1)
{
WaitForDebugEvent(&dbgEv, INFINITE);
switch(dbgEv.dwDebugEventCode)
{
case EXCEPTION_DEBUG_EVENT:
...
switch(dbgEv.u.Exception.ExceptionRecord.ExceptionCode)
{
case STATUS_ACCESS_VIOLATION:
...
break;
case STATUS_SINGLE_STEP:
case STATUS_BREAKPOINT:
if(dbgEv.u.Exception.dwFirstChance == 1) {
exAddr = dbgEv.u.Exception.ExceptionRecord.ExceptionAddress;
if(exAddr == ...) {
setBP(...);
}
else if(exAddr == ...) {
clearBP(...);
}
...
}
break;
...
ContinueDebugEvent(dbgEv.dwProcessId, dbgEv.dwThreadId, dwContinueStatus);
} |
I was able to set/clear software breakpoints inside setBP() and clearBP() functions and they work perfectly.
Now I want to add hardware breakpoints. The code I added to setBP() for a test goes like this:
Code: | HANDLE hThread;
WOW64_CONTEXT lcContext;
...
hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT, false, thID);
lcContext.ContextFlags = CONTEXT_ALL;
Wow64GetThreadContext(hThread, &lcContext);
lcContext.Dr0 = adr;
lcContext.Dr7 |= 1; // enable DR0 locally
lcContext.Dr7 &= 0xFFF0FFFF; // set bits 16-17 to execution & bits 18-19 to zero.
lcContext.Dr6 = 0; // clear DR6 before returning from the handler
Wow64SetThreadContext(hThread, &lcContext);
CloseHandle(hThread); |
The value of adr here is the same I use to set the CC byte for a software breakpoint.
As far as I can see - nothing happens, the debugger loop doesn't receive any single step exceptions (or events) and the process keeps running.
What am I doing wrong here ?
Thank you!
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Fri Jan 19, 2018 11:02 am Post subject: |
|
|
try Get/SetThreadContext instead of wow64
and a normal Context
_________________
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 |
|
|
toffler Cheater Reputation: 0
Joined: 27 Sep 2012 Posts: 38
|
Posted: Fri Jan 19, 2018 9:22 pm Post subject: |
|
|
I forgot to mention, the debugger is a x64 program, the debugee is x32, hence Wow64.
I use the same functions to clear software breakpoints (for lcContext.Eip--;) and they work, so I don't think the problem is there.
Can it be so that I have enough rights/permissions to set software breakpoints in a program but not hardware breakpoints?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sat Jan 20, 2018 5:10 am Post subject: |
|
|
even in a 32-bit process it's easier to use get/setthreadcontext (not wow64)
wow64 is just the secondary layer it jump switches to after exiting from kernelmode or system dll's which are in 64 bit and is the usual context(when a theead gets paused it'll wait in 64 bit mode)
anyhow, you are right, you need to obtain seDebugPrivilege
also, i noticed you're not suspending the tread. that may be needed
_________________
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 |
|
|
toffler Cheater Reputation: 0
Joined: 27 Sep 2012 Posts: 38
|
Posted: Mon Jan 22, 2018 11:02 am Post subject: |
|
|
Ok, I replaced wow64 calls with a get/setthreadcontext, added SuspendThread, successfully obtained seDebugPriviledge for the debugger thread before opening the process using this example https://support.microsoft.com/en-au/help/131065/how-to-obtain-a-handle-to-any-process-with-sedebugprivilege and checked if setthreadcontext returns any errors (it doesn't).
Didn't change a thing. My debugger loop doesn't receive any exceptions from the debugee thread after I set debug registers.
What else I could possibly miss here?
What about the address I put in DR0, is it the same I use for replacing CC byte in SWBP? Is any paging involved here?
Also, I enable HWBR locally and it's said that the CPU will clear debug registers when switching between tasks. How do I make sure it doesn't clean registers before the BP is hit?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Mon Jan 22, 2018 1:14 pm Post subject: |
|
|
is your debugger process running as admin?
and just call getthreadcontext to verify your breakpoont is still set
oh yes, the context field must be on a 128 byte boundary.
_________________
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 |
|
|
toffler Cheater Reputation: 0
Joined: 27 Sep 2012 Posts: 38
|
Posted: Wed Jan 24, 2018 8:53 am Post subject: |
|
|
I think I found what the problem is: I set a HWBP while suspending a thread_A but the HWBP will be hit by another thread_B that is created later somewhere down the line.
The value of registers DR0-DR3 is preserved across all threads, so if I set it for A it will be there for B.
But the value of DR7 is reset to zero, when I check values at CREATE_THREAD_DEBUG_EVENT my DR0 is fine but DR7 is 0.
How do I preserve DR7 across threads or how do I set HWBP in one thread for another to hit it?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Wed Jan 24, 2018 9:20 am Post subject: |
|
|
in windows every thread has their own debug registers (on context switch the dr* registers get loaded from the saved threadstate)
you just need to set the breakpoint in every single thread (so watch thread creation)
_________________
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 |
|
|
toffler Cheater Reputation: 0
Joined: 27 Sep 2012 Posts: 38
|
Posted: Wed Jan 24, 2018 11:24 am Post subject: |
|
|
What about an old thread that was created before I need (and know where) to set the HWBP?
If that one happens to be the one to hit the BP how do I set DR7 to it?
|
|
Back to top |
|
|
OldCheatEngineUser Whateven rank Reputation: 20
Joined: 01 Feb 2016 Posts: 1587
|
Posted: Wed Jan 24, 2018 11:40 am Post subject: |
|
|
just a question off topic, since you are talking about DR:
whats the relation between dr7 and dr0, dr1, dr2, and dr3?
i know a lil bit about them, but i dont understand the relation.
_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote: | i am a sweetheart. |
|
|
Back to top |
|
|
atom0s Moderator Reputation: 199
Joined: 25 Jan 2006 Posts: 8518 Location: 127.0.0.1
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Wed Jan 24, 2018 5:13 pm Post subject: |
|
|
toffler:
when you first attach the windows debugger api you will get flooded with create thread notification events, those are the old threads
alternatively, just get a threadlist and open every one of them and apply the debugregs
OldCheatEngineUser: dr7 controls what dr0,1,2 and 3 represent, and contains some extra features like breaking when a debug register is accessed
_________________
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 |
|
|
OldCheatEngineUser Whateven rank Reputation: 20
Joined: 01 Feb 2016 Posts: 1587
|
Posted: Wed Jan 24, 2018 5:20 pm Post subject: |
|
|
thanks db, i understood now.
_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote: | i am a sweetheart. |
|
|
Back to top |
|
|
toffler Cheater Reputation: 0
Joined: 27 Sep 2012 Posts: 38
|
Posted: Thu Jan 25, 2018 1:08 am Post subject: |
|
|
Dark Byte wrote: | toffler:
when you first attach the windows debugger api you will get flooded with create thread notification events, those are the old threads
alternatively, just get a threadlist and open every one of them and apply the debugregs |
Thanks, I'll try that
OldCheatEngineUser wrote: | just a question off topic, since you are talking about DR:
whats the relation between dr7 and dr0, dr1, dr2, and dr3?
i know a lil bit about them, but i dont understand the relation. |
dr0-dr3 hold up to 4 breakpoint addresses, dr7 enables/disables each of these and specifies if an address is a program command being executed or a data in memory that is being accessed.
|
|
Back to top |
|
|
OldCheatEngineUser Whateven rank Reputation: 20
Joined: 01 Feb 2016 Posts: 1587
|
Posted: Thu Jan 25, 2018 9:10 am Post subject: |
|
|
so i can say:
dr0 = eax
dr1 = ebx
dr2 = ecx
dr3 = edx
hardware breakpoints
while dr7 control them for whatever uses, looks simple but i know there a lot under the hood.
thanks.
_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote: | i am a sweetheart. |
|
|
Back to top |
|
|
|