Defining Win98Me Stubs for Kernel-Mode Routines

Defining Win98/Me Stubs for Kernel-Mode Routines

The WDMSTUB sample in the companion content is a lower-filter driver that defines a number of kernel routines that Windows 98/Me omits. It relies on the same basic trick that Microsoft crafted to port several hundred kernel-mode support functions from Microsoft Windows NT to Windows 98/Me that is, extending the symbol tables that the run-time loader uses when it resolves import references. To extend the symbol tables, you first define three data tables that will persist in memory:

  • A name table that gives the names of the functions you re defining

  • An address table that gives the addresses of the functions

  • An ordinal table that correlates the name and address tables

Here are some of the table entries from WDMSTUB:

static char* names[] = {  "PoRegisterSystemState",   "ExSystemTimeToLocalTime",  }; static WORD ordinals[] = { 0, , 6,  }; static PFN addresses[] = { (PFN) PoRegisterSystemState,  (PFN) ExSystemTimeToLocalTime,  };

The purpose of the ordinal table is to provide the index within addresses of the entry for a given names entry. That is, the function named by names[i] is address[ordinals[i]].

If it weren t for a version compatibility problem I ll describe in a moment, you could call _PELDR_AddExportTable as follows:

HPEEXPORTTABLE hExportTable = 0; extern "C" BOOL OnDeviceInit(DWORD dwRefData) { _PELDR_AddExportTable(&hExportTable,  "ntoskrnl.exe", arraysize(addresses), // <== don't do it this way! arraysize(names), 0, (PVOID*) names, ordinals, addresses, NULL); return TRUE; }

The call to _PELDR_AddExportTable extends the table of symbols that the loader uses when it tries to resolve import references from NTOSKRNL.EXE, which is of course the Windows XP kernel. NTKERN.VXD, the main support module for WDM drivers in Windows 98/Me, initializes this table with the addresses of the several hundred functions it supports. In effect, then, WDMSTUB is an extension of NTKERN.

Version Compatibility

The version compatibility problem to which I just alluded is this: Windows 98 supported a particular subset of the Windows 2000 functions used by WDM drivers. Windows 98 Second Edition supported a larger subset. The last version of Windows, Windows Me, supports a still larger subset. You wouldn t want your stub driver to duplicate one of the functions that the operating system supports. What WDMSTUB actually does during initialization, therefore, is dynamically construct the tables that it passes to _PELDR_AddExportTable:

HPEEXPORTTABLE hExportTable = 0; extern "C" BOOL OnDeviceInit(DWORD dwRefData) { char** stubnames = (char**) _HeapAllocate(sizeof(names), HEAPZEROINIT); PFN* stubaddresses = (PFN*) _HeapAllocate(sizeof(addresses), HEAPZEROINIT); WORD* ordinals = (WORD*) _HeapAllocate(arraysize(names) * sizeof(WORD), HEAPZEROINIT); int i, istub; for (i = 0, istub = 0; i < arraysize(names); ++i) { if (_PELDR_GetProcAddress((HPEMODULE) "ntoskrnl.exe", names[i], NULL) == 0) { stubnames[istub] = names[i]; ordinals[istub] = istub; stubaddresses[istub] = addresses[i]; ++istub; } } _PELDR_AddExportTable(&hExportTable, "ntoskrnl.exe", istub, istub, 0, (PVOID*) stubnames, ordinals, stubaddresses, NULL); return TRUE; }

The line appearing in boldface is the crucial step here it makes sure that we don t inadvertently replace a function that already exists in NTKERN or another system VxD.

There s one annoying glitch in the version compatibility solution I just outlined. Windows 98 Second Edition and Windows Me export just three of the four support functions for managing the IO_REMOVE_LOCK object. The missing function is IoRemoveLockAndWaitEx, if you care. My WDMSTUB.SYS driver compensates for this omission by stubbing either all or none of the remove lock functions based on whether or not this function is missing.

Stub Functions

The main purpose of WDMSTUB.SYS is to resolve symbols that your driver might reference but not actually call. For some functions, such as PoRegister SystemState, WDMSTUB.SYS simply contains a stub that will return an error indication if it is ever called:

PVOID PoRegisterSystemState(PVOID hstate, ULONG flags) { ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); return NULL; }

Sometimes, though, you don t need to write a stub that fails the function call you can actually implement the function, as in this example:

VOID ExLocalTimeToSystemTime(PLARGE_INTEGER localtime, PLARGE_INTEGER systime) { systime->QuadPart = localtime->QuadPart + GetZoneBias(); }

where GetZoneBias is a helper routine that determines the time zone bias that is, the number of units by which local time differs from Greenwich mean time by interrogating the ActiveTimeBias value in the TimeZoneInformation registry key.

Table A-2 lists the kernel-mode support functions that WDMSTUB.SYS exports.

Table A-2. Functions Stubbed in WDMSTUB.SYS

Support Function

Remarks

ExFreePoolWithTag

Stubbed

ExLocalTimeToSystemTime

Implemented

ExSystemTimeToLocalTime

Implemented

HalTranslateBusAddress

Subset implemented

IoAcquireRemoveLockEx

Implemented

IoAllocateWorkItem

Implemented

IoCreateNotificationEvent

Stub always fails

IoCreateSynchronizationEvent

Stub always fails

IoFreeWorkItem

Implemented

IoInitializeRemoveLockEx

Implemented

IoQueueWorkItem

Implemented

IoRaiseInformationalHardError

Implemented

IoReleaseRemoveLockEx

Implemented

IoReleaseRemoveLockAndWaitEx

Implemented

IoReuseIrp

Implemented

IoReportTargetDeviceChangeAsynchronous

Stub always fails

IoSetCompletionRoutineEx

Implemented

KdDebuggerEnabled

Implemented

KeEnterCriticalRegion

Implemented

KeLeaveCriticalRegion

Implemented

KeNumberProcessors

Always returns 1

KeSetTargetProcessorDpc

Implemented

PoCancelDeviceNotify

Stub always fails

PoRegisterDeviceNotify

Stub always fails

PoRegisterSystemState

Stub always fails

PoSetSystemState

Stub always fails

PoUnregisterSystemState

Stub always fails

PsGetVersion

Implemented

RtlInt64ToUnicodeString

Stub always fails

RtlUlongByteSwap

Implemented

RtlUlonglongByteSwap

Implemented

RtlUshortByteSwap

Implemented

SeSinglePrivilegeCheck

Always returns TRUE

ExIsProcessorFeaturePresent

Implemented

MmGetSystemRoutineAddress

Implemented

ZwLoadDriver

Implemented

ZwQueryDefaultLocale

Implemented

ZwQueryInformationFile

Implemented

ZwSetInformationFile

Implemented

ZwUnloadDriver

Implemented

Using WDMSTUB

To use WDMSTUB, include WDMSTUB.SYS in your driver package and specify it as a lower filter for your function driver. Here s an example from the INF file for one of the sample drivers in the companion content:

[DriverInstall] AddReg=DriverAddReg CopyFiles=DriverCopyFiles,StubCopyFiles [StubCopyFiles] wdmstub.sys,,,2 [DriverAddReg] HKR,,DevLoader,,*ntkern HKR,,NTMPDriver,,"wdmstub.sys,workitem.sys"

The indicated syntax for the NTMPDriver value in the driver key causes the system to load WDMSTUB.SYS before attempting to load the function driver WORKITEM.SYS. By the time the system gets around to loading WORK ITEM.SYS, the DriverEntry routine in WDMSTUB has already executed and defined the functions listed in Table A-2.

Note that using WDMSTUB as a lower-filter driver means that the install package won t require a reboot.

Interaction Between WDMSTUB and WDMCHECK

WDMCHECK will tell you when certain symbols are defined only because you happen to have WDMSTUB loaded. See Figure A-4 for an example.

figure a-4 wdmcheck results involving wdmstub.

Figure A-4. WDMCHECK results involving WDMSTUB.

Special Licensing Note

WDMSTUB.SYS is an exception to the licensing requirements for the samples in the companion content. To avoid problems on end user machines caused by inconsistent versions of WDMSTUB, I ask that you not redistribute WDMSTUB.SYS except under license from me. I will grant a royalty-free license to distribute WDMSTUB to anyone who asks. Just send an e-mail to walt oney@oneysoft.com, explain that you want to redistribute WDMSTUB, and provide contact details so I can fax a license agreement to you.



Programming the Microsoft Windows Driver Model
Programming the Microsoft Windows Driver Model
ISBN: 0735618038
EAN: 2147483647
Year: 2003
Pages: 119
Authors: Walter Oney

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net