Jump to content
Tuts 4 You

Dll injection + message loop


Killboy

Recommended Posts

Hi :)

I'm injecting a Dll into a process, the Dll then creates an empty window (creating a new class + Createwindow).

In my main process, I find the window with FindWindow(ClassName, NULL) and send WM_COPYDATA to it with the stuff it needs to handle.

The problem is that I need a message loop for my window to receive messages sent to it.

If I create the window and start the loop in DllMain (on DLL_PROCESS_ATTACH), I never return, thus I can't check if the Dll injection worked. (I could check if the window existed, but I dont really like that)

So I created a thread from DllMain, in which I create the window and loop the messages.

This works, but it feels weird. I wanted to create the window before returning from DllMain so I can check for the window right away instead of inserting another Sleep(2000) which can fail in like 1 of 10 cases.

However, if I create the window in DllMain but do the loop in a different thread, I don't get any messages for it, because it wasn't created in this thread.

So, is there a way to handle message loops for all threads ? Could I use CreateDialog ? Or does it need a message loop as well ?

I only used it in modal DialogBoxes which usually do all the looping and dispatching of messages, so they probably do the ones for nonmodal dialogs as well :wacko:

Link to comment

You can create the thread from DllMain and do some thread syncronization (events, semaphores... whatever you like). Then you can return from DllMain knowing if CreateWindow() worked or not without having a hardcoded waiting time, but having the possibility to use timeouts.

Good luck!

Link to comment

Thanks for the reply :)

I tried implementing events but it seemed like it didn't even execute the thread. I looked up CreateThread on MSDN again and I found this:

During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process.

Looks like I'll have to resort to interprocess synchronization then :/

Link to comment

Uh, nevermind. I've been taking a look and it seems that the reason is that if you try to create a thread, then the OS will try to notify all DLL's calling DllMain(DLL_THREAD_ATTACH). But as the DllMain() that called CreateThread() is still executing the DLL_PROCESS_ATTACH (and is a serialized function) there's a little deadlock.... so that's why you need to return from DllMain() to get the thread executed.

Also, taking a look at MS DLL Best Practices:

Creating a thread can work if you do not synchronize with other threads, but it is risky.

And, in general, use nothing that requires a minimum syncronization from DllMain. So it seems a bit risky without using additional DLL-exported functions.

Link to comment

Hm I got it working like this:

DLL:

DllMain (DLL_PROCESS_ATTACH):
CreateThread(somefunc)Somefunc:
if(!CreateEmptyWindow) return false;
OpenEvent("someevent")
SetEvent

Debugger:

if(!CreateEvent("someevent")) return false
InjectDll(CreateRemoteThread)
WaitForSingleObject(Event, 5000)
FindWindow
...

In the doc (nice find btw, thanks) it says you shouldnt call user32 functions in dll main, but since the thread is created after I return from DllMain (as it says in the quote above from CreateThread), this oughta work.

I don't really see any possible deadlocks, then again the doc somehow scared me :D

Should I rather export SomeFunc and call CreateRemoteThread on it after injecting the dll ?

The only problem is getting the dlls image base on an x64 system, the thread exit code is just a dword. Might just enumerate the modules but that sounds like work D:

Link to comment

Yeah, that doc is a bit scary but that's its work. Taken it's focused on writing dll from scratch and not thinking about code injection, I won't take it as an strict guide. As the saying goes: "If it works, don't touch it" :D Seriously, it seems a nice solution to me. Good work!

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...