What exactly is the risk when using TerminateProcess? - windows

My Win32 console applicaton uses a third-party library. After it exits WinMain global objects destruction begins and an AV happens somewhere deep inside. I'm really tempted to just write
TerminateProcess( GetCurrentProcess(), 0 );
somewhere near the end of WinMain. If I do this the application ends gracefully.
But MSDN says that doing so can compromise the state of global data maintained by dynamic-link libraries (DLLs) which is not clear. I understand that if I have some global object its destructor is not run and I risk not finalizing a database connection or something similar. I don't have anything like that in my program.
What exactly is the risk when using TerminateProcess? How do I determine if I can use it for my purpose?

Based on the documentation for that and ExtiProcess it seems the primary concern is that DLL's are unloaded without a call to DllMain with the flag DLL_PROCESS_DETACH.
My 2cents: The documentation is being paranoid that you will upset some critical operation which runs in DllMain + DLL_PROCESS_DETACH. Anyone who depends on that to maintain critical state is already at the mercy of task manager so I don't see a huge risk in using this API.

Generally the bad things will happen when interacting with objects outside of your process. For an example say you have some shared memory used by multiple processes that your process will write to and other processes read and or write to. Typically to synchronize the reading and writing a mutex is used. If a thread in your process has acquired the mutex and is in the middle of making changes when TerminatePorcess is called, the mutex will be abandoned and the shared memory potentially left in an inconsistent state.
I suspect you are miss using one of the third party libraries. DllMain is somewhat limiting so the library may have initialize and uninitialize functions that you are supposed to call.

AFAIK, if you're not doing anything "fancy" (which includes but is not limited to: creating threads, locks, DB connections, using COM objects), nothing terrible will happen. But as Earwicker says, you don't know what OS-wide stuff a DLL is doing, and you certainly don't know if that will change in the future, so relying on this is very fragile.
Aren't you curious to know why this access violation is occurring? It may well be the sign of something that became corrupted much earlier on. Please at least confirm that the bug is caused by this 3rd-party library, e.g. by writing a program that links with the library but whose main() does nothing, and confirming that this causes the same crash.

It depends how you interpret "global data". If you take it to mean (as I normally would) data stored in the process's address space, then the advice makes no sense - we know that memory is going to disappear, so who cares what happens to that?
So it may be referring to OS-wide stuff that a DLL may have done, that persists outside the lifetime of any process. A simple example would be a temporary file that might need to be cleaned up; crash the process too many times and you'll run out of disk space, so probably best not to make a habit of it.

Related

Does process termination automatically free all memory used? Any reason to do it explicitly?

In Windows NT and later I assume that when a process expires, either because it terminated itself or was forcefully terminated, the OS automatically reclaims all the memory used by the process. Are there any situations in which this is not true? Is there any reason to free all the memory used by a user-mode application explicitly?
Whenever a process ends, all memory pages mapped to it are returned to the available state. This could qualify as "reclaiming the memory," as you say. However, it does not do things such as running destructors (if you are using C++).
I highly recommend freeing all memory, not from a resources perspective, but from a development perspective. Trying to free up memory encourages you to think about the lifespan of memory, and helps you make sure you actually clean up properly.
This does not matter in the short run, but I have dealt with countless software programs which assumed that they owned the process, so didn't have to clean up after themselves. However, there are a lot of reasons to want to run a program in a sandbox. Many randomized testing scenarios can run much faster if they don't have to recreate the process every time. I've also had several programs which thought they would be standalone, only to find a desire to integrate into a larger software package. At those times, we found out all the shortcuts that had been taken with memory management.

Out of Memory Message box

I have an MFC application developed with VS2003
It is working fine in XP vista etc.
But when i have executed it in windows 8, and we use it for some time,
then no window is displayed. Instead of that the a MessageBox with a message 'Out of Memory' is displayed. And the Message box is Having the caption of my application.
This issue is rarely occurred in windows 7 too.
I have tried watching the handles using tools like processexplorer and it is not increasing.
Also many forums says that it is because of increase in unclosed handles or resources.
Can any one suggest how can i find where the issue is. Or any one provide possible reason for this.
I cant setup the devenv in the machine causing the issue. I am confused how to diagnose by executing a test build in that.
Please provide your findings.
Thanks in advance.
You clearly have a memory leak somewhere. It's hard to be any more specific without seeing the code.
A debugger is really the best way to solve this problem. If you can reproduce the problem on your development machine, that would be the easiest case. If not, you can attach a debugger to the running process on another machine, either locally or remotely.
The MFC libraries also support some basic memory leak detection, turned on by default for Debug builds and controllable for other builds using the AfxEnableMemoryTracking function. You can use this feature to obtain information about which blocks of memory were allocated but not properly deallocated (i.e. were leaked).
Like you mentioned, Process Explorer is another good way to track down resource leaks. Are you sure that the handle counts are remaining constant rather than trending upwards over time? If the values in the columns are never changing like the question suggests, then you are surely doing something wrong. Your application has to be creating objects in order to do its job. The point is to make sure that it disposes of them when it is finished.
If you can't reproduce the problem with the running application and have only the source code available, you'll need to go through the code and make sure that every use of new has a corresponding use of delete (and that new[] matches up with delete[]). And in general in C++, you should avoid explicit dynamic memory allocation wherever possible. Instead, use the container classes that are provided either by MFC or the standard library. For example, don't allocate arrays manually, use std::vector to do it for you. These container classes ensure that the memory is automatically deallocated in the destructor when the object goes out of scope.

Can I unload a DLL from another process? (Win32)

I want to unload a DLL from another process. Is it possible?
If yes, how to do that? (I'm using Win32 API)
Thank you very much.
Yes, this is possible. It is called DLL ejection and is featured by some DLL injectors. The way a DLL is usually loaded is via LoadLibrary and it is subsequently unloaded via FreeLibrary. FreeLibrary takes only one parameter which is a handle to the module to be unloaded. If you injected the DLL in the first place, you should be able to find this very easily. Otherwise there are ways of obtaining the handle such as CreateToolHelp32Snapshot with further enumeration with Module32First/Module32Next. Suppose you have obtained the handle through some means, then the steps to eject the DLL are simple:
Get the address of FreeLibrary with GetProcAddress. This address will match the one for the same function in the target because of how Windows works.
Call CreateRemoteThread on the target process, specifying lpStartAddress as the address of FreeLibrary, and with lpParameter as the module's handle
There are several caveats to DLL ejection.
You should only ever eject a DLL which you are certain no code is going to make use of again in the future. If any dynamically linked code attempts to make a call to your code after it has been freed, it will most likely trigger some form of page access violation.
You should ensure that no threads are executing within the code of the DLL whilst ejection is being performed for similar reasons.
DLL ejection should be avoided with general. If the library wants to have the option of being freed, it should supply some interface which users can access it through which eventually calls FreeLibraryAndExitThread.
If you require a code example for this, I have written an ejector as part of an injector I wrote in the past in C. I can search it up and find it but it's from many years ago and the code quality is not likely to be good.
You don't want to do this.
"Loading" a DLL is much more than simply opening (and locking) a file. When the NT loader starts an executable, it processes all the DLLs referenced by the image (recursively) and wires up the function calls (recursively): loading the DLLs, calling the DLL initialization code, etc.
Unloading a DLL would mean that you'd need to stop all processes that loaded your DLL, load the new DLL, and perform all the operations the NT loader would. Of course, unloading and re-loading a DLL would need to restore that old DLL's state (initialized variables etc), an operation which is not specified in Win32.
For a bit of background information, see this article on MSDN and this Under the Hood article in MSJ.
Short answer: No, it is impossible.
Win32 doesn't provide an API to unload a DLL of another process. If a library is freed unexpectedly, the process will crash. This leads to a serious security hole as it breaks process protection mechanism.
If you can modify both of the processes, you can modify the application and add routines to free a library, and let the other application to send the message.
I would instead look to change the function called when the process tries to invoke the functions in that dll. I know this is possible in theory.
It would mean a bit of memory hacking and knowing where the pointers to the functions are stored, but all of that can be found easily enough (ollydbg manages to do it), it would be harder if they use ordinals, even harder if they hard code the pointers, but no one does that nowadays. You could then inject your own code that (ideally) mimics the functions they mask, but does not actually do anything. They will probably have to be injected into the process, and that way you could get it to work without the process ever knowing, and without any crashes.

CreateRemoteThread, WriteProcessMemory, VirtualAllocEx - why use them?

Recently I have been reading up articles about DLL injection and I understand them fairly well.
However, what I don't understand is why APIs such as CreateRemoteThread, WriteProcessMemory(in being able to write to the memory of another process) and VirtualAllocEx(in being able to allocat memory in the context of another process) were implemented in the first place.
What was the original need for such APIs? Just curious.
WriteProcessMemory was made for ring3 debuggers that need to securely write process memory, most commonly for INT 3 breakpoints or user provided memory edits.
along the same line, CreateRemoteThread can also be used for debugging purposes, however, MSDN can enlighten us on CreateRemoteThread a bit more:
A common use of this function is to inject a thread into a process
that is being debugged to issue a break. However, this use is not
recommended, because the extra thread is confusing to the person
debugging the application and there are several side effects to using
this technique:
It converts single-threaded applications into
multithreaded applications.
It changes the timing and memory layout of
the process.
It results in a call to the entry point of each DLL in
the process.
IIRC, CreateRemoteThread is also used by debuggers to hook application native expection handlers, commonly set by SetExceptionHandler, which requires call from the target process as the handler is stored in the PEB.
VirtualAllocEx is just how windows virtual memory system operates, it needs a context to allocate in, be it in the current process, a child process or a remote process. VirtualAlloc in fact is nothing more than a pass through wrapper of the Ex variant, it just passes a special constant that indicates the handle of the caller process is to be used.

Verifying process integrity in memory?

It looks like it's impossible to prevent determined attackers from modifying one's process code/data. I'm hoping that its at least possible to detect such tampering.
Under Windows, is it possible to listen for DLL injections, WriteProcessMemory and CreateRemoteThread into the current process?
Under Linux, is it possible to listen for LD_PRELOAD and the DR rootkit?
with some really involved code you could be able to detect those...
It all depends on how determined the attacker is... IF they are really determined then they would use some rootkit approach - in that case your app can do nothing about it (no detection, no stopping as long as the attackers know what they are doing)...
another approach could be to try to do some hashing of your segments in memory while running but that would account for some snake oil since the hashing code itself would present an entry point to circumvent this method.
Executing your code inside a self-built VM which in turn communicates with the rest of the system through a hypervisor... the hypervisor has to be made the boot loader for the system of course so that the OS is just a "child" of your hypervisor... should do the trick...although you would have to write all that yourself and make sure it has no exploitable weakness (pretty sure noone can do that for such a complex piece of software)...
not sure what you are up against but as long as the HW+SW your code is running on is not directly under your full control there is always a way to do the things you mention and with a bit of planning avoid detection too...
OR is this "only" about protection from software piracy/reversing ?
IF so then there are some measures, even some 100% secure ones though it all is about balance of security versus usability...
Huh, how do you tell if LD_PRELOAD is malicious or not? What about ptrace? /dev/[k]mem? What about when one process plants a malicious plugin or something similar in the folder of another process's config directory? What about shared memory / IPC tampering?
First of all, this is a waste of time and complete nonsense to actually sell as a legitimate product. Not sure what you're trying to do. If it's antivirus, anticheat for a game, or DRM, then this is futile. The only thing you can do is run the process as another user, preventing other processes from modifying it in the first place. If that's not good enough, too bad, Linux isn't a secure operating system and never will be.
In theory, it's impossible to detect a process's memory being tampered with. In practice, it depends on how you define detect, and what kind of false positives and false negatives you care about.
If you know the normal behavior of a program is not to modify itself, you know exactly what segments of memory are meant to be static, and you know that there aren't any legitimate 3rd party programs on your PC that tamper with the program, then you may be able to detect memory tampering pretty easily.
The most general solution is to hook the OSs interprocess memory modification mechanisms like you said. This works as long as the enemy process doesn't have enough privileges to remove your hook or make certain OS calls that bypass your hook.
You can also just scan the entire process over and over, checksumming the memory using a secure hashing algorithm. Then again if the enemy process has privileges to modify your scanner, you lose.
So yeah, if the process hasn't the privileges to subvert your scanner, why would it have the privileges to modify the process you care about? Sounds like antivirus/anticheat/DRM to me.

Resources