📄 callkerneldll.cpp
字号:
//****************************************************************************//
//* //
//* Copyright (C) 2003, James Antognini, antognini@mindspring.com. //
//* //
//****************************************************************************//
/**************************************************************************************************/
/* */
/* This boiler-plate driver shows the invocation of a routine in a kernel DLL (see */
/* CallKernelDLLDispatchAny). */
/* */
/* Because of the way this driver will have been linked (eg, employing KernelDLLRtns.lib), the OS */
/* will automagically load the kernel DLL immediately before this driver is loaded (and if the */
/* DLL cannot be loaded, eg, cannot be found), this driver will not be loaded. */
/* */
/**************************************************************************************************/
#define JADrvNm "CallKernelDLL"
#define JADrvNmW L"CallKernelDLL"
#define JADrvVer "1.00"
#ifdef __cplusplus // C++ conversion.
extern "C"
{
#endif // End #ifdef C++ conversion.
#include <ntddk.h>
#define JADriverKernelMode 1 // Ensure kernel pieces available.
#include "KernelDLL.h"
#ifdef __cplusplus // C++ conversion.
}
#endif // End #ifdef C++ conversion.
//****************************************************************************//
//* //
//* Globals. //
//* //
//****************************************************************************//
#define CompDateTimeStr "dd mmm yyyy hh:mm:ss"
char DrvCompileInfo[sizeof(CompDateTimeStr)+1];
PDEVICE_OBJECT pPermDevObj = NULL,
pKernelDLLDevObj = NULL;
PDRIVER_OBJECT pKernelDLLDrvObj = NULL;
//***************************************************************************//
// //
// Routine prototypes (forward definitions). //
// //
//***************************************************************************//
VOID
CallKernelDLLUnload(IN PDRIVER_OBJECT);
NTSTATUS
CallKernelDLLDispatchAny(PDEVICE_OBJECT, PIRP);
/**************************************************************************************************/
/* */
/* DriverEntry. */
/* */
/**************************************************************************************************/
extern "C"
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING DeviceNameUniString,
DeviceLinkUniString,
DriverName,
WkUniStr;
PDEVICE_OBJECT pDevObj = NULL;
pKernelDLLExt pDevExt;
ULONG i;
BOOLEAN bHaveSymLink = FALSE,
bHaveRegPath = FALSE;
WCHAR static backslash = L'\\', // Delimiter in Unicode.
constDeviceName[] = L"\\Device\\",
constDeviceLink[] = L"\\DosDevices\\";
PWSTR pIdx;
ANSI_STRING LclDrvName;
char static DateCompiledBase[] = __DATE__,
TimeCompiledBase[] = " "__TIME__;
char DateCompiled[] = // Build date in preferred (dd mmm yyyy) format.
{DateCompiledBase[4], DateCompiledBase[5], DateCompiledBase[6],
DateCompiledBase[0], DateCompiledBase[1], DateCompiledBase[2], DateCompiledBase[3],
DateCompiledBase[7], DateCompiledBase[8], DateCompiledBase[9], DateCompiledBase[10],
0x0
};
if (' '==DateCompiled[0]) // Leading blank (eg, in ' 1 Apr 2003')?
strcpy(DrvCompileInfo, DateCompiled+1);
else
strcpy(DrvCompileInfo, DateCompiled+0);
strcat(DrvCompileInfo, TimeCompiledBase);
DbgPrint((JADrvNm " v" JADrvVer " (compiled %s)\n", DrvCompileInfo));
// Invoke an attached debugger. If there's none, continue.
_try // Per Mark Roddy, comp.os.ms-windows.programmer.nt.kernel-mode, 27 Apr 2001.
{
DbgBreakPoint();
}
_except(EXCEPTION_EXECUTE_HANDLER)
{
}
DeviceNameUniString.Buffer = NULL; // Ensure safe exit by branch to label 'done'.
DeviceLinkUniString.Buffer = NULL; // "
LclDrvName.Buffer = NULL; // "
if (!NT_SUCCESS(status)) goto done;
// Find the driver name in the registry path information. The following assumes the string to be searched ends with a
// backslash followed by 1 or more WCHARs that are the Unicode name.
for ( // Find last delimiter by working back from end.
pIdx = // Point to last WCHAR in buffer.
pRegistryPath->Buffer + (pRegistryPath->Length / sizeof(WCHAR)) - 1;
;
pIdx-- // Decrement by WCHAR width.
)
if (backslash==*pIdx) // Is current WCHAR a delimiter?
break;
// Build Unicode descriptor of driver name.
pIdx++; // Point to just after backslash.
DriverName.Length = pRegistryPath->Length - // Calculate length.
((pIdx - pRegistryPath->Buffer) * sizeof(WCHAR));
DriverName.MaximumLength = DriverName.Length + // Figure in length of terminator.
sizeof(WCHAR);
DriverName.Buffer = pIdx; // Point to driver name.
status = RtlUnicodeStringToAnsiString( // Get driver name in ansi.
&LclDrvName, // Descriptor.
&DriverName, // Unicode string to convert.
TRUE // Allocate space (which must be freed later).
);
if (!NT_SUCCESS(status)) // A problem?
{
DbgPrint((JADrvNm " DriverEntry: Failed to convert driver name!\n"));
goto done;
}
DeviceNameUniString.Length = 0; // Show current length of device name.
DeviceNameUniString.MaximumLength = // Show maximum length of device name.
sizeof(constDeviceName) -
sizeof(WCHAR) + // Don't need size of first terminator (that is, terminator of constDeviceName).
DriverName.MaximumLength;
DeviceNameUniString.Buffer = // Get space for device name and for ASCII driver name.
(PWSTR)ExAllocatePoolWithTag(
PagedPool,
DeviceNameUniString.MaximumLength,
'xxJA'
);
if (NULL==DeviceNameUniString.Buffer) // Failed to get storage?
{
DbgPrint(("%s DriverEntry: Failed to get storage for device name!\n", LclDrvName.Buffer));
goto done;
}
// Now build proper device name, eg, '\Device\Driver'.
RtlAppendUnicodeToString( // Initialize by appending L"\\Device\\" to empty string.
&DeviceNameUniString,
constDeviceName
);
RtlAppendUnicodeStringToString( // Append driver name.
&DeviceNameUniString,
&DriverName
);
// Set up the device.
status = IoCreateDevice(
pDriverObject,
sizeof(KernelDLLExt),
&DeviceNameUniString,
FILE_DEVICE_UNKNOWN, // Per Walt Oney, p 403.
0,
FALSE, // Not exclusive.
&pDevObj
);
if (FALSE==NT_SUCCESS(status)) // A problem?
{
DbgPrint(("%s DriverEntry: Failed to create the device, rc = 0x%08X!\n", LclDrvName.Buffer, status));
goto done;
}
pPermDevObj = pDevObj; // Save device address in module's global storage.
// Extension will have been zeroed by OS.
pDevExt = (pKernelDLLExt)pDevObj->DeviceExtension;
pDevExt->JAUniDeviceName.Length = // Save length of Unicode driver name.
DeviceNameUniString.Length;
pDevExt->JAUniDeviceName.MaximumLength = // Save maximum length of Unicode driver name.
DeviceNameUniString.MaximumLength;
pDevExt->JAUniDeviceName.Buffer = // Save address of Unicode driver name.
DeviceNameUniString.Buffer;
memcpy(&pDevExt->JADriverName, // Copy ANSI-string descriptor.
&LclDrvName,
sizeof(pDevExt->JADriverName)
);
// Create a symbolic link to gain access to this driver/device, eg, '\DosDevices\Driver'.
DeviceLinkUniString.Buffer = // Get space for symbolic link name.
(PWSTR)ExAllocatePoolWithTag(
PagedPool,
sizeof(constDeviceLink) +
DriverName.Length,
'xxJA'
);
if (NULL==DeviceLinkUniString.Buffer) // Failed to get storage?
{
DbgPrint(("%s DriverEntry: Failed to get storage for device link!\n", LclDrvName.Buffer));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -