Killboy Posted January 7, 2009 Posted January 7, 2009 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
Hikaru Posted January 8, 2009 Posted January 8, 2009 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!
Killboy Posted January 8, 2009 Author Posted January 8, 2009 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 :/
Hikaru Posted January 9, 2009 Posted January 9, 2009 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.
Killboy Posted January 9, 2009 Author Posted January 9, 2009 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 falseInjectDll(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 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:
Hikaru Posted January 12, 2009 Posted January 12, 2009 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" Seriously, it seems a nice solution to me. Good work!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now