A GetModuleHandle implementation - winapi

I need to do it this way because I am in DllMain() therefore, loader lock is held. I've read that GetModuleHandle() also uses the loader lock [page #6] which would result in deadlock.
How could GetModuleHandle() implemented? Some code would be a plus.
Update: Since I am using SetWindowsHookEx on WinXP only. Just going to take advice in the comments, go the easy way, and use GetModuleHandle() the first time the callback gets called.

You can call GetModuleHandle from DllMain. It doesn't load any libraries and doesn't increment module reference count. Other story is with LoadLibrary. Never call it from DllMain.

Related

Safe place to put unsafe DLL cleanup code on Windows?

We hit a case where it would be the best solution for us to put a FreeLibrary call into DllMain / DLL_PROCESS_DETACH.
Of course, you must not do that:
It is not safe to call FreeLibrary from DllMain.
The use case is that we have a situation like this:
(unknown client dll or exe) links dynamically or statically to ->
-> DLL_1, loads dynamically -> DLL_x
DLL_1 should load DLL_x transparently wrt. to it's client code, and it should to load DLL_x dynamically. Now, the loading can be done lazily, so that the LoadLibrary call needn't reside in the DLL_PROCESS_ATTACH part of DLL_1.
But once the client is done with DLL_1, when/before DLL_1 is unloaded from the process, it should also unload (== FreeLibrary) DLL_x.
Is there any way to do this without an explicit DLL_1/Uninitialize function that must be called by the client?
I'll note:
DllMain, and thus also any C++ global static destructor cannot be used.
Is there any other callback mechanism in either kernel32/ntdll or maybe in the shared MS CRT to make this happen?
Are there other patterns to make this usecase work?
The correct approach is an explicit Uninitialize function in DLL_1.
However, if you can't do that, you can work around the problem by launching a helper thread to do the unload for you. If you want to play it safe, launch the thread at the same time you load DLL_x and have it wait on an event object. (For the record, though, it is generally considered safe to launch a thread from DllMain so long as you respect the fact that it won't start up until DllMain has exited.)
Obviously, the helper thread's code can't be in DLL_1. If you can modify DLL_x you can put it there. If not, you'll need a helper DLL. In either case, the DLL containing the helper thread's code can safely self-unload using the FreeLibraryAndExitThread function.

BUG: Scheduling while atomic .... using sysfs_notify()

I have a kernel module that uses hrtimers to notify userspace when the timer has fired. I understand I can just use userspace timers, but it is emulating a driver that will actually talk to hardware in the future. Every once in a while I get a BUG: Scheduling while atomic. After doing some research I am assuming that the hrtimer.function that I register as a callback, is being called from an interrupt routine by the kernel internals (making my callback function in an "Atomic Context"). Then when I call sysfs_notify() within the callback, I get the kernel bug, because sysfs_notify() acquires a mutex.
1) Is this a correct assumption?
If this is correct, I have seen that there is a function called sys_notify_dirent() that I can use to notify userspace from an atomic context. But according to this source:
http://linux.derkeiler.com/Mailing-Lists/Kernel/2009-10/msg07510.html
It can only be called from a "process" context, and not an interrupt context (due to the spinlock).
2) Could someone explain the difference between process, interrupt, and atomic context?
3) If this cannot be used in an interrupt context, what is an alternative to notifying userspace in this context?
Correct, sysfs_notify() cannot be called from atomic context. And yes, sysfs_notify_dirent() appears to be safe to call from atomic context. The source you cite is a bug report that notices in an old kernel version that statement wasn't actually true, along with a patch to fix it. It now appears to be safe to call.
Follow the source code in gpiolib_sysfs.c, and you'll notice that sysfs_notify_dirent() eventually calls schedule_work(), which defers the actual call to sysfs_notify(), which is exactly what the comments to your question are advising you to do. It's just wrapped inside the convenience function.

Loading/calling ntdll from DllMain

One should not use functions other than those in kernel32.dll from DllMain:
From MS documentation:
Because Kernel32.dll is guaranteed to be loaded in the process address space when the entry-point function is called, calling functions in Kernel32.dll does not result in the DLL being used before its initialization code has been executed. Therefore, the entry-point function can call functions in Kernel32.dll that do not load other DLLs. For example, DllMain can create synchronization objects such as critical sections and mutexes, and use TLS. Unfortunately, there is not a comprehensive list of safe functions in Kernel32.dll.
...
Calling functions that require DLLs other than Kernel32.dll may result in problems that are difficult to diagnose. For example, calling User, Shell, and COM functions can cause access violation errors, because some functions load other system components. Conversely, calling functions such as these during termination can cause access violation errors because the corresponding component may already have been unloaded or uninitialized.
My question:
But the documentation does not mention ntdll.dll. - Can I call LoadLibrary for "ntdll" and use functions in ntdll from DllMain:
1) during DLL_PROCESS_ATTACH (load and use functions of ntdll)?
2) during DLL_PROCESS_DETACH (use functions of previously loaded ntdll)?
Also, please, would somebody with 1500+ reputation like to create a new tag titled "dllmain" ?
The answer to the question "is it safe in DllMain" always defaults to "no". In this case, calling LoadLibrary is never okay.
Generally speaking, calling anything in ntdll.dll is not recommended even places where it is safe to do so.

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().

An impasse with hooking calls to HeapAlloc for a memory tracking application

I am writing a memory tracking application that hooks all the calls to HeapAlloc using IAT patching mechanism. The idea is to capture all the calls to HeapAlloc and get a callstack.
However I am currently facing a problem with getting the callstack using DBGHELP Apis. I found that the dbghelp dll itself is linking to MSVCRT dll and this dependancy results in a recursive call. When I try to get a callstack for any of the calls from the target application, dbghelp internally calls some method from MSVCRT that again calls HeapAlloc. And since I have already patched MSVCRT it results in an infinite loop.
Has anyone faced this problem and solved it ? Is there any way out of this impasse?
This is a standard problem in function interception code. We had a similar issue with a logging library that used shared memory for storing log level information, while the shared memory library had to log information.
The way we fixed it could be applied to your situation, I believe.
In your intercept code, maintain a static flag that indicates whether or not you're in the middle of an intercept. When your intercept is called and the flag isn't set, set the flag then do what you currently do, including calling DbgHelp, then clear the flag.
If your intercept is called while the flag is set, only call the back-end HeapAlloc code without doing any of the other stuff (including calling DbgHelp which is what's causing your infinite recursion).
Something along the lines of (pseudo-code):
function MyHookCode:
static flag inInterceptMode = false
if inInterceptMode:
call HeapAlloc
return
inInterceptMode = true
call DbgHelp stuff
call HeapAlloc
inInterceptMode = false
return
function main:
hook HeapAlloc with MyHookCode
: : :
return
What about using some real memory tracking products like GlowCode?
You can use Deviare API Hook and get full stack-trace without using that API that has a big number of problems.

Resources