2.driverbase-内存可读、可写、有效性、指针是否为空、深度校验字符串(随手代码)

时间:2022-06-16 09:21:09

1.如在ring3下,则要判断是否可读可写:

KPROCESSOR_MODE PreviousMode;
	ULONG PID;
	PreviousMode = ExGetPreviousMode();
 
	// 如果非内核模式,就要开始检查IN的这些参数都否可读
	if (PreviousMode != KernelMode)
	{
		try
		{
			 ProbeForRead(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
						 ProbeForWrite(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			return GetExceptionCode();
		}
	}

2. 校验指针是否为空,内存有效性:

	// 效验ClientId是否为NULL
	if (ARGUMENT_PRESENT(ClientId)
		&& MmIsAddressValid(ClientId))
	{
		 //更安全的访问。
		 PID = (ULONG)ClientId->UniqueProcess;
		 KdPrint(("OpenProcess %d\r\n",PID));
	}
3.深度校验字符串函数:

//深度的效验
BOOLEAN ValidateUnicodeString(PUNICODE_STRING usStr)
{
	ULONG i;
 
	__try
	{
		if (!MmIsAddressValid(usStr))
		{
			return FALSE;
		}
		if (usStr->Buffer == NULL || usStr->Length == 0)
		{
			return FALSE;
		}
		for (i = 0; i < usStr->Length; i++)
		{
			if (!MmIsAddressValid((PUCHAR)usStr->Buffer + i))
			{
				return FALSE;
			}
		}
 
	}__except(EXCEPTION_EXECUTE_HANDLER){
 
	}
	return TRUE;
}

//验证一个WCHAR内容的指针是否可以访问
BOOLEAN ValidateWCHARString(WCHAR *pwzStr,ULONG_PTR Length)
{
	ULONG i;
 
	__try
	{
		//第一步判断指针和大小是否为NULL,是的话就没必要验证了
		if  (pwzStr == NULL || Length == 0)
		{
			return FALSE;
		}
		//以length长度循环检查指针pwzStr里面的值
		for (i = 0; i < Length; i++)
		{
			//检查是否可以访问。
			if  (!MmIsAddressValid((PUCHAR)pwzStr + i))
			{
				//只要有一个字节是不可读取
				return FALSE;
			}
		}
 
	}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{ //触发了异常
		return FALSE;
	}
	return TRUE;
}