132 lines
4.8 KiB
Plaintext
132 lines
4.8 KiB
Plaintext
|
This file describes the internals of ul\drv\nt4hack.h that enable building
|
||
|
UL for NT5 and NT4.
|
||
|
|
||
|
|
||
|
1. The symbol TARGET_NT4 is defined when building for NT4; it is not
|
||
|
defined when building for NT5.
|
||
|
|
||
|
|
||
|
2. A portion of the NT4 build environment must be used to build NT4-
|
||
|
compatible drivers. This is necessary because:
|
||
|
|
||
|
a. _except_handler3 is part of the kernel-mode exception
|
||
|
handling/dispatching mechanism.
|
||
|
|
||
|
b. All kernel-mode drivers link to ntoskrnl.lib. This is a
|
||
|
hybrid link-library containing mostly import definitions
|
||
|
for those routines exported by ntoskrnl.exe. This library
|
||
|
also contains the actual implementations of a few routines.
|
||
|
|
||
|
c. The NT4 version of ntoskrnl.lib contains the actual
|
||
|
_except_handler3 implemenation. As a result, each NT4 driver
|
||
|
contains a copy of this _except_handler3 implementation.
|
||
|
|
||
|
d. The NT5 version of ntoskrnl.lib contains an import
|
||
|
definition for _except_handler3. As a result, each NT5
|
||
|
driver imports _except_handler3 from the kernel.
|
||
|
|
||
|
e. Since NT5 drivers import _except_handler3 from the kernel,
|
||
|
and _except_handler3 is not exported from the NT4 kernel,
|
||
|
then NT5 drivers will not load under NT4.
|
||
|
|
||
|
|
||
|
3. When the build target is NT4, nt4hack.h manually #includes basetsd.h.
|
||
|
This file is #included by ntdef.h in the NT5 build environment, but
|
||
|
does not exist in the NT4 build environment. #including this file
|
||
|
enables UL to use the pointer-size-neutral types (such as SIZE_T
|
||
|
and ULONG_PTR), even on NT4 builds.
|
||
|
|
||
|
|
||
|
4. nt4hack.h defines a few macros & constants newly introduced in the
|
||
|
NT5 build environment. These include C_ASSERT, EXTERN_C, and
|
||
|
ANSI_NULL.
|
||
|
|
||
|
|
||
|
5. The function prototypes for ExInterlockedCompareExchange64() and
|
||
|
InterlockedCompareExchange() differ between the NT4 and NT5 build
|
||
|
environments. For NT4 they are defined as:
|
||
|
|
||
|
NTKERNELAPI
|
||
|
ULONGLONG
|
||
|
FASTCALL
|
||
|
ExInterlockedCompareExchange64(
|
||
|
IN PULONGLONG Destination,
|
||
|
IN PULONGLONG Exchange,
|
||
|
IN PULONGLONG Comperand,
|
||
|
IN PKSPIN_LOCK Lock
|
||
|
);
|
||
|
|
||
|
PVOID
|
||
|
FASTCALL
|
||
|
InterlockedCompareExchange(
|
||
|
IN OUT PVOID *Destination,
|
||
|
IN PVOID ExChange,
|
||
|
IN PVOID Comperand
|
||
|
);
|
||
|
|
||
|
Under NT5 they are defined as:
|
||
|
|
||
|
NTKERNELAPI
|
||
|
LONGLONG
|
||
|
FASTCALL
|
||
|
ExInterlockedCompareExchange64(
|
||
|
IN PLONGLONG Destination,
|
||
|
IN PLONGLONG Exchange,
|
||
|
IN PLONGLONG Comperand,
|
||
|
IN PKSPIN_LOCK Lock
|
||
|
);
|
||
|
|
||
|
NTKERNELAPI
|
||
|
LONG
|
||
|
FASTCALL
|
||
|
InterlockedCompareExchange(
|
||
|
IN OUT PLONG Destination,
|
||
|
IN LONG ExChange,
|
||
|
IN LONG Comperand
|
||
|
);
|
||
|
|
||
|
nt4hack.h #defines UlInterlockedCompareExchange64() and
|
||
|
UlInterlockedCompareExchange() with a few key type casts to ensure
|
||
|
commonality between platforms.
|
||
|
|
||
|
|
||
|
6. NT5 introduced the OBJ_KERNEL_HANDLE flag. This flag may be set in
|
||
|
the Attributes field of the OBJECT_ATTRIBUTES structure used as a
|
||
|
parameter for many NT APIs that create named objects. When an
|
||
|
object is opened or created with this flag set, the object is created
|
||
|
or opened using the security context of the calling thread, but the
|
||
|
resulting handle is only valid in the system process. Since the handle
|
||
|
is only valid in the system process, it is impossible for a user-mode
|
||
|
process to close, duplicate, or otherwise manipulate the handle or
|
||
|
the underlying object.
|
||
|
|
||
|
This is a Good Thing. Unfortunately, NT4 does not support this flag.
|
||
|
|
||
|
Fortunately, NT4 supports the KeAttachProcess() and KeDetachProcess()
|
||
|
APIs. KeAttachProcess() allows a thread in one process to attach to
|
||
|
the address space & handle table of another process. Any handles
|
||
|
created while attached to another process are only valid in the
|
||
|
context of the attached process.
|
||
|
|
||
|
nt4hack.h hides these differences by defining:
|
||
|
|
||
|
UL_KERNEL_HANDLE
|
||
|
UlAttachToSystemProcess()
|
||
|
UlDetachFromSystemProcess()
|
||
|
UlCloseSystemHandle()
|
||
|
|
||
|
Under NT4, UL_KERNEL_HANDLE is 0; under NT5 it is OBJ_KERNEL_HANDLE.
|
||
|
UL sets this flag whenever initializing an OBJECT_ATTRIBUTES structure.
|
||
|
|
||
|
Under NT4, UlAttachToSystemProcess() calls KeAttachProcess() to attach
|
||
|
to the system process; under NT5 it is a no-op.
|
||
|
|
||
|
Under NT4, UlDetachFromSystemProcess() calls KeDetachProcess(); under
|
||
|
NT5 it is a no-op.
|
||
|
|
||
|
UlCloseSystemHandle() calls UlAttachToSystemProcess(), ZwClose() to
|
||
|
close the specified handle, then UlDetachFromSystemProcess(). So,
|
||
|
under NT5, UlCloseSystemHandle() is basically a #define to ZwClose().
|
||
|
Under NT4, it must attach before the close and detach afterwards.
|
||
|
|