   DLL Injection to monitor window messages
  I am writing an application similar to Winspector Spy or Spy++ and i am looking at how to monitor messages from other windows. There is a wealth of information on sites like CodeProject and i have been reading some of the articles there, but i would like to get some help and advice from you guys just to make sure i am on the right track.To clarify exactly what it is that i want to do - i want to be able to monitor messages that are sent to a window (or, to be more correct, messages that a window processes) and have the data on those messages passed to my program so that it can log and display it. Additionally, i want to be able to monitor when windows are created/destroyed and also when processes are created/destroyed, but that can wait until i get message monitoring working.So, firstly, how to actually inject the code into another process. I will put the code in a DLL then load it in a remote process. This article lists 2 ways to do this (and a third way not requiring a DLL). But i am not sure which way is best for me. Could someone please explain the difference between these 2 methods?The first methods mentions windows hooks. I will be using message hooks to monitor window messages, but is this a different scenario to what's mentioned here? I would assume that i would need to inject the DLL which would then set a hook to monitor messages, but the article seems to be saying that i can use hooks as a way to actually inject the DLL. I'm confused.Secondly, i will probably want to also have the ability to call API functons on the window in the remote process, i.e. things like DestroyWindow which can only be called from the thread that created the window. I'm not yet sure how i will go about this but i'm just saying that installing a hook is not the only thing that my DLL will be doing.I will probably have a bunch more questions as i continue to read articles on the topic. [grin]   
Quote:Original post by XTAL256But i am not sure which way is best for me. Could someone please explain the difference between these 2 methods?The article you linked talks about that, see the "When to use CreateRemoteThread & WriteProcessMemory technique" section.Quote:... but the article seems to be saying that i can use hooks as a way to actually inject the DLL. I'm confused.About what?   It says:Quote:originally by OP articleAfter a successful call to SetWindowsHookEx, the system maps the DLL into the address space of the hooked thread automatically, but not necessary immediatelySo, you get a target thread, you supply a hook function that you presumably have in a DLL, and at some point in the future SetWindowsHookEx will inject your DLL into that process for you.  That's pretty straightforwardQuote:Secondly, i will probably want to also have the ability to call API functons on the window in the remote process, i.e. things like DestroyWindow which can only be called from the thread that created the window. I'm not yet sure how i will go about this but i'm just saying that installing a hook is not the only thing that my DLL will be doing.Once you get your DLL into the target's process space, that DLL IS part of the process.  Assuming you can get a hold of whatever you need, you can call the API to your heart's content.;Quote:Original post by AmrazekQuote:Original post by XTAL256But i am not sure which way is best for me. Could someone please explain the difference between these 2 methods?The article you linked talks about that, see the "When to use CreateRemoteThread & WriteProcessMemory technique" section.No that's the 3rd option, the one not requiring a DLL. I am asking about the "CreateRemoteThread & LoadLibrary" technique.Quote:Original post by AmrazekQuote:... but the article seems to be saying that i can use hooks as a way to actually inject the DLL. I'm confused.About what?   It says:Quote:originally by OP articleAfter a successful call to SetWindowsHookEx, the system maps the DLL into the address space of the hooked thread automatically, but not necessary immediatelySo, you get a target thread, you supply a hook function that you presumably have in a DLL, and at some point in the future SetWindowsHookEx will inject your DLL into that process for you.  That's pretty straightforwardAfter i posted this, i re-read that article (which always helps me understand it better) and also looked at some other articles and i think the SetWindowsHookEx technique is the one i want. As you said, Amrazek, once the DLL is loaded by SetWindowsHookEx i can use any other functions in the DLL. I just have to make sure that it is actually loaded when i call those functions, as the article says "the DLL won't be mapped into the remote process until a message is actually sent to (some window of) the hooked thread.". So after i call SetWindowsHookEx, i would just loop through all windows in the system and send them some dummy message (like WM_NULL).Ok, now come the follow-up questions [grin]:When using a shared data segment (#pragma data_seg...), how does my application share that data with the DLL in each remote process? If i create a Visual Studio project for my DLL and i have another project for the main application (the EXE), how do they both know about the shared segment? Where do i declare these variables?I am planning on communicating with my main app by having the DLL send it WM_COPYDATA messages where the data it sends contains info about the message that the remote window received. Is this a good idea? I mean, considering that it's sending a message in response to another message. Obviously the DLL would have to check if it is loaded in my own application, and not send the message then, otherwise i would get infinite recursion as it sends the WM_COPYDATA message then detects it's own message and sends it again, and again... But apart from that, are there any other pitfalls to this method, and are there other ways?   ;Quote:Original post by XTAL256No that's the 3rd option, the one not requiring a DLL. I am asking about the "CreateRemoteThread & LoadLibrary" technique.The main difference is that SetWindowsHook doesn't give you exact control over when exactly the DLL gets mapped (which can be a bad thing if what you want to do is time-sensitive, like detouring DirectX before a program is able to create a device in order to get control over said device).  Depending on how you set the hook, it could also impact system performance and cause some ruckus in the target process.  CreateRemoteThread/LoadLibrary is less overt but requires special access privileges in vista/windows 7 which may themselves require your program to be run in administrator mode or be silently blocked by the UAC, and aren't supported in 95/NT if that even matters these days.Quote:When using a shared data segment (#pragma data_seg...), how does my application share that data with the DLL in each remote process? If i create a Visual Studio project for my DLL and i have another project for the main application (the EXE), how do they both know about the shared segment? Where do i declare these variables?The shared data is stored in the DLL you'll be injecting.  Your own program will also load a copy of this DLL and through it be able to change those shared data members.  When you change a shared data member in your program's DLL, it also changes in all other instances of the DLL.  You can also respond to events this way (in a crude fashion).  Be very careful if you share anything that's capable of allocating memory (strings, vectors, objects) because it'll crash when the wrong DLL instance tries to access it.Quote:I am planning on communicating with my main app by having the DLL send it WM_COPYDATA messages where the data it sends contains info about the message that the remote window received. Is this a good idea? I mean, considering that it's sending a message in response to another message.Glancing at the MSDN doc, it looks like it'll work well.  The simpler the better when you're passing data between live programs you can't debug easily.Quote: Obviously the DLL would have to check if it is loaded in my own application, and not send the message then, otherwise i would get infinite recursion as it sends the WM_COPYDATA message then detects it's own message and sends it again, and again...Don't send data from one DLL instance to another DLL instance.  Have the DLL keep track of the hWnd of your controlling program and specifically target it with that message.  If you can't find the hWnd, your controlling program isn't running and no message needs be sent.Alternatively, have your program poll some shared data periodically.  Or create a shared memory segment and share data that way.  There are other ways of IPC too, such as sockets and named pipes.  I have little experience using those though.(Edit)The article mentions some other good reasons for each method at the very end.  CreateRemoteProcess won't work on a process that doesn't link with kernel32, for example[Edited by - Amrazek on April 9, 2010 6:04:37 AM];Quote:Original post by AmrazekThe main difference is that SetWindowsHook doesn't give you exact control over when exactly the DLL gets mappedYeah, but i can easily control that as i indicated above (by sending an initial WM_NULL message to each window to ensure the DLL is loaded).Quote:Depending on how you set the hook, it could also impact system performance and cause some ruckus in the target process.  CreateRemoteThread/LoadLibrary is less overt but requires special access privileges in vista/windows 7 which may themselves require your program to be run in administrator mode or be silently blocked by the UAC...Yeah, i read that hooking would have a bigger impact on performance. But CreateRemoteThread would still need to monitor messages and do pretty much all that a hook would do, how would that be much better performance?Quote:Quote:Obviously the DLL would have to check if it is loaded in my own application, and not send the message then, otherwise i would get infinite recursion as it sends the WM_COPYDATA message then detects it's own message and sends it again, and again...Don't send data from one DLL instance to another DLL instance.  Have the DLL keep track of the hWnd of your controlling program and specifically target it with that message.No, i didn't mean from the DLL to itself exactly. I meant that the application (EXE) would receive a WM_COPYDATA message from the DLL loaded in it's own process, to tell it that it has received a message (e.g. WM_MOVE). But the WM_COPYDATA message itself would also be detected by the DLL and then it would send yet another WM_COPYDATA message.Also, i am planning on using the shared data segment to hold the HWND of my application's window (as is done in many of the articles) so that the DLL knows who to communicate to.   ;Quote:Original post by XTAL256No, i didn't mean from the DLL to itself exactly. I meant that the application (EXE) would receive a WM_COPYDATA message from the DLL loaded in it's own process, to tell it that it has received a message (e.g. WM_MOVE). But the WM_COPYDATA message itself would also be detected by the DLL and then it would send yet another WM_COPYDATA message.This bit doesn't make sense to me now.  So you have an external DLL that you've injected into a target that will send a WM_COPYDATA message to another instance of that DLL that's loaded in your program, and THAT instance of a DLL will send the message up to your program?  Why do the middleman bit?  I'd send the data directly to your program's WndProc.  How many different instances of the DLL are you going to have?  Are you targeting a number of processes at once?;  You seem to be reading too much into what i say, Amrazek. I meant exactly what you said you would do: send the data directly to your program's WndProc. I never said anything about the DLL sending a message to another DLL,Quote:application (EXE) would receive a WM_COPYDATA message from the DLLBut you do realize that the DLL would be mapped into every running process with a window, right? And that would include my own application that is to receive the WM_COPYDATA messages. You see what i mean? Anyway, i have that bit figured out.   ;  This whole time I was under the impression that you had a specific target in mind.  You're just mapping your DLL into every process?  That makes things clearer, especially the bit with you treating your own application like a target.  Your concerns about the WM_COPYDATA message now make sense when they didn't before.I'd personally just have a bool shared value in the DLL to identify your own program's DLL, and not respond to WM_COPYDATA the default way in that DLL.;  Hi.  I’m the author of MHS, the #1 game-hacking tool now ahead of Cheat Engine.It does everything you want.The method of injection you want is the CreateRemoteThread() version.I will assume you only need conceptual advice and will not be posting actual code.Find online one of the many tutorials on injecting DLL’s using this method.Once your DLL is injected, subclass the target window.  All messages received by the window can then be handled by your own routine inside your DLL.  From here you can do anything with the messages you want.In order to connect your DLL to your main process, have your DLL export a function that your main process can call remotely (using CreateRemoteThread() again).  Your function must be __stdcall and accept 1 (one) parameter.The parameter will be a pointer to a structure in memory in the local process space (of the DLL).  That means before your main application can call that function it will first use VirtualAllocEx() to allocate space in the DLL process, then WriteProcessMemory() to fill the structure.  It then calls your exported DLL function with the address allocated via VirtualAllocEx() (which is the address of the structure containing the data your DLL will need to interface with your main application).The structure will need to contain the process ID of your main application.  The function in your DLL will use this to call OpenProcess() on your main application and can then call functions in your main application the same way your main application calls functions in your DLL.  Other things the structure may include are function addresses in the main process.Using this communication system you are now free to transfer anything about the window’s message you want to the main application.As for your second issue, you probably want to be able to call any function in the target process with any number of parameters, and with any calling convention.This is the same as before.  You must define a structure that contains all of these parameters (number of parameters to pass, each parameter as an array, the calling convention, values to set in EAX, EDX, ECX, EBX, etc., etc.)Main application allocates this structure in the DLL process, fills the values in with WriteProcessMemory(), then uses CreateRemoteThread() on your special DLL routine which accepts a pointer to that structure.The DLL uses that information locally and with the help of same ASM sets up the stack, pushes parameters, sets registers, and calls the target function (whose address must also be included in the structure).By returning the EAX value after the called function returns, you can set the return value for your thread which your main application can use as well.L. Spiro   