views:

688

answers:

3

Is it possible to write a program under windows that will cause a remote process thread to break (stop execution in that thread) upon reaching a predefined address?

I have been experimenting with the Windows Debug API, but it seems very limited when it comes to setting breakpoints. The DebugBreakProcess function seemed promising, but I can't find any examples on how to use this API call.

+6  A: 

You need to use WriteProcessMemory to write a breakpoint (on x86, an opcode of 0xCC) to the address. On x86, when the debuggee hits that point in the code the 0xCC will generate an int 3 exception. This is picked up by your debugger's WaitForDebugEvent will return a DEBUG_EVENT with EXCEPTION_DEBUG_EVENT set.

You then need to patch the that address back to its original code before continuing. If you want to break again, you need to single step and then repatch the breakpoint opcode. To single step, you need to set the single step flag in EFlag in the thread context.

DebugBreakProcess is used to generate a remote break of a process you are debugging - it can't be used to break at an arbitrary point in the code.

Michael
So I could do something like:1. Read the current op at the predefined address (PA) and store it2. Replace the op with 0xCC and NOPS to generate a int 3 exception (Will the int 3 exception automatically stop execution?)3. Catch the EXCEPTION_DEBUG_EVENT4. I've stopped execution of the thread correctly but I've replaced part of the code and will have unexpected results. I could tried rewriting the stored OP at the PA but won't it already be too late? Can I instead force the remote thread to exectue the OP manually somehow?
ldog
It won't be too late to patch - the target IP hasn't changed and continuing will cause the debugee to reissue the exception if you haven't changed the code.
Michael
I'm having problems patching. I can set the break point and I can catch the breakpoint exception but when I try to WriteProcessMemory to write back the original opcode I get Access Voilation Exceptions which means that the program does not exectue the code properly. I do a FlushInstructionCache after the WriteProcessMemory but it doesn't seem to help.
ldog
*SOLVED* You need to access the thread that broke on the breakpoint, and set its EIP register back one instruction. I don't know why but this is required.In reply to your comment: "the target IP hasn't changed and continuing will cause the debugee to reissue the exception " this is false at least under my system (Vista x64)
ldog
@gmatt - You are correct. I was bitten by this exact same problem several years ago.
Michael
+1  A: 

Michael is right - also, if you want to break into an arbitrary process in the debugger once you've attached (i.e. if the user hits "Break into process" all of a sudden), the standard way is to create a remote thread whose routine issues an int3.

Paul Betts
DebugBreakProcess appears to create the remote thread that breaks.
Michael
Oh yes, then use that - using CreateRemoteThread correctly is quite tricky.
Paul Betts
A: 

If you are looking for a debug program, and not looking to write it, winDbg allows you to set a breakpoint when a memory adress is changed. Just open the .exe you want to debug with it.

here's a link to the download: http://www.microsoft.com/whdc/devtools/debugging/default.mspx

David Menard