I'm working on an application (DLL) that logs specific WIN32 calls using Detours. It is injected into a target application that passes the filter. It has to absolutely log every call that the application makes, starting from the first instruction in the application's entry point.
I now am looking for a way to make my application (the one that always runs) inject the DLL as fast as possible, preferably without the target application making any other calls.
Is there any way to achieve this?
You could use the AppInit_DLLs registry key to load a dll into a process. The dll is loaded during DLL_PROCESS_ATTACH of User32.dll. For regular applications this should happen prior to running any application code.
Keep in mind though that AppInit_DLLs should be renamed Deadlock_Or_Crash_Randomly_DLLs.
As far as I know, there's no straightforward way of doing this in Windows.
Your options are:
Hooking the CreateProcess (or lower) function in all processes. When a new process is created, change the arguments to create it as suspended, inject, and resume if needed.
Using a driver.
Related
Currently I am working on a application in which I need to hook dll into running application. In order to achieve this goal, I have updated the LoadAppInit_DLLs registry key to 1 and AppInit_DLLs has been set to the location of the dll.
This approach works fine as the application get opens the dll get injected into the process of that application.
However, this injection process not only inject the dll into the application that I am interested, but it injects it for all the applications that I am starting in windows operating system. How could I specify this inject to happen only for the application that I need it to inject and not for all the application. I am looking for a way to know from the dll that which application it is calling and then to decide whether to load it or ignore loading it.
How could I specify this inject to happen only for the application that I need it to inject and not for all the application.
Using AppInit_DLLs, you can't.
Working with the AppInit_DLLs registry value
All the DLLs that are specified in this value are loaded by each Microsoft Windows-based application that is running in the current log on session.
I am looking for a way to know from the dll that which application it is calling
A DLL is loaded into the address space of a process. A DLL can call GetModuleFileName(NULL) to get the
full path and filename of the process it has been loaded into.
and then to decide whether to load it or ignore loading it.
Normally, a DLL's DllMain() entry point allows the DLL to selectively abort loading by returning FALSE to the DLL_PROCESS_ATTACH notification. However, AppInit_DLLs specifies additional DLLs that are deemed required for successful app initialization, similar to static-linked DLLs, so it does not allow DLLs the luxury of selective loading. If an AppInit DLL returns FALSE, the whole process is aborted.
You will have to manually hook the DLL into the target app yourself. You can do that by either:
Using CreateRemoteThread() to call LoadLibrary() from inside a specific process to load the DLL into that same process. The DLL's entry point does not need to validate the loaded process, since the loading app has already done so when deciding which process to load the DLL into.
This approach takes some setup, though. You have to use VirtualAllocEx() and WriteProcessMemory() to copy the DLL's full path string into the target process before you can then have the remote thread call LoadLibrary() with that path string as input.
Using SetWindowsHookEx() to install a global system-wide hook that is implemented inside the DLL, so the DLL gets loaded into every running process.
The difference between this approach and using AppInit_DLLs is that this approach is handled dynamically after each process is running, and thus allows the DLL the luxury of selectively aborting its own loading without terminating each process it rejects.
Configuring the Application Compatibility Toolkit to load your DLL into the specific app(s) you are interested in.
All DLLs, listed in the LoadAppInit_DLLs registry key will be loaded to the all processes, linked against user32.dll. If for some reason your dll is unable to load (for example - you had returned FALSE from the DllMain on DLL_PROCESS_ATTACH) the process will be terminated. Using LoadAppInit_DLLs even for the debugging purposes is messy and pretty dangerous. Perhaps you should choose another hooking mechanism, for example using SetWindowsHookEx
I am trying to use dll injection to intercept a call to Direct3DCreate8 from my application to acquire a handle to the Direct3d device and draw an overlay on the screen that it projects. The call to this API happens right after the application's execution which, if I understand correctly, renders useless the dll injection into running process technique as the API call I was after has already happened when I inject the dll.
Is this assumption correct? If yes, how can one inject the dll during process execution to catch a desired API call?
EDIT: I am aware of system-wide api hooks but would be nice to hear a 'local' solution to this problem.
EDIT 2: Forgot to mention, replacing the .dll in the application's folder is of no use, as the application looks for the .dll (d3d8.dll in my case) in System32/SysWOW64 directories.
Being a bit late for the party I wanted to offer you a solution of using Microsoft Detours (which is free for non-commercial use on x86 platforms and costs tremendous money otherwise). They have a DetourCreateProcessWithDllEx function that might suit your needs.
Quoting Detours documentation:
The process is created in a suspended state with the CREATE_SUSPENDED flag to CreateProcess. Detours then modifies the image of the application binary in the new process to include the specified DLL as its first import. Execution in the process is then resumed. When execution resumes, the Windows process loader will first load the target DLL and then any other DLLs in the application's import table, before calling the application entry point.
I am trying to inject my code to another process using CreateRemoteThread, but if my code is being injected while process is loading DLL's, thread becomes frozen until DLL's are loaded (it is OK according to MSDN). I have tried to detect if process is loaded by injecting code and waiting for result and checking EAX then, but it is very slow.
So, I'm looking for method to check if process is still loading DLL's or it has all DLL's loaded and I can call CreateRemoteThread to wait my code being executed immediately.
Use the Debug API, run your target process as a debugee and have your injecting process be the "debugger", you will then get informed of all of the DLL load/unload events and also when the process is loaded and ready to run (you hit the "loader breakpoint"). It gets more complex for x64 and more complex still if you're trying to inject into managed code but it works pretty well.
I have several tools which use this method (here and here) no source code available, sorry.
If what you are trying to do is hook various APIs, then the canonical way of doing this is to always also hook LoadLibrary() so that you can hook any NEW DLLs that are loaded whilst the process is running. I still find it useful, however, to control the target process using the debug api as it makes it easier to hook as soon as you can (at loader breakpoint, before you resume the process).
Since you already have a HANDLE to the target process, try using WaitForInputIdle() before calling CreateRemoteThread().
I have a process that doing some inline hooks on WinSock module (Send and Receive functions).
On a machine with McAfee I can see that two dlls are being injected into my process:
hipi.dll
hipqa.dll
Both are also doing probably inline hooking on those functions and I get collisions and unwanted behaviors. Is there an option to prevent/unload those dlls so they will not interfere?
10x,
Guy
There are many scenario to achieve DLL injection(Hooking), BTW, you must learn more about how stuff works behind every method, the most common one is by using CreateRemoteThread() API function, then you must to inject your security DLL on every process and hook/redirect/deny any call to CreateRemoteThread() or any "dangerous" API call.
PS: BUT keep in your mind:
user-mode hooking can NEVER be an option to apply additional security
checks in any safe manner. If you only want
to “sandbox” a dedicated process, you know well about, and the process in fact doesn’t know about
EasyHook, this might succeed! But don’t ever attempt to write any security software based on user
mode hooking. It won’t work, I promise you…
You have 2 options.
Add an exclusion for your process so that McAfee doesn't attempt to scan it. I don't use McAfee's products, but I would assume that this would be a relatively straightforward process.
Uninstall McAfee
The easiest solution is to just unhook the affected functions. I had to do the same to work around some Dell crapware. It's not excessively hard, even though it requires some understanding of x86 assembly. You have to disable DEP, make the patched code writeable, find the original instructions, and copy them back. Finding the original instructions probably means disassembling the patch.
Another alternative is simply to hook it at a different place. For example, hook the IAT instead and then when you are done with whatever you want, forward execution back to the real function where it will then go through McAfee's hook.
I've had to deal with something similar once. Read their own hook assembly stub, so you can figure out how to hook in a way you chain to their hook after yours.
I'd imagine that McAfee are performing DLL injection from kernel-mode. They are likely finding the address of the KeServiceDescriptorTable (exported by NTOSKRNL on 32-bit systems and the address to it is leaked on 64-bit environments by KiSystemServiceRepeat -> close to KiSystemCall64 found by the IA32_LSTAR Model Specific Register) and then locating NtCreateThreadEx from the service table, or they're using KeInitializeApc and KeInsertQueueApc (both exported by NTOSKRNL) for APC injection (custom NtQueueApcThread wrapper). That would be logical considering they are a security vendor with a lot of resources, I doubt they'd be injecting from user-mode.
The likelihood is they are abusing PsSetCreateProcessNotifyRoutineEx or PsSetLoadImageNotifyRoutineEx to detect new process creation. The first one is not as good as the latter, the latter is better for filtering of NTDLL.DLL since it is the first module loaded into every single process, and signifies the process has actually started up properly and is just about ready to execute its own code (after the Windows module loads, and because McAfee will need to wait for Win32 modules like kernel32.dll to be loaded otherwise they'll crash the process if they use the Win32 API at all in their injected modules).
You can try intercepting LdrInitializeThunk or KiUserApcDispatcher, but honestly, there's not much you can do. McAfee will find a way to inject into your process no matter what you do, because they have control from kernel-mode. If you develop process protection via a variety of kernel-mode callbacks from a driver, they'll bypass it using non-exported routines located via pattern match scanning of ntoskrnl.exe, or exported routines which don't invoke the callback notification APIs. If you locally patch routines invoked for thread creation/APC locally in your own process when performed by a remote attacker, they'll find ways to prevent this and bypass it (e.g. patch the patched routines in the address space of your process back to the original, inject, then re-patch the bytes back).
You're playing with fire if you want to stop security software with the privileges McAfee has. It is similar to how Anti-Cheat cannot stop game hackers who have kernel-mode access, and go do drastic measures of even flagging Debug Mode/Test Mode enabled nowadays.
One part of some software I have written is a COM dll.
Other software uses this COM dll.
My software has an update function where it will download a newer version of the dll, but the update will fail if the dll is in use because the file cannot be deleted or written to.
The question is, how can I update a COM dll that is in use?
I have considered popping up a message asking the user to close any applications that are using the DLL if it is in use, if this is the best solution how would I go about detecting if the COM dll was in use before popping up the message?
Thanks in advance.
You cannot update it in place for existing applications, but one way to do this would be to save it with a different file name or different folder and call DllRegisterServer on the DLL to register it under the new name. New applications which begin using your object should now use the new version.
If this is just a matter of detecting whether you can replace the file then it is easy. Just try to open it with a share flag that denies reading. That's going to fail if the DLL is loaded in another process. Use _fsopen() or CreateFile(). Beware of the race condition.
Detecting which processes have the file loaded is a harder problem, CreateToolhelp32Snapshot() and Process32First/Next plus Module32First/Next to enumerate processes and the DLLs they have loaded. Still tough to generate a good diagnostic for the user, the process name isn't that helpful.
When you have downloaded the update, you must launch a third program (which you write) that does not have any dependancies on your COM component, or any other piece that is to be updated. This launcher, or bootstrapper, must shut down all your pieces, uninstall them, and install the update. When the update is installed you may then re-launch your application.
If you need also to download updates to the updater itself, your main program can do that.
Here is a simple solution for you. Create a wrapper DLL, which will be used by the other processes. Inside that DLL you explicitly load/unload your DLL, which is subject to updates. Of course you will have to suspend all callers when an update process kicks in.