PDA

View Full Version : Multiple STEP_OVER in a row


psyCK0
January 6th, 2004, 05:04
Hey all,

Need some plugin help: I need my plugin to do a "step over" two times in a row.
I try:
<pre>Go(Getcputhreadid(), 0, STEP_OVER, 0, 1);
Go(Getcputhreadid(), 0, STEP_OVER, 0, 1);</pre>and<pre>Sendshortcut(PM_MAIN, 0, WM_KEYDOWN, 0, 0, VK_F8);
Sendshortcut(PM_MAIN, 0, WM_KEYDOWN, 0, 0, VK_F8);
</pre>

but only one step over is executed. I suppose thats because olly dosnt have the time to execute the second one... Is there any good way to get this to work?

focht
January 6th, 2004, 07:09
Greetings,

in short: you can't do it that way.
This is one shortcoming i noticed too when with such stuff some time ago.

The problem is as follows:

(i guess you are hooking into mainloop() callback listening to events)

ollydbg itself sits in an event loop, calling WaitForDebugEvent() / ContinueDebugEvent() to synchronize with the debuggee.
When the debugging event occurs, the system suspends all threads in the process being debugged and notifies the debugger of the event.
Ollydbg then propagates it to all connected plugins.

Pseudecode:

<pre>
while( debuggee_alive)
{
WaitForDebugEvent( &de,INFINITE)
if( de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
{
update_internal_stuff()

for_all_loaded_plugins
{
call_plugin_mainloop( &de)
}
}

if (de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
{
debuggee_alive = false;
}

ContinueDebugEvent( de.dwProcessId,de.dwThreadId, DBG_CONTINUE);
}

</pre>

Now as you see, the event propagation to plugins is synchronous.
Even if you call an asynchronous method (posting message whatever) which causes DEBUG_EVENTs, the debuggers main loop can't be entered twice that time (no reentrancy) because the debuggers loop thread waits for the call to the plugins mainloop() to return!

Currently i think there is only one way to get around that limitation:
You need to separate each call between debug events.

Make some kind of internal command queue, where you store command sequences.
When your plugin gets the debug event (after issueing command), dequeue the next command - only one command at a time!
This gives the ollydbg the chance to execute the debugger loop itself and to pump messages in other gui threads (if any).
Your go/singlestep command causes another DEBUG_EVENT to be issued which in turn lets the debugger call the plugins mainloop(). Voila. Synchonized.

Of course i might be wrong with my assumptions ... if so the author of ollydbg should clearify it

Regards,

A. Focht

psyCK0
January 6th, 2004, 14:12
Thanks for the info. =) It really doesn't make it any easier for me, but at least now I know....

psyCK0
January 7th, 2004, 08:34
Do you happen to know why olly wont take commands from another thread in the plugin? If I create a new thread and pass it the value of Getcputhreadid() and then run Go() using the passed value olly doesnt react?

focht
January 7th, 2004, 12:33
Greetings,

well maybe

As i explained above, ollydbg has a debugger loop (in fact, ollydbg itself is single threaded).
If you issue commands from the plugin's callback, they will be processed within the context of the thread that called the plugin callback (ollydbg's main thread).
This has the consequences as explained in my previous post (issueing commands in row)

You are spawning a separate (command) thread, unknown to ollydbg, to issue commands.
This imposes several penalties under windows operating systems due to its design.
As you might know, message queue (and all associated window objects) belong to thread that created them.
One cannot take out actions (like redrawing) by directly calling gui API functions on another thread context (it might work sometimes but often fails).
This is why one need to synchronize these actions to the right thread context (using SendMessage/PostMessage calls).

Imagine, what *might* happen if you call one of ollydbg's exported API functions.
Maybe the function is complex.
Imagine, the function does some stuff which invalidates internal data, structures ... and the gui stuff (forms/windows) itself.
Guess - the function calls gui/control functions implicit - uh oh wait ... Remember which thread context we are? Yike!
Not the one, that created the windows nor executes the main message loop.
Usually, applications become unstable at this point.

Maybe ollydbg maintains some state variable (which gets updated while/after processing main debugger loop) or checks the thread context before calling any gui stuff (which is tedious, because the plugin API isnt designed to be "multithread safe".

Only the author knows, how the stuff in ollydbg's exported API is exactly implemented.
Some functions may implicitly call gui APIs - some functions might not.

My advice: DONT call any ollydbg API functions from a thread context, unknown to ollybdg itself (that is any thread, not created by the main program itself)!
It will lead to side effects, things dont work as expected and finally ollydbg might become unstable.

Just issue the commands one-by-one each time the debug event callback gets called.
Maintain some internal state machine or command queue to implement this behavior.

Regards,

A. Focht.