how to prevent dll loading

c++ / delphi package - dll injection and api hooking
Post Reply
jgh0721
Posts: 28
Joined: Tue Apr 22, 2014 8:06 am

how to prevent dll loading

Post by jgh0721 »

i want to prevent dll loading in globally.

1. LdrLoadDll hook per each process
- i worried about crash with madcodehook
2. madcodehook unique feature?
- per each dll loading event call my callback routine
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: how to prevent dll loading

Post by madshi »

May I ask which purpose this is for?

Generally, hooking LdrLoadDll should work "fine". The biggest problems I see with this approach are:

1) Many many people want to hook dll loading, using either madCodeHook or other hooking libraries. So you have to be prepared that there could be collisions with other hooking libraries. madCodeHook does its best to be friendly to other hooking libraries, but I can't guarantee that other hooking libraries will play friendly with us. In most cases it should work just fine, though.

2) Of course if you block certain dlls from loading, that could cause crashes in applications. E.g. let's say you block loading of xxx.dll, but application X requires this dll to be present and working. Application X might even do something like "someFunc = GetProcAddress(LoadLibrary("xxx.dll"), "SomeAPI")", without checking if LoadLibrary actually succeeded. So you need to be aware of that blocking the loading of dlls *can* potentially lead to crashes, or non-working applications.
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: how to prevent dll loading

Post by iconic »

If you need to support Vista+ you can use LdrRegisterDllNotification() and inside your callback check that the load reason is LDR_DLL_NOTIFICATION_REASON_LOADED (1) then use the passed-in notification data to determine the DLL. Both the full and base filename via a unicode_string structure are available to you which is the same as what LdrLoadDll() sees. Once you've determined which DLL is being loaded you can overwrite the DLL's entry point with XOR EAX, EAX RET which returns False in DllMain() so the DLL never loads. DllBase is a passed-in structure member as well so you don't need to hunt for it and you can calculate the entry point address easily from that. By doing things this way you don't have to worry about API hook collisions or security software becoming watchfully paranoid. I use this technique in commercial software and my DLL is injected system-wide so it's proven to work reliably and in a stable manner. Just make sure that you remember to unregister the notify routine in your module's DLL_PROCESS_DETACH otherwise the callback will remain installed inside the target process even after your DLL has been unloaded.

P.S: If you must also support XP and below you can call the very undocumented LdrSetAppCompatDllRedirectionCallback() API in which you also receive the fully qualified DLL filename as a parameter and if it matches a DLL of interest you can return STATUS_UNSUCCESSFUL or some other relevant NT error code. This also works just fine and I am using this in software as mentioned above.

--Iconic
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: how to prevent dll loading

Post by madshi »

Uh, here come iconic's special magic undocumented hacks... 8)

Haven't heard of LdrSetAppCompatDllRedirectionCallback() yet. Does it also work in Windows 2000? And does it still work in Windows 10?

I did try using LdrRegisterDllNotification() in madCodeHook to replace my internal LoadLibrary API hook, but I had to remove it again because it proved to not be stable enough. It seems you need to be rather careful about what you do within a LdrRegisterDllNotification() callback. <sigh>
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: how to prevent dll loading

Post by iconic »

Hey Madshi :D

LdrSetAppCompatDllRedirectionCallback() only works on XP and below (2000 should work too) IIRC but it's only really applicable to what the OP asked in this thread, not so much for patching an in-memory/loaded module such that is possible with LdrRegisterDllNotification(). LdrRegisterDllNotification() can be tamed but as you've already mentioned one must be very careful inside the callback function. When your callback is called the loader lock is held and the DLL module is in the pre dynamic linking stage, which is very early. Whatever you do make sure your code doesn't wind up intentionally or accidentally loading another library inside the callback execution. You might also consider deferred processing of the mapped module at least until OEP is called. For one project I jump to my own callback function that has overwritten the DLL's entry point, apply some module patches, write the original prologue back and call the original entry point again. A cleaner solution might be to add your own TLS callback to the module which just points to your code and do whatever you need to inside. In other projects I've had (luck?) simply applying my patches right inside the notification callback itself without any stability issues. I guess it all just depends on what you're doing to the mapped module.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: how to prevent dll loading

Post by madshi »

Well, yes, I have a (complicated) function that runs whenever a new DLL is potentially loaded or unloaded. That function runs through all installed API hooks and checks them. Historically I always had my own LoadLibrary hook and doing all these things in it worked fine. But simply trying to replace my LoadLibrary hook with LdrRegisterDllNotification() sometimes produced stability issues. I could be due to the loader lock, but I think there were other issues, as well.

I guess I could try hacking around it somehow by using one of the methods you mentioned. But honestly, my LoadLibrary hook works fine, so I'm somewhat reluctant to add many new hacks to replace something which already works fine. If LdrRegisterDllNotification() had worked fine without any additional hacks, it would have been a very welcome replacement for my LoadLibrary hook. But as it is, I think I'll stick to what has worked well for many years.
iconic
Site Admin
Posts: 1065
Joined: Wed Jun 08, 2005 5:08 am

Re: how to prevent dll loading

Post by iconic »

Like the popular phrase goes, if it aint broke don't fix it ;)

--Iconic
_NN_
Posts: 55
Joined: Mon Jan 21, 2013 4:00 pm

Re: how to prevent dll loading

Post by _NN_ »

Do you plan to introduce using LdrRegisterDllNotification instead of LdrLoadDll hook ?
I think it will be very handy to minimize number of hooks.

The only problem I encountered with this approach that you must not use API which acquire loader lock, e.g. GetProcAddress .
At least this was situation in Windows 7 some time ago.

Did you think about using PsSetLoadImageNotifyRoutine in the driver ?
It could be much better than any hooks.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: how to prevent dll loading

Post by madshi »

I've tried LdrRegisterDllNotification, but it wasn't stable for me. I need to do things that require the loader lock.

PsSetLoadImageNotifyRoutine is fine to use within the driver. But our hook dlls are loaded in each and every running user mode process. Are you suggesting that the driver should somehow contact the user mode part of madCodeHook in each running process, whenever a new dll is loaded? Calling into user mode from within driver land is really tricky, especially if you want it to happen in a "blocking" way. When a new DLL is loaded, the madCodeHook user mode part has to eventually reinstall/install new API hooks, and it should do so before LoadLibrary() returns to the caller, so there's no chance that APIs of the newly loaded DLL are bypassing our hooks.
_NN_
Posts: 55
Joined: Mon Jan 21, 2013 4:00 pm

Re: how to prevent dll loading

Post by _NN_ »

I've tried LdrRegisterDllNotification, but it wasn't stable for me. I need to do things that require the loader lock.
This is true, but this API is much nicer as long as it is not hooked by itself :)
I am not familiar with your code, but several APIs can be workarounded, like self implemented GetProcAddress, it is not hard at all.

Yeah, talking with user mode from kernel is tricky.
I think the best approach is instead of talking for each module loading, the driver could be configured to monitor dlls and load yours only when needed.
Similar to process dll injection you do.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: how to prevent dll loading

Post by madshi »

I already have my own GetProcAddress etc. I'm not sure if the loader lock is the only problem with LdrRegisterDllNotification. I think I also had some problems with stack overflows, or something like that. In any case, the current solution works fine, so I'm not sure how much time I want to spend investigating why LdrRegisterDllNotification doesn't work well for me. I'm calling my own HookAPI() within the "new dll was loaded" callback. So I'd have to modify *all* code of HookAPI() and all subroutines etc to not aquire the loader lock. That would be an awful lot of code to walk through and modify. With a certain danger of introducing new bugs. For what benefit exactly? Just for the "good feeling" that we use an OS callback instead of a hook?

About your driver suggestion: Again, the problem is handling loaded dlls in a blocking way. If your hook dll wants to hook e.g. directx, then maybe you want the driver to only inject your hook dll once a process loads a directx dll. However, in the moment the driver gets notified about the loaded directx dll, how can the driver make it happen that the user mode loads your hook dll *BEFORE* the LoadLibrary(directx) call returns to the caller? This must be done in a blocking way. If the LoadLibrary(directx) call returns while your API hooks are not installed yet, you're going to miss some API calls you wanted to hook.

In order to make this work, the driver would have to magically make user mode load your hook dll *and* initialize it (DLL_PROCESS_ATTACH) before the LoadLibrary(directx) call returns to the caller. How is the driver supposed to do that? One way might be to stall the ImageLoad callback in the driver, then create a user mode thread which calls LoadLibrary(yourHook.dll) and then wait until the user mode thread has finished running. But that doesn't sound like a very good idea to me. First of all creating user mode threads from kernel land is kind of nasty. And then, blocking the LoadImage callback in the driver until a user mode thread has finished running is even nastier!

I don't think it's a problem to inject a hook dll into every running process, as long as the hook dll is small, lightweight and doesn't do anything bad. Most madCodeHook users use this approach and it seems to work well.
_NN_
Posts: 55
Joined: Mon Jan 21, 2013 4:00 pm

Re: how to prevent dll loading

Post by _NN_ »

I don't think it's a problem to inject a hook dll into every running process, as long as the hook dll is small, lightweight and doesn't do anything bad. Most madCodeHook users use this approach and it seems to work well.
It is not a real problem, but I am sure it will make many clients to be happier when they don't see any third party dlls in the system processes.
madshi
Site Admin
Posts: 10753
Joined: Sun Mar 21, 2004 5:25 pm

Re: how to prevent dll loading

Post by madshi »

Well, of course you could exclude some or even all system processes from injection. But that's probably not what you want?
_NN_
Posts: 55
Joined: Mon Jan 21, 2013 4:00 pm

Re: how to prevent dll loading

Post by _NN_ »

Well, of course you could exclude some or even all system processes from injection. But that's probably not what you want?
Yes.
I am sure that I can justify my dll in all processes, it is not an issue.
Post Reply