How can I tell if a Windows module handle is still valid? - windows

A module can be unloaded, so how can I tell for sure if it is still in memory? I have a handle to it, obtained from GetModuleHandle. When I tried calling GetHandleInformation on it I see error 0xc0000008 - "An invalid HANDLE was specified." This happened before it could have been unloaded.

The term "handle" is a bit overloaded here - lots of different classes of objects in the Win32 API are called "Handles".
GetHandleInformation is used for handles to kernel objects - files, registry keys, mutexes, etc.
The HMODULE returned by GetModuleHandle is used by the loader and is not an actual kernel object, hence GetHandleInformation fails. Neither of the flags you get in GetHandleInformation makes sense for HMODULE though.
If you want to check if the HMODULE is still loaded in memory, you can just call GetModuleHandle - this API should be quick enough to call many times. However, the result of GetModuleHandle can be invalid the moment it returns - another thread could have called FreeLibrary. It is better to ensure that the DLL does stay loaded. You can do this by calling LoadLibrary yourself, or by calling GetModuleHandleEx which will increment the reference count of the DLL.

Two solutions:
1
Call GetModuleFileName() on the HMODULE. If the module is loaded you will get a valid filename. If it is not loaded, you won't get a valid filename. Be sure to either set the first byte of the returned filename array to '\0' before you call GetModuleFileName() or to check the return value. If you set the first byte before the call you can effectively ignore the return value and just treat the zero length string as a "not loaded" signal.
TCHAR szModName[MAX_PATH + 1];
szModName[0] = _T('\0');
GetModuleFileName(hMod, szModName, MAX_PATH);
// zero length string if not loaded, valid DLL name if still loaded
2
Call VirtualQuery() passing the HMODULE as the address to query. As an experiment do this on a loaded library and on a library you know to be freed. You will find they have very differentl results for the returned MEMORY_BASIC_INFORMATION. I leave it to you to work out a suitable algorithm to determine the difference between the two.
Caveat
Of course, the caveat that another thread may unload the library while you are running eiher of these tests applies. In my experience, this is highly unlikely to happen, but that depends very much on what you are doing, why you are doing it, and when you are doing it the program's execution path. Use with care.

It's very simple API.
PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)
Sample program:
(PVOID)typedef PIMAGE_NT_HEADERS (NTAPI *RTLIMAGENTHEADER)(PVOID);
RTLIMAGENTHEADER RtlImageNtHeader;
HMODULE hDll = GetModuleHandle("ntdll.dll");
HMODULE hDllTmp = LoadLibrary("ws2_32.dll");
RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hDll,"RtlImageNtHeader");
struct _IMAGE_NT_HEADERS *r,*r2;
r= RtlImageNtHeader(hDllTmp);
FreeLibrary(hDllTmp);
r2= RtlImageNtHeader(hDllTmp);
//r = NULL
//r2 = return ws2_32 PE Header address

Related

What would happen if I use LoadLibraryExW() to load same .dll twitce when ASLR is on?

What would happen if I load same .dll twice or more times using:
handle = ::LoadLibraryExW(dllpath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)
Does it return same address when ASLR(DYNAMICBASE) is on?
Nothing different than without ASLR. The second LoadLibraryEx call will return the same handle as the first call and the usage count of the DLL is incremented.
So the DLL isn't loaded "twice". Is is loaded on the first call.
Except the different use of the search path the behavior is identical to LoadLibrary.
From MSDN,
Section: Remarks [3rd Para]
If the specified module is a DLL that is not already loaded for
the calling process, the system calls the DLL's DllMain function with
the DLL_PROCESS_ATTACH value.
[11th Para]
The system maintains a per-process reference count on all loaded
modules. Calling LoadLibrary increments the reference count. Calling
the FreeLibrary or FreeLibraryAndExitThread function decrements the
reference count. The system unloads a module when its reference count
reaches zero or when the process terminates (regardless of the
reference count).
If the module is already loaded in the process memory, it will just return you back the same HMODULE handle with incremented reference count. Also, it will not call the DLL_PROCESS_ATTACH in subsequent calls.

Do I Need to close the handle if I don't store the return value of GetModuleHandle?

I was wondering if I had to close the handle if for example I were to call GetModuleHandle this way
GetProcAddress(GetModuleHandle("modulename"), "nameoftheexportedfunction")
what would be the proper way to close the handle? Do I need to do
HMODULE hModule = GetModuleHandle("modulename");
GetProcAddress(hModule, "nameoftheexportedfunction")
CloseHandle(hModule);
Or does it get deleted automatically if the value returned by GetModuleHandle isn't stored into a variable?
GetModuleHandle returns an HMODULE (aka HINSTANCE - see What is the difference between HINSTANCE and HMODULE?). This data type cannot be passed to CloseHandle.
The HMODULE could be passed to FreeLibrary but that is not required either, since GetModuleHandle doesn't increase the reference count on the module. In fact, calling FreeLibrary might cause the module to get unmapped prematurely, leading to a spectacular crash.
In short: GetModuleHandle returns a read-only value, that doesn't need to be disposed off in any way. The first line of code in your question is fine.
The Windows API can be very confusing in this respect, as there are multiple things called a handle, and they all have different rules.
In this case, CloseHandle closes kernel handles, which typically refer to files or other kernel resources such as synchronization objects that are created with a name—which all are identified by being returned as a HANDLE.
GetModuleHandle returns an HMODULE—actually the base address of a loaded EXE or DLL—and, as it is not a HANDLE, does not need to be, and must not be, released with CloseHandle.
As #David Heffernan points out, this does not mean other handle types never have their own destroy/release/un-acquire semantics, and it also does not mean that every HANDLE you get from an API must be passed to CloseHandle either. There is just no substitute for knowing the specific API you are dealing with and its particular handle management requirements.

WINAPI: GetModuleHandle and increment refcount

How can I increment refcount of the HMODULE returned by the GetModuleHandle? Can I DuplicateHandle, or I need to go through hops, retrieve module's path and then LoarLibrary on that path? In short, I want to emulate GetModuleHandleEx without using this function (which is XP+).
You cannot use DuplicateHandle() on a HMODULE. The MSDN Library article lists the kind of handles that DH will accept in the Remarks section, a module handle is not one of them.
One reason for this is that a HMODULE is not actually a handle at all, it is a pseudo handle. There's history behind this, back in the 16-bit versions of Windows they actually were handles. But that disappeared in the 32-bit version, they are now simply the address of the module where it is loaded in memory. One pretty standard trick to convert a code address to a module handle is to use VirtualQuery() and cast the returned MEMORY_BASIC_INFORMATION.BaseAddress to (HMODULE). Very handy sometimes.
Yes, the only other way to increment the reference count is to use LoadLibrary().

How to find out caller info?

This will require some background. I am using Detours to intercept system calls. For those of who don't know what Detours is - it is a tool which redirects call to system functions to a detour function which allows us to do whatever we want to do before and after the actual system call is made. What I want to know is that if it is possible to find out somehow any info about the dll/module which has made this system call? Does any win32 api function help me do this?
Lets say traceapi.dll makes a system call to GetModuleFileNameW() inside kernel32.dll. Detour will intercept this call and redirect control to a detour function (say Mine_GetModuleFileNameW()). Now inside Mine_GetModuleFileNameW(), is it possible to find out that this call originated from traceapi?
call ZwQuerySystemInformation with first argument SystemProcessesAndThreadsInformation.
once you have the returned buf, typecast it to PSYTSTEM+PROCESS_INFORMATION and use its field to extract your info.
status = ZwQuerySystemInformation (
SystemProcessesAndThreadsInformation, buf, bufsize, NULL);
PSYSTEM_PROCESS_INFORMATION proc_info = (PSYSTEM_PROCESS_INFORMATION) buf;
proc_info->ProcessName, which is a UNICODE_STRING will give you the calling process name.
Please note that the structure and field I am talking about is not documented and might change in future release of windows. However, I am using it and it works fine on WIN XP and above.
I don't know how many stack frames will be on the stack that are owned by Detours code. Easy to find out in the debugger, the odds are good that there are none. That makes it easy, use the _ReturnAddress intrinsic to get the caller's address. VirtualQuery() to get the base address, cast it to HMODULE and use GetModuleFileName(). Well, the non-detoured one :)
If there are Detours stack frames then it gets a lot harder. StackWalk64() to skip them, perilous if there are FPO frames present.

how come we need not close the handle returned by ShellExecute?

On success, ShellExecute returns a handle.
Do we need to close this handle, and if so, how ?
According to examples published my Microsoft, we need not close this handle. But the doc of ShellExecute itself is mute on the subject. Can you confirm we indeed do not need to close this handle ?
But then, how can a handle be valid and in no need of being closed ??? Which of the following statements is/are true:
the handle is invalid and we can't do anything with it;
the handle is never freed and there is a (Microsoft-sponsored) memory leak (until the caller program ends);
the handle is automatically freed by the system at some time and never reused afterwards (-> another kind of resource leak). Only on trying to use it can we know whether it still points to something.
what else ?
That hinstance is a 16 bit thing, in win32, it is just a number > 32 on success and can't be used for anything other than as an error code when the function fails. On the other hand, if you pass SEE_MASK_NOCLOSEPROCESS to the Ex version, you have a handle you need to close.
Taken from: http://msdn.microsoft.com/en-us/library/bb762153%28VS.85%29.aspx
If the function succeeds, it returns a
value greater than 32. If the function
fails, it returns an error value that
indicates the cause of the failure.
The return value is cast as an
HINSTANCE for backward compatibility
with 16-bit Windows applications. It
is not a true HINSTANCE, however. It
can be cast only to an int and
compared to either 32 or the following
error codes below.
I clear a little what is HINSTANCE and HMODULE. This are not a HANDLE, but much more as a memory address (pointer). You can understand this if you just cast a hInstance to (IMAGE_DOS_HEADER *) and look inside of the loaded module. You can use VirtualQueryEx (GetCurrentProcess(),...) to receive more information (a size for example) from a memory address.
Look at http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx and http://www.apriorit.com/our-experience/articles/9-sd-articles/74-hmodule-hinstance-handle-from-static-library-in-c and you will be see how you can receive a HINSTANCE from a memory address (__ImageBase).
So if you LoadLibrary for example you receive a HMODULE (it's the same as HINSTANCE). You should use FreeLibrary not to "close handle", but to unload module from memory. If you use GetModuleHandle for example, you receive also the same address (you receive address casted as HMODULE), but you should NOT call FreeLibrary to "close the handle".
If you understand what is HINSTANCE and HMODULE and how they should be used, you will be know how to use HINSTANCE returned from ShellExecute.

Resources