驱动加载监控

85 篇文章 6 订阅
83 篇文章 9 订阅

Hook_ZwLoadDriver和HOOK_ZwSetSystemInformation(xp)

Hook_ZwLoadDriver(
  IN PUNICODE_STRING DriverServiceName )//服务名,在注册表

所以要在注册表改驱动ImagePath看驱动路径。

注意通过instrDrv加载驱动不一定看到的是原本加载驱动的文件,是通信方式加载驱动,在ZwLoadDriver中 如果是用SCM加载驱动,那么得到的进程路径是server.exe,所以可Hook

xp:NtRequestWaitReplyPort

Win7:NtAlpcSendWaitReceivePort

或者通过注册回调的方式PsSetLoadImageNotifyRoutine

UCHAR xxx[]="\xb8\x22\x00\x00\xc0\c3";
_CopyMemory(DriverEntry,xxx,sizeof(xxx));
//就是mov eax,0xC0000022//b8 status_access_denied
return //c3

拷贝到DriverEntry起始地址。

代码片段

hook ntloaddriver正常,hook NtAlpcSendWaitReceivePort遇到大坑,只能得到pid,想得到驱动加载的远程序不知道怎么操作,日后再找其他方法,并且停止会蓝屏,只能看到PID

#include "precomp.h"

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
	unsigned int *ServiceTableBase;
	unsigned int *ServiceCounterTableBase; //Used only in checked build
	unsigned int NumberOfServices;
	unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define NUM(x) *(PULONG)((PUCHAR)x+1)
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
#define SDT     SYSTEMSERVICE
#define KSDT KeServiceDescriptorTable

void StartHook(void);
void RemoveHook(void);



typedef struct _PORT_MESSAGE
{
	union
	{
		struct
		{
			CSHORT DataLength;
			CSHORT TotalLength;
		} s1;
		ULONG Length;
	} u1;
	union
	{
		struct
		{
			CSHORT Type;
			CSHORT DataInfoOffset;
		} s2;
		ULONG ZeroInit;
	} u2;
	union
	{
		CLIENT_ID ClientId;
		double DoNotUseThisField;
	};
	ULONG MessageId;
	union
	{
		SIZE_T ClientViewSize; // only valid for LPC_CONNECTION_REQUEST messages
		ULONG CallbackId; // only valid for LPC_REQUEST messages
	};
} PORT_MESSAGE, *PPORT_MESSAGE;
//typedef struct _PORT_MESSAGE *PPORT_MESSAGE;
typedef struct _ALPC_MESSAGE_ATTRIBUTES
{
	ULONG AllocatedAttributes;
	ULONG ValidAttributes;
} ALPC_MESSAGE_ATTRIBUTES, *PALPC_MESSAGE_ATTRIBUTES;



NTKERNELAPI NTSTATUS ZwLoadDriver(
	IN PUNICODE_STRING DriverServiceName);

NTSYSCALLAPI NTSTATUS NTAPI	 ZwAlpcSendWaitReceivePort(
	_In_ HANDLE PortHandle,
	_In_ ULONG 	Flags,
	_In_reads_bytes_opt_(SendMessage->u1.s1.TotalLength) PPORT_MESSAGE 	SendMessage,
	_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES 	SendMessageAttributes,
	_Out_writes_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ReceiveMessage,
	_Inout_opt_ PSIZE_T 	BufferLength,
	_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES 	ReceiveMessageAttributes,
	_In_opt_ PLARGE_INTEGER 	Timeout
);



NTSTATUS Hook_ZwLoadDriver(
	IN PUNICODE_STRING DriverServiceName);


NTSTATUS Hook_NtAlpcSendWaitReceivePort(HANDLE PortHandle,
	ULONG Flags,
	PPORT_MESSAGE SendMessage,
	PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
	PPORT_MESSAGE ReceiveMessage,
	PSIZE_T BufferLength,
	PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
	PLARGE_INTEGER 	Timeout);


//定义函数指针
typedef NTSTATUS(*ZWLOADDRIVER)(
	IN PUNICODE_STRING DriverServiceName);




typedef NTSTATUS(*RealNTALPCSENDWAITRECEIVEPORT)(_In_ HANDLE PortHandle,
	_In_ ULONG 	Flags,
	_In_reads_bytes_opt_(SendMessage->u1.s1.TotalLength) PPORT_MESSAGE 	SendMessage,
	_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES 	SendMessageAttributes,
	_Out_writes_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ReceiveMessage,
	_Inout_opt_ PSIZE_T 	BufferLength,
	_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES 	ReceiveMessageAttributes,
	_In_opt_ PLARGE_INTEGER 	Timeout);

static RealNTALPCSENDWAITRECEIVEPORT OldNtAlpcSendWaitReceivePort;


static ZWLOADDRIVER              OldZwLoadDriver;



static HANDLE g_Pid = 0;    //加载驱动的进程PID

//正则匹配
BOOLEAN IsPatternMatch(PUNICODE_STRING Expression, PUNICODE_STRING Name, BOOLEAN IgnoreCase)
{
	return FsRtlIsNameInExpression(
		Expression,
		Name,
		IgnoreCase,//如果这里设置为TRUE,那么Expression必须是大写的
		NULL
	);
}


NTSTATUS Hook_ZwLoadDriver(
	IN PUNICODE_STRING DriverServiceName)//服务名,在注册表
{
	UNICODE_STRING			uPath = { 0 };
	NTSTATUS				status = STATUS_SUCCESS;
	BOOL					skipOriginal = FALSE;
	WCHAR					szTargetDriver[MAX_PATH] = { 0 };
	WCHAR					szTarget[MAX_PATH] = { 0 };
	R3_RESULT				CallBackResult = R3Result_Pass;
	WCHAR					wszPath[MAX_PATH] = { 0 };
	UNICODE_STRING ustrProcessPath = { 0 };
	WCHAR				wszProcessPath[MAX_PATH] = { 0 };
	__try
	{
		UNICODE_STRING CapturedName;

		if ((ExGetPreviousMode() == KernelMode) ||
			(DriverServiceName == NULL))
		{
			skipOriginal = TRUE;
			status = OldZwLoadDriver(DriverServiceName);
			return status;
		}

		uPath.Length = 0;
		uPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
		uPath.Buffer = wszPath;


		CapturedName = ProbeAndReadUnicodeString(DriverServiceName);

		ProbeForRead(CapturedName.Buffer,
			CapturedName.Length,
			sizeof(WCHAR));

		RtlCopyUnicodeString(&uPath, &CapturedName);

		if (ntGetDriverImagePath(&uPath, szTargetDriver))
		{

			// 			if(ntIsDosDeviceName(szTargetDriver))
			// 			{
			// 				if( ntGetNtDeviceName(szTargetDriver, 
			// 					szTarget))
			// 				{
			// 					RtlStringCbCopyW(szTargetDriver, 
			// 						sizeof(szTargetDriver), 
			// 						szTarget);
			// 				}
			// 			}
			DbgPrint("Driver:%ws will be loaded\n", szTargetDriver);
			ustrProcessPath.Buffer = wszProcessPath;
			ustrProcessPath.Length = 0;
			ustrProcessPath.MaximumLength = sizeof(wszProcessPath);
			GetProcessFullNameByPid(PsGetCurrentProcessId(), &ustrProcessPath);
			DbgPrint("Parent:%wZ\n", &ustrProcessPath);

			//CallBackResult = hipsGetResultFromUser(L"加载", szTargetDriver, NULL,User_DefaultNon);//弹窗
			if (CallBackResult == R3Result_Block)
			{
				return STATUS_ACCESS_DENIED;
			}

			skipOriginal = TRUE;
			status = OldZwLoadDriver(DriverServiceName);
			return status;
		}


	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{

	}

	if (skipOriginal)
		return status;

	return OldZwLoadDriver(DriverServiceName);
}



NTSTATUS Hook_NtAlpcSendWaitReceivePort(HANDLE PortHandle,
	ULONG Flags,
	PPORT_MESSAGE SendMessage,
	PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
	PPORT_MESSAGE ReceiveMessage,
	PSIZE_T BufferLength,
	PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
	PLARGE_INTEGER 	Timeout)
{
	UNICODE_STRING StrProcessName = { 0 };
	StrProcessName.MaximumLength = MAX_PATH * sizeof(WCHAR);
	StrProcessName.Length = 0;
	WCHAR tmp[MAX_PATH] = { 0 };
	StrProcessName.Buffer = tmp;
	UNICODE_STRING uExpression = { 0 };
	RtlInitUnicodeString(&uExpression, L"*SERVICES.EXE");
	__try {
		if (SendMessage)
		{
			g_Pid = PsGetCurrentProcessId();
			DbgPrint("DriverLoad PID=%d\n", g_Pid);
			GetProcessFullNameByPid((HANDLE)g_Pid, &StrProcessName);
			if (IsPatternMatch(&uExpression, &StrProcessName, TRUE))
			{
				DbgPrint("Parent:%wZ\n", &StrProcessName);
			}
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{

	}
		return OldNtAlpcSendWaitReceivePort(PortHandle, Flags, SendMessage,
			SendMessageAttributes, ReceiveMessage, BufferLength, ReceiveMessageAttributes,
			Timeout);
}




NTSTATUS RtlSuperCopyMemory(IN VOID UNALIGNED *Dst,
	IN CONST VOID UNALIGNED *Src,
	IN ULONG Length)
{
	PMDL pmdl = IoAllocateMdl(Dst, Length, 0, 0, NULL);
	if (pmdl == NULL)
		return STATUS_UNSUCCESSFUL;
	MmBuildMdlForNonPagedPool(pmdl);
	unsigned int *Mapped = (unsigned int *)MmMapLockedPages(pmdl, KernelMode);
	if (!Mapped)
	{
		IoFreeMdl(pmdl);
		return STATUS_UNSUCCESSFUL;
	}

	KIRQL kirql = KeRaiseIrqlToDpcLevel();

	RtlCopyMemory(Mapped, Src, Length);

	KeLowerIrql(kirql);

	MmUnmapLockedPages((PVOID)Mapped, pmdl);
	IoFreeMdl(pmdl);

	return STATUS_SUCCESS;

}

void StartHook(void)
{
	//获取未导出的服务函数索引号
	HANDLE    hFile;
	PCHAR    pDllFile;
	ULONG  ulSize;
	ULONG  ulByteReaded;


	OldZwLoadDriver = SDT(ZwLoadDriver);
	ULONG hookAddr = (ULONG)Hook_ZwLoadDriver;
	OldNtAlpcSendWaitReceivePort = SDT(ZwAlpcSendWaitReceivePort);
	ULONG hookAddr1 = (ULONG)Hook_NtAlpcSendWaitReceivePort;
	
	
	
	
	RtlSuperCopyMemory(&SDT(ZwLoadDriver), &hookAddr, 4);    //关闭
	
	
	RtlSuperCopyMemory(&SDT(ZwAlpcSendWaitReceivePort), &hookAddr1, 4);
	return;
}

void RemoveHook(void)
{
	
	ULONG hookAddr = (ULONG)OldZwLoadDriver;
	RtlSuperCopyMemory(&SDT(ZwLoadDriver), &hookAddr, 4);    //关闭

	ULONG hookAddr1 = (ULONG)OldNtAlpcSendWaitReceivePort;
	RtlSuperCopyMemory(&SDT(ZwAlpcSendWaitReceivePort), &hookAddr1, 4);    //关闭

}




 

Unhook需要通过deviceiocontrol来进行参考【原创】总结一把,较为精确判断SCM加载 - 看雪安全论坛
https://bbs.pediy.com/thread-135988.htm

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 驱动加载工具drivermonitor是一款用于监控和管理系统驱动程序的软件。它能够帮助用户实时监测和管理计算机中驱动加载情况,确保系统驱动的正常运行。 驱动加载工具drivermonitor的主要功能包括以下几个方面: 1. 驱动监控:该工具可以监控系统驱动加载过程,实时显示驱动加载情况,包括加载成功与失败的驱动监控功能可以帮助用户及时发现并解决驱动加载问题,提高系统的稳定性和性能。 2. 驱动管理:该工具提供驱动管理功能,用户可以通过工具对已加载驱动程序进行查看、卸载和更新操作。用户可以根据具体需求来管理系统驱动,保持系统驱动程序的最新和正确性。 3. 驱动备份与恢复:工具提供驱动备份和恢复功能。用户可以备份系统中的驱动程序,确保在需要重新安装系统或更换硬件时能够迅速恢复所有驱动。这样可以节省用户手动查找和下载驱动程序的时间和精力。 4. 驱动更新:工具可以自动检测并下载最新的官方驱动程序,帮助用户及时更新系统驱动以提升系统性能和稳定性。更新驱动可以修复一些已知的驱动问题,提高硬件设备的兼容性和使用效果。 总之,驱动加载工具drivermonitor是一个方便实用的工具,可以帮助用户监控和管理系统驱动程序,以保证系统的稳定运行。通过其提供的功能,用户可以更好地维护和管理系统驱动,提升计算机的工作效率和用户体验。 ### 回答2: 驱动加载工具DriverMonitor是一款非常有用的软件,它可以帮助用户实时监控和管理计算机上的驱动程序。今天,我将向大家介绍一下该工具的功能和优点。 首先,DriverMonitor可以自动检测和识别计算机上的所有已安装驱动程序。它会显示驱动程序的名称、版本号以及提供商等详细信息,让用户可以清楚地了解自己系统中的驱动情况。 其次,DriverMonitor会实时监控已安装驱动程序的状态和更新情况。如果有新版本的驱动程序可用,它会及时通知用户,并提供下载和安装的选项。这个功能非常方便,因为驱动程序的更新通常能够修复一些系统问题,提升性能和兼容性。 此外,DriverMonitor还提供了一键备份和恢复驱动程序的功能。用户可以选择性地备份系统中的驱动程序,以防在安装新版本驱动程序之前出现问题。如果不小心卸载了某个驱动程序,用户也可以通过DriverMonitor快速恢复到之前的备份,避免不必要的麻烦。 最后,DriverMonitor还有一个驱动程序的卸载功能。当用户不再需要某个驱动程序时,它可以完全清除该驱动程序的所有相关文件和注册表项,确保系统的干净和稳定。 总之,驱动加载工具DriverMonitor是一款功能全面且易于使用的软件。它能够帮助用户监控和管理计算机上的驱动程序,提供驱动程序更新和备份、恢复功能,以及驱动程序的完全卸载。无论是日常使用还是解决系统问题,DriverMonitor都能为用户提供便捷的驱动程序管理工具。 ### 回答3: 驱动加载工具DriverMonitor是一种帮助用户管理和监控计算机驱动程序的软件。它可以自动检测计算机上已安装的驱动程序,并提供详细的信息和实时监控。用户可以通过DriverMonitor来查看驱动程序的版本、厂商以及其它相关信息,这有助于了解计算机中各个设备的驱动情况。 DriverMonitor还可以帮助用户更新驱动程序。它会定期检查计算机中每个设备的驱动程序是否有新的版本可用,并提供更新的提醒。用户可以通过DriverMonitor的界面一键更新驱动程序,这样可以保持计算机设备的最新状态,提升计算机的性能和稳定性。 此外,DriverMonitor还具备一些其他功能。它可以创建系统快照,用于备份和还原驱动程序。如果用户在更新驱动程序过程中出现问题,可以使用系统快照来还原到之前的驱动版本。同时,DriverMonitor还具备驱动程序的卸载功能,可以帮助用户完全移除不需要的驱动程序,释放磁盘空间和优化系统性能。 总之,驱动加载工具DriverMonitor是一款功能强大、易于使用的软件。它可以帮助用户管理和监控计算机驱动程序,提供更新驱动的提醒,并具备系统快照和驱动卸载等功能。通过使用DriverMonitor,用户可以更好地维护和优化计算机的驱动程序,提升计算机的性能和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值