How “safe” (from a best practice and supportability perspective) is the use of DLL injection techniques?


Another question in internal discussion.


Here is one reply:






From:
Subject: RE: DLL Injection




DLL injection is never safe.  You’re talking about squirting code into a process that was never designed, built, or tested by the process’s author, and co-opting or creating a thread to run that code.  You run the risk of creating timing, synchronization, or resource issues that weren’t there before or exacerbating issues that were there.

Comments (4)

  1. Ian Hanschen says:

    And yet this is something some companies are forced to do every day, as a matter of practice, due to lack of extensibility in the platform. It’s been happening for at least a decade.

  2. Do you know the reason why those companies opt to use this technique? Just curious.

  3. Ian Hanschen says:

    During some quick multi-tasking I had read this post and hastily responded – I misunderstood the post and thought it meant "any third party code within a process". I now see that it’s using the whole suspendthread/get|setthreadcontext/resumethread/etc mess. I definately do not recommend this and have never used it in any of my work. There are situations where CreateRemoteThread is definately a requirement, but the route of a windows hook is usually best.

    As a side, let’s say you want to inject code into a process where windowing hooks are not loaded, and there is no formal method for introducing your code to the process(for example winlogon has GINA). And let’s say the OS in question does not have CreateRemoteThread(), and you have to introduce your code to this process for your product to be effective. Then you’re in a situation where you’re either re-evaluating the whole idea or having to get really creative. I almost went this route when injecting some code into a process on Windows CE 3(no CreateRemoteThread), but instead opted to get more creative and come up with something a little less invasive. Windows CE has an api – PerformCallback4, which is used to execute code in another process under the context of the current thread(basically threads can move across processes on the OS with help from the kernel).

    So the route ended up being:

    1) Alloc space in remote process

    2) Write code to perform my task(in this case it was generating an apiset call to load a dll)

    3) Set it executable

    4) PerformCallback4() into the process using the current thread.

    5) Free the remote block of code after the thread has returned from the call.

    Sometimes you just have to get creative to get the job done – especially in situations where there are no friendly ways to do what you want – some would argue that you simply should not attempt something if the OS was not designed for it. I argue that that simply stifles a lot of innovation. That doesn’t mean I think developers should start trampling across the process list doing god knows what, but I believe that there are a lot of interesting things that can be done if you move a little bit ‘outside of the box’, and truely take the time to get a deep understanding of the consequences of any attempts. Take a look at what we’ve done – http://www.stardock.com. WindowBlinds, WindowFX, DesktopX, ObjectBar..the list goes on. There’s definately a balance to it.

  4. Nicky says:

    How to use PerformCallBack4? because this function have structure CALLBACKINFO and what parameter LPVOID1 , LPVOD2 ,..