Protect my own process from being injected through AppInit_DLLs

c++ / delphi package - dll injection and api hooking
Post Reply
leochou0729
Posts: 9
Joined: Tue Nov 02, 2021 2:46 pm

Protect my own process from being injected through AppInit_DLLs

Post by leochou0729 »

Hello,
I try to inject my own DLL using madCodeHook driver and hook ntdll's LdrLoadDll to prevent my own process from being injected through AppInit_DLLs.
But I find my DLL is loaded later than the one specified in AppInit_DLLs. Is it any way to implement it? Modifying the registry values manually is not an option for me. I need to do it programmatically. Thanks!

Regards,
Leo
iconic
Site Admin
Posts: 1090
Joined: Wed Jun 08, 2005 5:08 am

Re: Protect my own process from being injected through AppInit_DLLs

Post by iconic »

Hello,

AppInit_DLLs are loaded when user32.dll is initialized, if an app is statically linked to user32 (any GUI process is by default) then AppInit_DLLs will be loaded earlier than when MCH default injection gets a crack at it. You might see if the IAT injection flag works, it *should* however the issue is that your hook DLL can not be unloaded any longer as a side effect. The flag you can test with is USE_IAT_DLL_INJECTION, but if memory serves me correctly, your hook DLL must export at least 1 function/symbol even if it's a do-nothing function, some people even export DLLMain but I've never been a fan of this personally.

The entire concept of importing a DLL is so that said DLL can expose functionality to the rest of the process and its modules, in this case via exported data of some sort. It does not have to actually be really used however =) Dummy functions work fine as the OS does not care as long as at least something is exported.

As per the madCodeHook documentation:
// By default, the madCodeHook injection driver injects your DLL into newly
// created processes by hooking "NtTestAlert()". Which the OS loader usually
// calls the first time right before executing the EXE's "main()" entry
// point.
// Optionally, you can activate the new IAT patching logic, which will
// modify the EXE's import table in such a way that your hook DLL appears to
// be statically linked to by the EXE. This way the OS loader will actually
// do the dirty work for us and load your hook DLL together with all the
// other statically linked DLLs. Unfortunately this also means that the OS
// considers your hook DLL essential to the new process, so we can't ever
// uninject it again.
// param: bool
// default: false
USE_IAT_DLL_INJECTION = $00000014;
Source: http://help.madshi.net/mchOptions.htm

--Iconic
leochou0729
Posts: 9
Joined: Tue Nov 02, 2021 2:46 pm

Re: Protect my own process from being injected through AppInit_DLLs

Post by leochou0729 »

Hi Iconic,
My app needs to inject DLLs into third-party applications to show watermarks, control printing jobs, etc., as well as to protect my own processes from being injected. I have a stub DLL that is prebuilt and bound to the MCH driver. It will load other DLLs based on the app configuration. I also need the injected DLL to be unloaded upon uninstallation. For my own processes, it doesn't matter that the injected DLL cannot be unloaded because I will quit all my processes during uninstallation.

I have two questions:
1. Does calling SetMadCHookOption with USE_IAT_DLL_INJECTION configure the MCH driver globally? If so, my stub DLL cannot be unloaded either.
2. Does calling InjectLibrary with INJECT_VIA_IAT_PATCHING have the same effect, except that it only affects the specific DLL?

Right now, I am using a more direct method. I create a new DLL that hooks LdrLoadDll in DllMain and exports a dummy function. Then, I link it with my executables before any other import libraries. Although it is still loaded later than user32.dll (according to ProcMon logs), I find that LdrLoadDll is always hooked before user32.dll loads the AppInit DLLs. I'm not sure if this is a coincidence. The ReactOS source code looks too complicated for me. Could you please share what you know about how it works internally? Thanks!

Leo
iconic
Site Admin
Posts: 1090
Joined: Wed Jun 08, 2005 5:08 am

Re: Protect my own process from being injected through AppInit_DLLs

Post by iconic »

Hello,

I understand your situation well enough, madCodeHook's earliest injection mode is IAT injection so that's the best it offers for early injection. AFAIR it's a driver flag (USE_IAT_DLL_INJECTION) *only*, TBH it's been a while since I've even used it. The only downside as I mentioned previously is that there is no supported way to unload the injected module since the process considers the DLL imperative to operation, an essential component if you will.

The typical loading + init for modules (simplified) is this:

Statically-linked -> TLS callbacks -> NtTestAlert(flush APC queue of target prior to running) -> Program Entrypoint

As far as user32.dll and AppInitDLLs, I just know that they're loaded as soon as user32.dll's init() is called, it's been a long time since I needed to hook anything that early TBH so I can't add anything more to this thread.

--Iconic
Post Reply