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; }