3

I'd like to prevent a specific third-party DLL file from loading into my application's process at runtime. My initial attempt at this was using the MS Detours product.

I have a 32-bit MFC application running on Windows 10 64-bit. I tested with the free MS Detours 3.0 version as a feasibility check.

In my MFC application class constructor, I call Detours to intercept the "load library" APIs (LoadLibraryW, LoadLibraryExW, LoadLibraryA, and LoadLibraryExA). This lets me intercept library loading and currently I just log out the name of the library being loaded and then call the original API so it proceeds to load the library. The eventual plan would be to look for the specific third-party DLL file name and in that case just return failure, preventing the DLL file from loading.

This sort of works. When I run my test application, close it, and then check the log I see a bunch of library load messages logged from my intercept functions.

BUT, my code never sees the particular third-party DLL file I'm looking for. What's happening is that the third-party DLL file is already loaded by the time I get to my application class constructor. So I'm too late!

How can I get some code to execute EARLIER and so hopefully install the detours stuff BEFORE the third-party library gets injected?

Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85
Nerdtron
  • 1,486
  • 19
  • 32

2 Answers2

4

Sounds like either:

  • your app is static linking to the target DLL directly

  • one of your app's dependent DLLs is static linking to the target DLL, or otherwise loading it while itself is being loaded.

  • the target DLL is listed in the AppInit_DLLs Registry key.

  • another process has loaded the DLL as a global hook via SetWindowsHookEx(), using a hook type that injects the DLL into all running processes.

Nothing you can do to intercept the target DLL if it is being loaded before your app's code starts running. Statically linked DLLs are loaded by the OS before the EXE's code starts running. So only dynamically loaded DLLs can be intercepted with a detour, and only if loaded after you have installed you detour.

You need to find where the target DLL is actually being loaded from.

If your EXE is static linking to it directly, load it dynamically instead, either explicitly via LoadLibrary() in your code, or via your linker's delay-load feature (if it has one), which uses LoadLibrary() internally.

If another DLL is loading it, load that DLL dynamically instead of static linking to it.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Our app is not statically linked to the target DLL, nor are any of the dependent DLLs. This is a completely independent third party product which, once installed on the system, will inject itself into running processes. I'm looking to prevent it from being inject in mine. – Nerdtron Dec 10 '15 at 02:35
  • 1
    The only ways I know of for a DLL to inject itself into a new process before it starts running code is if 1) the DLL is listed in the `AppInit_DLLs` Registry key, or 2) another process has registered the DLL as a global hook via `SetWindowsHookEx()`. – Remy Lebeau Dec 10 '15 at 03:13
  • right, there are multiple ways for it to happen; in my case its happening and I'd like to figure out how to prevent it. Using Detours as I described originally I think, might work, the problem I'm having is I need to have my code execute early enough so I can get in there BEFORE the third party DLL is injected. – Nerdtron Dec 10 '15 at 14:55
  • 1
    You can't prevent the injection if you don't know how it is happening. Track that down. There are multiple ways of injecting, but there are only so many ways, so use process of elimination. Check your dependencies. Check the Registry. Use SysInternals ProcessMonitor to see if another app is loading the DLL before your app does. My guess is another app may be using `SetWindowsHookEx()` to globally inject the DLL into all processes. If the DLL is injecting before your code starts running, the injection cannot be prevented/detoured in your code... – Remy Lebeau Dec 10 '15 at 17:39
  • 1
    You may have to move/delete the DLL, or kill/uninstall the injecting app (if there is one), or hook the injecting app yourself to detour SetWindowsHookEx() from loading the DLL, etc. – Remy Lebeau Dec 10 '15 at 17:39
  • True, if the DLL is being injected before my process starts then Detours isn't going to do it. However, I suspect its being injected after my process starts but before my MFC app class constructor gets called. My hope is that I can figure out a way to get my code to execute much earlier in the process lifetime. Unfortunately MFC takes over WinMain. So I was hoping maybe someone else had run into this and figure out how to get code executing earlier. – Nerdtron Dec 11 '15 at 05:20
  • I don't think I can go that much on the offensive against this app. I'm hoping on a more defensive approach which lets this app do what it wants otherwise, but just doesn't load into my process. – Nerdtron Dec 11 '15 at 05:21
  • 1
    What makes you think the injection is occurring after your app starts running code? **IF** that is true, you might try creating a static object in global memory and have its constructor install the detour. That will run before `WinMain()` is entered. But that is still no guarantee of catching the injection if it is really that early in the process lifetime. – Remy Lebeau Dec 11 '15 at 06:51
  • I know the injection occurs before my MFC app class constructor gets called. I don't know for sure the injection occurs after my app starts running code. So its possible even at the first code my app runs its too late, but its the next thing I want to try in hopes I can get to it before it injects. To do that, though, I need code executing early enough to at least be able to try that approach. I think your idea about the static object is a good one. I hadn't thought of that. I'll give that a try. – Nerdtron Dec 11 '15 at 13:07
  • I tried using static data init (which was a great idea btw, I had forgotten about how early that gets initialized), but this was too late. The third party DLL was already injected. So it must be injecting itself right as the process is created meaning Detours probably isn't going to do it for me. – Nerdtron Dec 11 '15 at 14:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97666/discussion-between-remy-lebeau-and-nerdtron). – Remy Lebeau Dec 11 '15 at 17:43
1

Probably, your code is referencing some function / export of the third part library.
One way you can try is to use /DELAYLOAD linker option to create stub function for the imported function.

See https://msdn.microsoft.com/en-us/library/151kt790.aspx for an explanation and requirements.

You can even provide an helper function to handle the loading of your dll, so you don't need retour.

alangab
  • 849
  • 5
  • 20
  • No, this is not a library being referenced by my application. Its a completely independent third party product which, once installed on the system, will inject itself into running processes. The goal is to prevent it from injecting into mine. – Nerdtron Dec 10 '15 at 02:36