 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Chris12 Expert Cheater
Reputation: 1
Joined: 27 Apr 2012 Posts: 103
|
Posted: Sun Apr 29, 2012 7:15 pm Post subject: Quick debugging question |
|
|
Hi,
I wrote my own debugger (WaitForDebugEvent and those functions).
It can set hardware breakpoints and everything works correctly when using "Execute" breakpoints.
Now there are ReadWrite and Write breakpoints too.
In the debug event that i receive, the ExceptionRecord Exceptionaddress is the address of the OpCode that caused this SingleStep.
Thats ok, but how do i get the address that this opcode accessed??
Example:
I have 4 hardwarebreakpoints, (readwrite)
Now I get a single step debug event because some opcode tries to read from the address of one of those breakpoints.
How would I know which breakpoint is hit ????
I hope you understand what I mean, if not, tell me
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25827 Location: The netherlands
|
Posted: Sun Apr 29, 2012 7:23 pm Post subject: |
|
|
if bit 0 in dr6 is set, bp 1 was hit
if bit 1 in dr6 is set, bp 2 was hit
...
Also, problem number two you will encounter:
The state of the registers and eip are that of AFTER the specific instruction has been accessed. Finding out the previous opcode can be tricky
_________________
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 |
|
 |
Chris12 Expert Cheater
Reputation: 1
Joined: 27 Apr 2012 Posts: 103
|
Posted: Sun Apr 29, 2012 7:40 pm Post subject: |
|
|
Ah i totally forgot about the 6th register
thank you so much!!
Why would I need the previous opcode?
Ah, and that raises the next question:
Say i have one opcode that is like this:
0x11 0x22 0x33 0x44 0x55 (not real opcodes of course)
If i set a breakpoint on the address of 0x11 it will get hit.
But what if i set my breakpoint on byte further (on 0x22)
what opcode will be hit ?
this one, or the next one ?
or hit at all because the breakpoint is not aligned with a opcode?
does that mean that the cpu only compares breakpoints to EIP ??
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25827 Location: The netherlands
|
Posted: Sun Apr 29, 2012 7:54 pm Post subject: |
|
|
When using a data breakpoint you will get a eip of 12345 while the instruction that caused the breakpoint is 12340. If you wanted to know the instruction that caused the breakpoint instead of just acting when it is accessed, you'll need to figure out the start address of the previous opcode. So not 12344, not 12343, 12342, 12341, but 12340
execute breakpoints only check the EIP being executed, the size is always 1
_________________
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 |
|
 |
Chris12 Expert Cheater
Reputation: 1
Joined: 27 Apr 2012 Posts: 103
|
Posted: Sun Apr 29, 2012 8:02 pm Post subject: |
|
|
Understood.
Luckily I don't need to know the accessing instruction
But if I'd need to get the address of the accessing instruction, I guess I need to disassemble the code? :/
Thank you for the information! You are awesome
edit1:
oh and by the way, is it possible for the application to use GetThreadContext on itself to check if it is being debugged (besides IsDebuggerPresent) ?
Is there any other way to see if the app checks itself for hardware breakpoints?
edit2:
The more I think about it, the scarier it gets...
A application could check dr0-dr3 for known offsets, and thereby detect the presence of a debugger.
Now the question is, is GetThreadContext the only way to retreive dr0-d4 ?? or can it somehow access those registers manually ??
edit3:
ewwwww, thats not nice, mov dr0,eax does actually work :/
any way to prevent that in a feasible way?
edit4:
ahh and another question:
i use one CE to set a readwrite breakpoint in a target app, and i also place a execute breakpoint
on readProcessMemory
and then i open a second ce, i can view the target apps memory without any breakpoint getting hit in the first ce...
why? any way to counter this?
isn't there some kind of "meta-debugger" ?
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25827 Location: The netherlands
|
Posted: Sun Apr 29, 2012 8:32 pm Post subject: |
|
|
mov dr0,eax does not work in usermode, you need to be in kernelmode to use it (it will raise an gpf(13) exception if you try to use it in usermode)
But to answer the question, yes, there is a way to hide the debug register state, but it's not easy
If the global debug flag in DR7 is set it will cause a single step interrupt each time the debug registers are read out or written to (you can't use setthreadcontext to set this, you need to set it manually in kernelmode)
In the interrupt handler emulate the read and write to return the values the system thinks it is, but leave the state to what you wish it to be.
An example of that can be found here: http://code.google.com/p/cheat-engine/source/browse/trunk/DBKKernel/debugger.c#778
Note that this involves 'tasksurfing' , each time windows does a taskswitch between one thread to another, the debug registers are accessed (if the target or origin process uses debug registers) so basically, you'll be going through a lot of different processes, just to be sure that the debugregisters are set properly
Also, you need to set dr7.gd on every processorthread
As for edit4:
That is because
1: the debug register is not set inside the thread that is accessing the memory
2: Windows tends to prevent breakpoints from reporting when they originate in kernelmode (if using the original readprocessmemory)
With a minor adjustment to ce's kernelmode debugger to not care about the processid, but only about the PEProcess, you CAN make it log external processes
as for a 'meta-debugger' , if you think ce's kernelmode debugger is good, you should see dbvm's internal debugger that goes even deeper (serial port required for now though)
_________________
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 |
|
 |
Chris12 Expert Cheater
Reputation: 1
Joined: 27 Apr 2012 Posts: 103
|
Posted: Sun Apr 29, 2012 8:57 pm Post subject: |
|
|
1.
Ok, my debugger always sets its breakpoints on CREATE_THREAD_DEBUG_EVENT,
in order to fake a "process global" behaviour of the breakpoints,
so the debug register not being set correctly can't be it...
So that means it must be windows...
2.
But that raises the question: In what context is ReadProcessMemory even executed???
When I use it on another app; I don't think that it spawns a thread in the targetprocess to read from, or does it?
And that, in turn, raises the question: How does ReadProcessMemory even counter possible synchronisation issues?
Can other threads modify the memory that ReadProcessMemory reads, while it is in the process of reading ????
3.
You said that "mov dr0,eax" doesn't work for normal processes, thats nice to hear.
But will the reverse work ? That is, reading the content of the debug register?
Btw: how the fuck do you know all this? You must be something like a hacker god :/
Thank you again for all the information, sensei =D
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25827 Location: The netherlands
|
Posted: Sun Apr 29, 2012 9:13 pm Post subject: |
|
|
1: Not really sure what the problem is, as you said, process global, so not system global
2: It runs in the context of the calling thread (So inside another process)
In windows memory is seperated in two basic parts. Usermode memory and Kernelmode memory
Every process has it's unique usermode memory and share the same kernelmode memory (mostly, paging tables excluded etc...)
Now, when a usermode thread calls readprocessmemory it goes into kernelmode, swaps the usermode memory with the target memory and does a copy/map into kernelmode memory, then switches the usermode memory back to the original and copies the memory from the kernelmode copy to usermode, all while inside the same thread context (so DR registers hold the same values all the while)
3: Same, usermode can not access the DR register, read nor write
| Quote: |
how the fuck do you know all this?
|
Experience.
And reading these:
http://download.intel.com/design/processor/manuals/253665.pdf
http://download.intel.com/design/processor/manuals/253666.pdf
http://download.intel.com/design/processor/manuals/253667.pdf
http://download.intel.com/design/processor/manuals/253668.pdf
http://download.intel.com/design/processor/manuals/253669.pdf
_________________
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 |
|
 |
|
|
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
|
|