focht
February 1st, 2004, 11:50
Greetings,
ok i have your stuff now
I used both versions of ollydbg (1.09d and 1.10b), they show same behaviour.
The executable you supplied shows the "anomalies" thats for sure.
From what i've seen so far i can say the following:
The problem only appears if the application is multithreaded and at least one thread is suspended due to call to an OS synchronization API, like:
SleepEx
WaitForSingleObjectEx
WaitForMultipleObjectsEx
SignalObjectAndWait
MsgWaitForMultipleObjectsEx
It seems the thread where the injector code is run on differ from time to time.
Example: target has two application created threads
------------------
thread id: 2708 (this is the main gui thread of the application)
It just pumps messages.
Duck.exe+0x13d3
USER32.dll!InternalCallWinProc+0x1b
USER32.dll!UserCallDlgProcCheckWow+0x146
USER32.dll!DefDlgProcWorker+0xa6
USER32.dll!DefDlgProcA+0x21
USER32.dll!InternalCallWinProc+0x1b
USER32.dll!UserCallWinProcCheckWow+0x150
USER32.dll!SendMessageWorker+0x4a3
USER32.dll!SendMessageW+0x7d
USER32.dll!xxxButtonNotifyParent+0x3e
USER32.dll!xxxBNReleaseCapture+0xf5
USER32.dll!ButtonWndProcWorker+0x6ba
USER32.dll!ButtonWndProcA+0x4a
USER32.dll!InternalCallWinProc+0x1b
USER32.dll!UserCallWinProcCheckWow+0x150
USER32.dll!DispatchMessageWorker+0x306
USER32.dll!DispatchMessageW+0xb
USER32.dll!IsDialogMessageW+0x570
USER32.dll!DialogBox2+0x142
USER32.dll!InternalDialogBox+0xce
USER32.dll!DialogBoxIndirectParamAorW+0x35
USER32.dll!DialogBoxParamA+0x4a
Duck.exe+0x1315
------------------
thread id: 2792 (this is a worker thread, waiting for some event to be signaled)
ntdll.dll+0x8090304
ntdll.dll!NtWaitForSingleObject+0xc
kernel32.dll!WaitForSingleObjectEx+0xa8
kernel32.dll!WaitForSingleObject+0xf
Duck.exe+0x17ad
kernel32.dll!BaseThreadStart+0x37
One time, ollydbg did the following, trying to run the injector code:
...
RunSingleThread( 2708)
...
This worked, because the thread itself wasnt in any waitable/alertable state.
Some time later:
...
RunsingleThread( 2792)
...
This causes the infamous "Injection timeout" message.
The reason is clear (i told in my last message).
You can't wake up thread using ResumeThread() if it is in any Waitable/Alertable state. This behaviour is by OS design.
So the question remains ... why does ollydbg try to run the injector code on a thread which is in alertable state while another non-alertable thread is available?
I think that can only answer the author of ollydbg itself...
Of course there is an extremly clever way (first introduced by Jeffrey Richter) to circuumvent this and wake up even threads in alertable state.
The magic is called QueueUserAPC().
Regards,
A. Focht