在DriverEntry中FindOriAddress(3)得到文件基址中的SSDT索引号为3的函数地址
调试结果如下:
通过脚本查看到的SSDT的信息如下图:
脚本来源于:http://bbs.pediy.com/showthread.php?t=34018
$$ ntcall Script v0.1
$$ by 小喂 2006.10.29
$$ $$><d:\ntcall.txt
aS ufLinkS "<u><col fg=\\\"emphfg\\\"><link name=\\\"%x\\\" cmd=\\\"uf 0x%x\\\">";
aS ufLinkE "</link></col></u>";
r $t1 = nt!KeServiceDescriptorTable;
r $t2 = poi(@$t1 + 8);
r $t1 = poi(@$t1);
.printf "\nOrd Address fnAddr Symbols\n";
.printf "--------------------------------\n\n";
.for (r $t0 = 0; @$t0 != @$t2; r $t0 = @$t0 + 1)
{
r $t3 = poi(@$t1);
.printf /D "[%3d] %X: ${ufLinkS}%X${ufLinkE} (%y)\n", @$t0, @$t1, @$t3, @$t3, @$t3, @$t3;
r $t1 = @$t1 + 4;
}
.printf "\n- end -\n";
ad ufLinkS;
ad ufLinkE;
Driver.cpp内容:
#include "Driver.h"
//#include <windows.h>
#include "ntimage.h"
//#include "ntos.h"
//#include "wdbgexts.h"
//#include "ntdbg.h"
//#include <zwapi.h>
#include <string.h>
/************************************************************************
* 函数名称:GetServiceId
* 功能描述:取得ntoskrnl.exe SSDT导出函数服务号,(只能取得导出函数)
* 参数列表:
FunctionName:函数名
* 返回值:返回导出服务号
*************************************************************************/
ULONG GetServiceId(PCWSTR FunctionName)
{
UNICODE_STRING UnicodeFunctionName;
ULONG address;
ULONG ServiceId;
RtlInitUnicodeString(&UnicodeFunctionName, FunctionName);
address = (ULONG)MmGetSystemRoutineAddress(&UnicodeFunctionName);
//打印函数地址
KdPrint(("[GetServiceId] address:0x%x\n", address));
//打印服务号
ServiceId = *(PSHORT)(address+1);
KdPrint(("[GetServiceId] ServiceId:0x%x\n", ServiceId));
return ServiceId;
}
/************************************************************************
* 函数名称:RVA2PTR
* 功能描述:根据内存基址,得到RVA对应的文件偏移地址
* 参数列表:ULONG ImageBase--文件内存基址
* ULONG Rva--要转换的RVA地址
* 返回值:ULONG 相应的文件偏移地址
*************************************************************************/
ULONG RVA2PTR(ULONG ImageBase, ULONG Rva)
{
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
PIMAGE_OPTIONAL_HEADER pOptHeader = NULL;
PIMAGE_SECTION_HEADER pSecHeader = NULL;
ULONG dwNumOfSections = 0;
ULONG i = 0;
ULONG dwFileOffset = 0;
pDosHeader = (PIMAGE_DOS_HEADER)ImageBase;
pNtHeader = (PIMAGE_NT_HEADERS)((ULONG)ImageBase + pDosHeader->e_lfanew);
pOptHeader = (PIMAGE_OPTIONAL_HEADER)&pNtHeader->OptionalHeader;
dwNumOfSections = pNtHeader->FileHeader.NumberOfSections;
pSecHeader = (PIMAGE_SECTION_HEADER)((ULONG)pOptHeader + pNtHeader->FileHeader.SizeOfOptionalHeader);
for (i = 0; i < dwNumOfSections; i++)
{
ULONG dwMinAddr = pSecHeader->VirtualAddress;
ULONG dwMaxAddr = dwMinAddr + pSecHeader->Misc.VirtualSize;
if (Rva >= dwMinAddr && Rva < dwMaxAddr)
{
dwFileOffset = Rva - dwMinAddr + pSecHeader->PointerToRawData;
break;
}
pSecHeader++;
}
return dwFileOffset;
}
/************************************************************************
* 函数名称:GetModuleName
* 功能描述:从输入的路径中得到程序名
* 参数列表:char *processPath 输入的路径名,如D:\peinfo.exe
char *processName 返回的进程名,如peinfo.exe
*
* 返回值:返回到参数中,processName
*************************************************************************/
void GetModuleName(char *processPath, char *processName)
{
ULONG nLen = strlen(processPath) - 1;
ULONG i = nLen;
KdPrint(("[GetModuleName] i = %d", nLen));
while (processPath[i] != '\\')
{
i = i - 1;
}
strncpy(processName, processPath+i+1, nLen - i );
}
/************************************************************************
* 函数名称:FindOriAddress
* 功能描述:根据SSDT索引号从原始文件中得到SSDT表中的函数地址,用于对比
文件中的SSDT与内存中的SSDT索引中的函数地址是否变化,检测是
否HOOK了SSDT中的函数
* 参数列表:ULONG index 索引号
*
* 返回值:文件中函数地址
*************************************************************************/
ULONG FindOriAddress(ULONG index)
{
ULONG size = 0;
NTSTATUS status;
ULONG baseAddress;
PSYSTEM_MODULE_INFORMATION list = NULL;
char szFileName[256] = {0};
char szKernelName[256] = "\\SystemRoot\\system32\\";
UNICODE_STRING unKernelName;
ANSI_STRING anKernelName;
ULONG rvaOfsstd = 0;
ULONG offsetOfsstd = 0;
LARGE_INTEGER locationOfServiceId;
OBJECT_ATTRIBUTES object_attributes;
IO_STATUS_BLOCK io_status = {0};
HANDLE hFile;
ULONG dwOriAddr;
ZwQuerySystemInformation(SystemModuleInformation, &size, 0, &size);
KdPrint(("[FindOriAddress]:size:0x%x\n", size));
list = (PSYSTEM_MODULE_INFORMATION)ExAllocatePool(NonPagedPool, size);
if (NULL == list)
{
KdPrint(("[FindOriAddress]:ExAllocatePool error\n"));
ExFreePool(list);
return -1;
}
status = ZwQuerySystemInformation(SystemModuleInformation, list, size, 0);
if (!NT_SUCCESS(status))
{
KdPrint(("[FindOriAddress]:ZwQuerySystemInformation error\n"));
ExFreePool(list);
return -1;
}
baseAddress = (ULONG)list->Module[0].Base;
KdPrint(("[FindOriAddress]:baseAddress=0x%x\n", baseAddress));
//分离出内核文件名
GetModuleName(list->Module[0].ImageName, szFileName);
KdPrint(("[FindOriAddress]:szFileName=%s\n", szFileName));
strcat(szKernelName, szFileName);
RtlInitAnsiString(&anKernelName, szKernelName);
RtlAnsiStringToUnicodeString(&unKernelName, &anKernelName, TRUE);
KdPrint(("[FindOriAddress]:unKernelName=%wZ\n", unKernelName));
ExFreePool(list);
//得到SSDT表的RVA
rvaOfsstd = (ULONG)KeServiceDescriptorTable.ServiceTableBase - baseAddress;
offsetOfsstd = (ULONG)RVA2PTR(baseAddress, rvaOfsstd);
//得到SSDT表的FileOffset
offsetOfsstd = RVA2PTR(baseAddress, rvaOfsstd);
KdPrint(("[FindOriAddress]:offsetOfsstd=0x%x\n", offsetOfsstd));
locationOfServiceId.QuadPart = offsetOfsstd + index * 4;
KdPrint(("[FindOriAddress]:locationOfServiceId=0x%x\n", locationOfServiceId));
KdPrint(("[FindOriAddress]:当前ssdt对应的地址=0x%x\n", locationOfServiceId));
InitializeObjectAttributes(&object_attributes, &unKernelName, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL);
//打开文件
status = ZwCreateFile(
&hFile,
FILE_EXECUTE| SYNCHRONIZE,
&object_attributes,
&io_status,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT|FILE_RANDOM_ACCESS,
NULL,
0);
if (!NT_SUCCESS(status))
{
KdPrint(("[FindOriAddress] error ZwCreateFile\n"));
KdPrint(("[FindOriAddress] ntstatus = 0x%x\n", status));
return 0;
}
//读取文件
status = ZwReadFile(hFile, NULL, NULL, NULL, NULL, &dwOriAddr, sizeof(ULONG), &locationOfServiceId, NULL);
if (!NT_SUCCESS(status))
{
KdPrint(("[FindOriAddress] error ZwReadFile\n"));
KdPrint(("[FindOriAddress] ntstatus = 0x%x\n", status));
return 0;
}
//重定位
dwOriAddr = baseAddress - 0x400000 + dwOriAddr;
KdPrint(("[FindOriAddress] dwOriAddr = 0x%x\n", dwOriAddr));
RtlFreeUnicodeString(&unKernelName);
return dwOriAddr;
}
/************************************************************************
* 函数名称:FindModuleByAddress
* 功能描述:根据输入的内核地址,返回该地址所在的模块路径
* 参数列表:ULONG Address---要查询的内核地址
* PVOID name_buffer---接收返回的模块路径
* 返回值:无,返回模块路径到参数name_buffer中
*************************************************************************/
void FindModuleByAddress(ULONG Address, PVOID name_buffer)
{
ULONG size = 0;
PSYSTEM_MODULE_INFORMATION list;
NTSTATUS status;
ULONG i = 0;
ULONG minAddress = 0;
ULONG maxAddress = 0;
ZwQuerySystemInformation(SystemModuleInformation, &size, 0, &size);
KdPrint(("[FindModuleByAddress]:size:0x%x\n", size));
list = (PSYSTEM_MODULE_INFORMATION)ExAllocatePool(NonPagedPool, size);
if (NULL == list)
{
KdPrint(("[FindModuleByAddress]:ExAllocatePool error\n"));
ExFreePool(list);
return ;
}
status = ZwQuerySystemInformation(SystemModuleInformation, list, size, 0);
if (!NT_SUCCESS(status))
{
KdPrint(("[FindModuleByAddress]:ZwQuerySystemInformation error\n"));
ExFreePool(list);
return ;
}
for (i = 0; i < list->Count; i++)
{
minAddress = (ULONG)list->Module[i].Base;
maxAddress = minAddress + list->Module[i].Size;
if (Address >= minAddress && Address <= maxAddress)
{
memcpy(name_buffer, list->Module[i].ImageName, sizeof(list->Module[i].ImageName));
KdPrint(("[FindModuleByAddress]:ModuleName:%s \n", name_buffer));
ExFreePool(list);
return ;
}
}
ExFreePool(list);
return;
}
/************************************************************************
* 函数名称:GetFunctionId
* 功能描述:解析ntdll.dll的IAT,得到ssdt函数的服务号
* 参数列表:PUNICODE_STRING DllName---Dll名称
* FunctionName---要查找的函数名称
* 返回值:返回导出服务号
*************************************************************************/
ULONG GetFunctionId(PUNICODE_STRING DllName, char* FunctionName)
{
ULONG ServiceId = 0;
NTSTATUS ntstatus;
HANDLE hFile = NULL;
HANDLE hSection = NULL;
OBJECT_ATTRIBUTES object_attributes;
IO_STATUS_BLOCK io_status = {0};
PVOID baseaddress = NULL;
SIZE_T size = 0;
ULONG virual_size = 0;
PVOID ModuleBase = NULL;
ULONG addr = 0;
//偏移量
ULONG dwOffset = 0;
PIMAGE_DOS_HEADER pDosHeader = NULL;
PIMAGE_NT_HEADERS pNTHeader = NULL;
IMAGE_DATA_DIRECTORY DataDirectory = {0};
PIMAGE_EXPORT_DIRECTORY pExportDirectory = NULL;
PULONG functions = NULL;
PUSHORT ordinals = NULL;
PULONG names = NULL;
ULONG iNumOfName = 0;
ULONG iNumOfFuncs = 0;
ULONG pFuncAddr = 0;
ULONG i = 0;
ULONG j = 0;
InitializeObjectAttributes(&object_attributes, DllName, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL);
//打开文件
ntstatus = ZwCreateFile(
&hFile,
FILE_EXECUTE| SYNCHRONIZE,
&object_attributes,
&io_status,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT|FILE_RANDOM_ACCESS,
NULL,
0);
if (!NT_SUCCESS(ntstatus))
{
KdPrint(("[GetFunctionAddress] error ZwCreateFile\n"));
KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
return 0;
}
InitializeObjectAttributes(&object_attributes, NULL, OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, NULL, NULL);
//创建区段
ntstatus = ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &object_attributes, 0, PAGE_EXECUTE, SEC_IMAGE, hFile);
if (!NT_SUCCESS(ntstatus))
{
KdPrint(("[GetFunctionAddress] error ZwCreateSection\n"));
KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
ZwClose(hFile);
return 0;
}
//映射区段到进程内存地址空间
ntstatus = ZwMapViewOfSection(hSection, NtCurrentProcess(), &baseaddress, 0, 1024, 0, &size, (SECTION_INHERIT)ViewShare , MEM_TOP_DOWN, PAGE_READWRITE);
if (!NT_SUCCESS(ntstatus))
{
KdPrint(("[GetFunctionAddress] error ZwMapViewOfSection\n"));
KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
ZwClose(hSection);
ZwClose(hFile);
return 0;
}
ZwClose(hFile);
//得到模块基址
dwOffset = (ULONG)baseaddress;
//验证基址
KdPrint(("[GetFunctionAddress] baseaddress = 0x%x\n", dwOffset));
//Dos头部
pDosHeader = (PIMAGE_DOS_HEADER)baseaddress;
//PE文件头
pNTHeader = (PIMAGE_NT_HEADERS)( (ULONG)baseaddress + pDosHeader->e_lfanew);
KdPrint(("[GetFunctionAddress] pNTHeader = 0x%x\n", pNTHeader));
//数据目录
DataDirectory = (IMAGE_DATA_DIRECTORY)(pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); // + IMAGE_DIRECTORY_ENTRY_EXPORT
KdPrint(("[GetFunctionAddress] DataDirectory = 0x%x\n", DataDirectory));
addr = DataDirectory.VirtualAddress;
virual_size = DataDirectory.Size;
//导出表
pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((ULONG)baseaddress + addr);
//导出表的三个数组指针
functions = (PULONG)( (ULONG)baseaddress + pExportDirectory->AddressOfFunctions );
ordinals = (PUSHORT)((ULONG)baseaddress + pExportDirectory->AddressOfNameOrdinals);
names = (PULONG)((ULONG)baseaddress + pExportDirectory->AddressOfNames);
iNumOfName = (ULONG)pExportDirectory->NumberOfNames;
iNumOfFuncs = (ULONG)pExportDirectory->NumberOfFunctions;
for( i=0; i < iNumOfFuncs; i++) //i<AddressOfFunctions 中个元素个数
{
if(*functions) //AddressOfFunctions VA != NULL
{
for( j = 0; j < iNumOfName; j++) // j < NumberOfNames
{
if(i==ordinals[j]) //pwOrds is a pointer to AddressOfNameOrdinals
{
PCHAR pCurFuncName=(PCHAR)baseaddress + names[j];
KdPrint(("[GetFunctionAddress] funcName:%s\n", pCurFuncName));
if (strcmp(pCurFuncName, FunctionName) == 0)
{
ULONG offsetfunction = *functions;
pFuncAddr = (ULONG)((ULONG)baseaddress + functions[0]);
ULONG pFuncAddr2 = (ULONG)((ULONG)baseaddress + offsetfunction);
KdPrint(("[GetFunctionAddress]:pFuncAddr:0x%x\n", pFuncAddr));
KdPrint(("[GetFunctionAddress]:pFuncAddr2:0x%x\n", pFuncAddr2));
break;
}
}
}
functions++;
}
break;
}
KdPrint(("[GetFunctionAddress]:%s:0x%x\n", FunctionName, pFuncAddr));
//ServiceId = *(PSHORT)(pFuncAddr+1);
ServiceId = 1;
KdPrint(("[GetFunctionAddress]:ServiceId:0x%x\n", ServiceId));
ZwUnmapViewOfSection(NtCurrentProcess(), baseaddress);
ZwClose(hSection);
return ServiceId;
}
/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath )
{
_asm int 3
NTSTATUS status;
KdPrint(("Enter DriverEntry\n"));
GetServiceId(L"ZwCreateFile");
KdPrint(("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"));
UNICODE_STRING dllName;
ULONG ZwCreateProcessEx_ServiceId;
RtlInitUnicodeString(&dllName, L"\\??\\c:\\windows\\system32\\ntdll.dll");
ZwCreateProcessEx_ServiceId = GetFunctionId(&dllName, "ZwCreateProcessEx");
KdPrint(("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n"));
KdPrint(("enter FindOriAddress\n"));
FindOriAddress(3);
KdPrint(("out FindOriAddress\n"));
//注册其他驱动调用函数入口
pDriverObject->DriverUnload = HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
//创建驱动设备对象
status = CreateDevice(pDriverObject);
KdPrint(("DriverEntry end\n"));
return status;
}
/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (
IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");
//创建设备
status = IoCreateDevice( pDriverObject,
sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,
FILE_DEVICE_UNKNOWN,
0, TRUE,
&pDevObj );
if (!NT_SUCCESS(status))
return status;
pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}
/************************************************************************
* 函数名称:HelloDDKUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("Enter DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
while (pNextObj != NULL)
{
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
pNextObj->DeviceExtension;
//删除符号链接
UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
IoDeleteSymbolicLink(&pLinkName);
pNextObj = pNextObj->NextDevice;
IoDeleteDevice( pDevExt->pDevice );
}
}
/************************************************************************
* 函数名称:HelloDDKDispatchRoutine
* 功能描述:对读IRP进行处理
* 参数列表:
pDevObj:功能设备对象
pIrp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
KdPrint(("Enter HelloDDKDispatchRoutine\n"));
NTSTATUS status = STATUS_SUCCESS;
// 完成IRP
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
KdPrint(("Leave HelloDDKDispatchRoutine\n"));
return status;
}
Driver.h内容如下:
/************************************************************************
* 文件名称:Driver.h
*************************************************************************/
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //设备名称
UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
HANDLE Section;
PVOID MappedBase;
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT PathLength;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, *PSYSTEM_MODULE_INFORMATION_ENTRY;
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Count;
SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation, // 0 Y N
SystemProcessorInformation, // 1 Y N
SystemPerformanceInformation, // 2 Y N
SystemTimeOfDayInformation, // 3 Y N
SystemNotImplemented1, // 4 Y N
SystemProcessesAndThreadsInformation, // 5 Y N
SystemCallCounts, // 6 Y N
SystemConfigurationInformation, // 7 Y N
SystemProcessorTimes, // 8 Y N
SystemGlobalFlag, // 9 Y Y
SystemNotImplemented2, // 10 Y N
SystemModuleInformation, // 11 Y N
SystemLockInformation, // 12 Y N
SystemNotImplemented3, // 13 Y N
SystemNotImplemented4, // 14 Y N
SystemNotImplemented5, // 15 Y N
SystemHandleInformation, // 16 Y N
SystemObjectInformation, // 17 Y N
SystemPagefileInformation, // 18 Y N
SystemInstructionEmulationCounts, // 19 Y N
SystemInvalidInfoClass1, // 20
SystemCacheInformation, // 21 Y Y
SystemPoolTagInformation, // 22 Y N
SystemProcessorStatistics, // 23 Y N
SystemDpcInformation, // 24 Y Y
SystemNotImplemented6, // 25 Y N
SystemLoadImage, // 26 N Y
SystemUnloadImage, // 27 N Y
SystemTimeAdjustment, // 28 Y Y
SystemNotImplemented7, // 29 Y N
SystemNotImplemented8, // 30 Y N
SystemNotImplemented9, // 31 Y N
SystemCrashDumpInformation, // 32 Y N
SystemExceptionInformation, // 33 Y N
SystemCrashDumpStateInformation, // 34 Y Y/N
SystemKernelDebuggerInformation, // 35 Y N
SystemContextSwitchInformation, // 36 Y N
SystemRegistryQuotaInformation, // 37 Y Y
SystemLoadAndCallImage, // 38 N Y
SystemPrioritySeparation, // 39 N Y
SystemNotImplemented10, // 40 Y N
SystemNotImplemented11, // 41 Y N
SystemInvalidInfoClass2, // 42
SystemInvalidInfoClass3, // 43
SystemTimeZoneInformation, // 44 Y N
SystemLookasideInformation, // 45 Y N
SystemSetTimeSlipEvent, // 46 N Y
SystemCreateSession, // 47 N Y
SystemDeleteSession, // 48 N Y
SystemInvalidInfoClass4, // 49
SystemRangeStartInformation, // 50 Y N
SystemVerifierInformation, // 51 Y Y
SystemAddVerifier, // 52 N Y
SystemSessionProcessesInformation // 53 Y N
} SYSTEM_INFORMATION_CLASS;
#pragma pack(1)
typedef struct ServiceDescriptorEntry{
unsigned int *ServiceTableBase;
unsigned int *ServiceCountTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
extern "C" __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
extern "C" NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);
// 函数声明
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp);
ULONG GetServiceId(PCWSTR FunctionName);
ULONG GetFunctionId(PUNICODE_STRING DllName, char* FunctionName);
void FindModuleByAddress(ULONG Address, PVOID buffer);
ULONG RVA2PTR(ULONG ImageBase, ULONG Rva);
void GetModuleName(char *processPath, char *processName);
ULONG FindOriAddress(ULONG index);