My C++ application is using a 3rd party DLL that provides an API to some external software. There are no other options here. This is the software, API, and DLL that I must use.
I am trying to bomb-proof my interface. When an API call goes bad, the DLL does something that immediately kills the entire process. I've wrapped the call in try/catch, I'm using an SEH translation class that I've used successfully in other projects (and /EHa is selected), and I'm even handling std::unexpected. None of that gets triggered. As soon as I call the DLL function, the process ends.
What other avenues should I look at to protect my process? I want to avoid spinning off a child process for just this API.
The only surefire way to protect yourself from a DLL API gone wrong is to fork a child process and have that process do the DLL interaction (see firefox and plugin-container). For example, if the DLL calls exit nothing you do will catch that.
Related
A while back I made a post regarding creating a dll, for the purpose of injection, that will cause the host application to trigger an Nvidia Optimus laptop to "awaken" the dGpu. This being necessary because of the pathetic system nvidia created here which results in MANY applications not recognizing the presence of the power dGpu, and instead using the integrated intel gpu. (Specifically some video processing apps which take hours longer using Intel's than it would Nvidia's). That post was here.
Suffice to say, I moved to work in Antarctica and gave up on the project. I just picked it back up years later and decided to learn (enough) C++ to program it here. I have created the DLL, and if I place the DX code in a function, then call that function from a host "caller" program.. IT WORKS!!! However, if I put that code in the DLLMAIN, and then simply load that dll from my "caller" program (without actually calling a specific function)... the procedure executes!!! However, when it gets to the part of the code where CREATEDEVICE is run, it crashes. I have since learned this is due to an issue called deadlock, or loaderlock.. i'm not sure which. I understand the concept, but don't have anywhere NEAR the C++ understanding to develop a workaround.
So basically.. can I run my procedure in DLLMAIN using some workaround? Maybe spawning an independent thread somehow (so DLLMAIN can finish executing to it's return?) Thanks for any info. I'll include the vcproject source code here.. but it's a Frankenstein of things I found online.. so don't look for elegance- I know next to nothing about C++ programming! http://s000.tinyupload.com/index.php?file_id=07876333208461296171
The loader lock is a lock which is per-process and owned just after you call LoadLibrary, until just before the LoadLibrary returns. It is intended to ensure the process correctly accounts for the loaded DLLs and their order.
There is very little code which can be added in DllMain which doesn't run the risk of a fail, as any Windows call which may cause IPC can fall fowl of the loader-lock.
If you can create a thread from outside the process, or create a second function you can call directly, then this will be a better solution
I have some doubts about anti dll injection in C++.
I have a game C++ based, Im having problems with hackers with dll injection.
Then i need to prevent it.
I find notify hook there from there:
MSDN - Notification Hooks
But i dont have idea how to use it.
Its is possible notify hook to prevent dll injection?
How its possible? (With and example better).
Can be from dll? (With example better).
Thanks for read that post.
PS: sorry for my english.
Forget it, unless you do very sophisticated things, it's not going to work. By sophisticated I mean something like the code obfuscation, anti-debugging technology used in Skype. Just look at this talk.
You can spend a ton of time on trying to prevent DLL injection, in the end somebody will spend less time than you and circumvent your protection. I think the time would be better invested in an architecture that's more secure and tamperproof (ie calculating scores on the server, etc).
It's a cat and mouse game you can't win.
This question is old but I will briefly answer it in better form for anyone who does happen to stumble upon it magically after a proper response.
You cannot fully prevent code injection from within your own process, but you can try to do some tricks without interception of other processes. It is not recommended because you need to have experience and knowledge with lower-level tasks, especially to get it working properly and not prevent functionality of your own software, however...
Asynchronous Procedure Calls (APC) is an implementation from the Windows Kernel. It is primarily used for code injection into other running processes, Windows uses it a lot itself for a variety of things such as notifications being sent to specific processes. When a user-mode process calls QueueUserApc (KERNEL32), NtQueueApcThread (NTDLL) will be invoked. NtQueueApcThread (NTDLL) will perform a system call which will cause NtQueueApcThread (NTOSKRNL) to be invoked, which is not exported by NTOSKRNL - for anyone wondering, NTOSKRNL is the Windows Kernel, and a system-call is nothing more than a transition from user-mode to kernel-mode since the Native API System Routines exist in kernel-mode memory, NTDLL routines for NTAPI are system call stubs which direct control up to the Windows Kernel. When NtQueueApcThread (NTOSKRNL) is called, it'll use KeInitializeApc and KeInsertQueueApc (both do happen to be exported by NTOSKNL). When the APC is actually issued to the targeted process, KiUserApcDispatcher (NTDLL) will be locally called within the process, unless the APC is performed in a more extensive manner to bypass this activity (99% of the time it will not be prevented). This means that you have an oppertunity to intercept this behavior and prevent APC injection into your own process with one single local hook in your own process, via byte-patching (also known as "inline hooking") KiUserApcDispatcher, exported by NTDLL. The only problem which you will face is that it is undocumented and this is not officially supported by Microsoft; you'll need to figure out how the parameters work and how to prevent the callback routine from blocking off genuine requests which are needed to provide functionality for your own software. This will however include prevention of kernel-mode APC injection, not just user-mode attacks.
There are many ways to inject code into a process, and APC is simply one of them. Another common method would be through remote thread creation. When a user-mode process attacks another process via remote thread creation, it'll typically call CreateRemoteThread (KERNEL32). This will lead down to RtlCreateUserThread (NTDLL), and RtlCreateUserThread will call NtCreateThreadEx (NTDLL). NTDLL will perform a system call and then NtCreateThreadEx (non-exported routine from the Windows Kernel) will be invoked in kernel-mode memory. In the end, the targeted process will have LdrInitializeThunk locally invoked, and RtlUserThreadStart will also be invoked locally. Both of these routines are exported by NTDLL. This is a same scenario as with APC... You can patch LdrInitializeThunk locally, however you must do it properly to prevent genuine functionality within your own software.
These two techniques are not full-proof, there is no "full-proof" solution. There are many ways to inject code into a process, and there are very sophisticated methods to bypass said solutions from myself. Anti-Virus software has been battling anti-RCE/self-protection for as long as I can remember, as has Anti-Cheat systems. You should look into kernel-mode device driver development as well, it'll allow you to register kernel-mode callbacks which can help you out.
The first callback you should look into is ObRegisterCallbacks. It allows you to receive a Pre-operation callback notification whenever NtOpenProcess is called from the Windows Kernel. This means that user-mode processes will also trigger it, since NtOpenProcess ends up being called in kernel-mode after NTDLL makes the system-call. I cannot remember specifically if the callback APIs are triggered in the NtOpenProcess stub itself or if it goes deeper into Ob* kernel-mode only routines, but you can check at ease with WinDbg with remote kernel debugging, or Interactive Disassembler (target ntoskrnl.exe and use the symbolic links provided by Microsoft). ObRegisterCallbacks supports notifications for both handle creation & duplication for the process and the processes' threads, you can strip access rights you don't want permitted for the requested handle.
The second callback you should look into would be PsSetCreateThreadNotifyRoutineEx. This callback routine will allow you to receive a notification whenever a new thread creation occurs on the system; you can filter it out for your own process and if a rogue thread is created, terminate the thread.
The third callback you should look into would be PsSetLoadImageNotifyRoutineEx. This callback will provide a notification whenever a new module is loaded into a process; once again, you can filter for your own process. If you detect a rogue module, you can attempt to have your process call LdrUnloadDll (NTDLL) targeting the base address of the newly loaded image, however the reference count for the module needs to be 0 for it to be unloaded. In that case, you can try "hacky" methods like calling NtUnmapViewOfSection/NtFreeVirtualMemory. Bear in mind, if you mess up the rogue loaded module and it has set memory byte patches to redirect execution flow to its own routines, unless you restore them, your process will crash when they are referenced.
These are some ideas, commonly the ones typically used. Kernel-Mode callbacks are very popular among security software and anti-cheat software. As for thread creation, you'll be interested in mitigating this as much as possible -> if you only look for rogue DLL loads then you'll miss out on reflective DLL loading. Also remember of the other code injection methods, like thread hijacking, shared window memory exploitation with ROP chain call exploitation, DLL patching on-disk, etc.
In c++ ,I want to hook more than one dll to a process. Right now I use CreateProcesswithdll() which can hook only one api at a time. What can I do to inject multiple dlls?
I came across this problem because MS detours requires us to name our custom dll the same as original dll in order to properly detour the api calls. So even though i could have different api calls handled in the same detour dll I created I need to have different names to hook calls from different apis, which means I need different detour Dlls. This also means I need to inject different DLLs. Am I right?
If I am unclear about something I will try to present it more clearly :D
Thanks!
P.S: Just to make my problem more lucid. I need to inject more than 1 dll onto the same process. CreateProcesswithdll() creates a new process with its thread in sleep state. It is woken up after the detours has finished injecting the dll and setting up the hooks. If I want to inject more than one dll I obviously cant repeatedly call CreateProcesswithdll()
so what do i do?? or Is my understanding about some aspect of this wrong?
Calling LoadLibrary() and FreeLibrary() is NOT SAFE from DLLMain(). From TFA:
"The entry-point function should
perform only simple initialization or
termination tasks. It must not call
the LoadLibrary or LoadLibraryEx
function (or a function that calls
these functions), because this may
create dependency loops in the DLL
load order. This can result in a DLL
being used before the system has
executed its initialization code.
Similarly, the entry-point function
must not call the FreeLibrary function
(or a function that calls FreeLibrary)
during process termination, because
this can result in a DLL being used
after the system has executed its
termination code."
EDIT: Apologies - this was meant as a comment for Serge's answer above.
Seems like detourattach and detourdetach will do the trick for me. Thanks everyone!
I found this blog useful!
Obviously you can load any number of DLLs from the first DLL you inject with detours.
EDIT.
When DLL is loaded system runs DllMain of your DLL (with fdwReason==DLL_PROCESS_ATTACH) and then within that function you can do whatever you like, e.g. you can call LoadLibrary to load other DLLs.
ADD:
I totally agree with comments that calling LoadLibrary from DllMain is unsafe. So you can call LoadLibrary (and all the other tricky things) from thread created in DllMain.
Unfortunately, MSDN is not clear enough with it. I'm writing a program which uses a global hook, and I'm worrying about what would happen if the program terminates abnormally (crashes, killed by user, etc).
Does Windows automatically unhook global hooks installed by a process when the process terminates?
If not, is it possible to call UnhookWindowsHookEx() in another process to release the hook? (I'm thinking of doing this in a hooked thread, if it detects that the installer process is dead.)
If the answers were no and no, isn't it dangerous to leave a global hook active when the installer process is terminated? What are the standard methods of dealing with this situation?
I've read in MSDN that UnhookWindowsHookEx() doesn't free the dll loaded in other processes, but it doesn't say when will the dll be freed. This article in CodeProject seems to suggest that the dll is unmapped (in the respective process) when the first message arrives at the hooked thread, so it's about right after the UnhookWindowsHookEx() call. Is it true?
Thank you.
Yes, when a process terminates the system cleans up after it -- all handles are closed implicitly.
No, it's not, and you don't need to anyway.
(It's Yes and no not no and no)
I don't see why there's a DLL loaded in another process involved here. (EDIT: I was originally thinking of a systemwide hook such as CBTProc -- if your hook is per-process that might be different) If you're dealing with something like the link indicated in #Hans' comment, whereby you've injected your own DLL into the target process, then you should put functionality to unload the hook inside your DLL, not tie it's correct operation to your application. (I.e. if sending the message back to your application fails inside the DLL, then your DLL should decide to unload itself) /EDIT When a DLL is loaded inside another process it's up to that process to do the freeing.
If your process dies, UnhookWindowsHookEx is called implicitly and your hooks are removed. The .dll is unloaded by the message processing code after a new message is received. Therefore some background processes which almost never receive any messages, may still keep the library locked long after your hook was removed. Broadcasting a WM_NULL message usually helps. I like sending it a few times after unhooking.
SendNotifyMessage(HWND_BROADCAST, WM_NULL, 0, 0);
What is the difference between the three functions and when to use them??
main() means your program is a console application.
WinMain() means the program is a GUI application -- that is, it displays windows and dialog boxes instead of showing console.
DllMain() means the program is a DLL. A DLL cannot be run directly but is used by the above two kinds of applications.
Therefore:
Use WinMain when you are writing a program that is going to display windows etc.
Use DLLMain when you write a DLL.
Use main in all other cases.
WinMain is used for an application (ending .exe) to indicate the process is starting. It will provide command line arguments for the process and serves as the user code entry point for a process. WinMain (or a different version of main) is also a required function. The OS needs a function to call in order to start a process running.
DllMain is used for a DLL to signify a lot of different scenarios. Most notably, it will be called when
The DLL is loaded into the process: DLL_PROCESS_ATTACH
The DLL is unloaded from the process: DLL_PROCESS_DETACH
A thread is started in the process: DLL_THREAD_ATTACH
A thread is ended in the process: DLL_THREAD_DETACH
DllMain is an optional construct and has a lot of implicit contracts associated with it. For instance, you should not be calling code that will force another DLL to load. In general it's fairly difficult function to get right and should be avoided unless you have a very specific need for it.
[Addendum to your question]
Also don't forget the DllEntryPoint:
When loading time is involved the entry point is DllMain.
(Ex. COM in-process server DLL).
When running time is involved the entry point is DllEntryPoint.
(Ex. LoadLibrary get called).