基于文件与内容比较检测SSDT变化

在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);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值