驱动加载监控

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值