Run-Time Dynamic Linking
As you know, Windows systems rely extensively on dynamic linking to connect applications and drivers to system libraries. In both kernel mode and user mode, if an executable module references a library or an entry point that doesn t exist, the system will refuse to load the module. If you ve done extensive application programming for Windows platforms, you may be familiar with the Win32 API function GetProcAddress, which allows you to obtain a pointer to an exported function at run time. Programmers commonly use GetProcAddress to resolve symbol imports dynamically in a way that doesn t preclude the application from being loaded.
In Windows 2000 and later systems, you can call MmGetSystemRoutine Address to locate an entry point in the kernel or in the hardware abstraction layer (HAL). In effect, this function is a kernel-mode version of GetProcAddress. For example (see the SPINLOCK sample from Chapter 4):
typedef VOID (FASTCALL *KEACQUIREINSTACKQUEUEDSPINLOCK) (PKSPIN_LOCK, PKLOCK_QUEUE_HANDLE); KEACQUIREINSTACKQUEUEDSPINLOCK pKeAcquireInStackQueuedSpinLock; UNICODE_STRING us; RtlInitUnicodeString(&us, L"KeAcquireInStackQueuedSpinLock"); pKeAcquireInStackQueuedSpinLock = (KEACQUIREINSTACKQUEUEDSPINLOCK) MmGetSystemRoutineAddress(&us);
To use MmGetSystemRoutineAddress effectively, note the following fine points:
The function only searches NTOSKRNL.EXE (the kernel) and HAL.DLL (the hardware abstraction layer) for the symbol you specify. You can t use this function to dynamically resolve entry points into other drivers or system components.
Windows 98/Me doesn t support the function (but read on to learn about WDMSTUB, which does support it).
You need to use the same name that the kernel uses for a given symbol. You may need to consult WDM.H or NTDDK.H to follow a chain of macro definitions.