When I attach OllyDbg or ImmunityDebugger to a process, it automatically breaks execution. I'm attaching to a user-mode service running as SYSTEM and only need to catch exceptions, so this is not ideal. Is there a way to disable the break-on-attach behaviour?
-
You would like to attach the debugger to the program and immediately perform a 'continue', is it correct ?– perrorApr 12, 2013 at 10:20
-
Pretty much. I'd prefer to avoid the breakpoint entirely. I just want the debugger to break if an exception occurs.– PolynomialApr 12, 2013 at 10:42
-
@Polynomial will anti-debugging techniques be an option as well?– Denis LaskovApr 12, 2013 at 11:11
-
@DenisLaskov An option? I'm not sure I follow.– PolynomialApr 12, 2013 at 12:40
-
1@Polynomial: uhm, why is it harsh? a.) I could just have downvoted and not told you why, so you would have never known b.) downvotes on questions affect your rep (true) but not mine (so even if you checked everyones rep all the time you couldn't tell who downvoted) c.) you can simply edit your question to be less ambiguous and I'll gladly retract my downvote - it may even end up as an upvote. Last but not least, I stand by the downvote and the reason for it. Downvotes on answers affect both (-1 for voter, -2 for person answering), btw. But check out my profile I downvote also answers ;)– 0xC0000022L ♦Apr 12, 2013 at 14:54
3 Answers
Explanation
The break on attach is due to the ntdll
DbgUiRemoteBreakin
and DbgBreakPoint
functions being called. If you check the kernel32
DebugActiveProcess
function called by the debugger, OllyDbg or ImmunityDebugger, you will see a call to the CreateRemoteThread
, CreateRemoteThreadEx
, or ZwCreateThreadEx
function depending on your OS.
So, i guess one way to bypass breaking is:
- debug the debugger itself
- go to the
DbgUiIssueRemoteBreakin
function and spot the call to the function creating the remote thread. - change the
lpStartAddress
parameter in case ofCreateRemoteThread
/CreateRemoteThreadEx
toDbgBreakPoint
+1RETN 0xC3
Plugin
I created an OllyDbg v1.10 plugin which NOP
s the INT3
in DbgBreakPoint
in the process with the PID you choose. It has only been tested on Windows 7.
Usage
Place SilentAttach.dll in OllyDbg directory, fire OllyDbg, Press Alt+F12, and then enter process Id of the process you want to silently attach to.
N.B. Since no break occurs, OllyDbg does not extract many piece of info. e.g. list of loaded module. So, you have to activate the context by something like Alt+E then Alt+C
-
2This is probably the best solution as it doesn't mess with DbgBreakPoint. Just NOP the call to DbgBreakPoint in DbgUiRemoteBreakin in the process you want to attach to. Apr 12, 2013 at 18:20
-
1
One way to do this is to have an OllyDbg plug-in that performs a
WriteProcessMemory(hDebuggee, GetProcAddress(GetModuleHandle("ntdll"), "DbgBreakPoint"), &mynop, 1, NULL)
where hDebuggee is the handle for the process being debugged (I believe that OllyDbg has an API for retrieving this value), and mynop is a variable that holds a 0x90 byte (nop instruction).
That will clear the int3 instruction that is causing the break, allowing the execution to continue immediately. It's a common anti-debugging trick.
-
I take that back. It was the usual OllyDbg attach freeze bug. This works as intended. Probably the easiest one to implement! Apr 12, 2013 at 18:23
I don't think this is possible without doing something extremely invasive. Either patching OllyDbg to use an alternative ZwXX/NtXX function which accepts some flags or patching the kernel. The initial break is done by the operating system so that the debugger can gather information about the process it is being attached to.
I haven't verified but my guess is that OllyDbg is calling DebugActiveProcess in order to attach to it. The documentation for it states:
After the system checks the process identifier and determines that a valid debugging attachment is being made, the function returns TRUE. Then the debugger is expected to wait for debugging events by using the WaitForDebugEvent function. The system suspends all threads in the process, and sends the debugger events that represents the current state of the process.
And later on
After all of this is done, the system resumes all threads in the process. When the first thread in the process resumes, it executes a breakpoint instruction that causes an EXCEPTION_DEBUG_EVENT debugging event to be sent to the debugger. All future debugging events are sent to the debugger by using the normal mechanism and rules.
-
Bugger. I assume that local kernel debugging on Windows doesn't work the same way? Apr 12, 2013 at 14:32