⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pathproc.c

📁 臭氧层主动防御系统驱动源代码!臭氧层主动防御系统驱动源代码!
💻 C
📖 第 1 页 / 共 2 页
字号:
	pusFilename = &ObjectName;


	/*
	 * is the filename referenced in relation to some directory?
	 * if so, append the filename to a specified directory name
	 */

	if (ARGUMENT_PRESENT(ObjectAttributes->RootDirectory))
	{
		if (! NT_SUCCESS( ObReferenceObjectByHandle(ObjectAttributes->RootDirectory, 0, 0,
													KernelMode, &Object, NULL) ))
		{
			ObDereferenceObject(Object);
			FINISH_GetPathFromOA(("GetPathFromOA(): ObReferenceObjectByHandle() failed\n"));
		}


		if (Object == NULL)
		{
			ObDereferenceObject(Object);
			FINISH_GetPathFromOA(("GetPathFromOA(): Object = NULL\n"));
		}


		if (! NT_SUCCESS( ObQueryNameString(Object, pONI, bMAX_PATH, &len) ))
		{
			ObDereferenceObject(Object);
			FINISH_GetPathFromOA(("GetPathFromOA(): ObQueryNameString() failed\n"));
		}


		ObDereferenceObject(Object);
		Object = NULL;


		/* extracted directory name */
		pusFilename = &pONI->Name;


		/* is the directory name too long? */

		if (pusFilename->Length >= bMAX_PATH - sizeof(WCHAR))
			FINISH_GetPathFromOA(("GetPathFromOA(): directory name is too long\n"));


		/*
		 * pusFilename points to a buffer of MAX_PATH size, ObQueryNameString() sets MaximumLength to the length
		 * of the directory name, we need to reset this back to MAX_PATH to be able to append a filename
		 * (reusing the same buffer)
		 */
		pusFilename->MaximumLength = bMAX_PATH;


		pusFilename->Buffer[ pusFilename->Length / sizeof(WCHAR) ] = L'\\';
		pusFilename->Length += sizeof(WCHAR);


		if (RtlAppendUnicodeStringToString(pusFilename, ObjectAttributes->ObjectName) == STATUS_BUFFER_TOO_SMALL)
		{
			LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("GetPathFromOA: 1 %S\n", pusFilename->Buffer));
			LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("GetPathFromOA: 2 %S\n", ObjectAttributes->ObjectName->Buffer));
			FINISH_GetPathFromOA(("GetPathFromOA(): RtlAppendUnicodeStringToString() = STATUS_BUFFER_TOO_SMALL\n"));
		}
	}


	if (ResolveLinks == TRUE)
	{
		ret = ResolveFilenameW(pusFilename, OutBuffer, OutBufferSize);
	}

//XXX
	if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, pusFilename, TRUE)))
	{	
		if (ResolveLinks == TRUE)
		{
			ret = ResolveFilename(name.Buffer, OutBuffer, OutBufferSize);
		}
		else
		{
			if (name.Length >= OutBufferSize - 1)
			{
				LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("GetPathFromOA: Pathname too long %d\n", name.Length));

				OutBuffer[0] = 0;

				ret = FALSE;
			}
			else
			{
				strcpy(OutBuffer, name.Buffer);

				ret = TRUE;
			}
		}

		RtlFreeAnsiString(&name);
	}


//	LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("%d GetPathFromOA: %s (%S)\n", (ULONG) PsGetCurrentProcessId(), OutBuffer, pusFilename->Buffer));


	return ret;
}


/*
 * ConvertLongFileNameToShort()
 *
 * Description:
 *		Converts long windows filenames to their DOS short equivalent filenames
 *		(i.e. c:\program files to c:\progra~1).
 *
 * Parameters:
 *		LongFileName - long filename buffer.
 *		ShortFileName - output buffer where a short filename is written to.
 *		ShortFileNameSize - size of an output buffer (in bytes).
 *
 * Returns:
 *		TRUE to indicate success, FALSE if failed.
 */

#if 0

BOOLEAN
ConvertLongFileNameToShort(IN PCHAR LongFileName, OUT PCHAR ShortFileName, IN USHORT ShortFileNameSize)
{
	int			LongFileNameIndex = 0, ShortFileNameIndex = 0, CurrentFileNameLength, TotalLength, ExtensionLength, NumberOfSpaces;
	BOOLEAN		ProcessingExtension = FALSE;
	CHAR		ch, Extension[3];


	if (LongFileName == NULL)
		return FALSE;

	TotalLength = strlen(LongFileName);


	/* if the filename does not start with X:\ then assume \device\blah\ format and skip over the first 2 slashes */
	if (LongFileName[0] == '\\')
	{
		int Slashes = 0;

		do
		{
			if ( (ch = ShortFileName[ShortFileNameIndex++] = LongFileName[LongFileNameIndex++]) == '\0') return TRUE;
			if (ch == '\\') ++Slashes;
		} while (Slashes != 3);
	}

	for (NumberOfSpaces = ExtensionLength = CurrentFileNameLength = 0; ; LongFileNameIndex++)
	{
		/* if we finished traversing the entire directory path or reached a '\' then process the filename (append the extension if necessary) */
		if (LongFileNameIndex == TotalLength || LongFileName[LongFileNameIndex] == '\\')
		{
			/*
			 * if the filename is longer than 8 chars or extension is longer than 3 chars then we need
			 * to create a 6 char filename followed by a '~1' and the first 3 chars of the last extension
			 */

			if (CurrentFileNameLength > 8 || ExtensionLength > 3 || NumberOfSpaces > 0)
			{
				CurrentFileNameLength -= NumberOfSpaces;

				if (CurrentFileNameLength > 7)
				{
					ShortFileName[ShortFileNameIndex - 2] = '~';
					ShortFileName[ShortFileNameIndex - 1] = '1';
				}
				else if (CurrentFileNameLength == 7)
				{
					ShortFileName[ShortFileNameIndex - 1] = '~';
					ShortFileName[ShortFileNameIndex++] = '1';
				}
				else
				{
					ShortFileName[ShortFileNameIndex++] = '~';
					ShortFileName[ShortFileNameIndex++] = '1';
				}
			}

			if (ExtensionLength > 0)
			{
				ShortFileName[ShortFileNameIndex++] = '.';
				ShortFileName[ShortFileNameIndex++] = Extension[0];

				if (ExtensionLength > 1)
				{
					ShortFileName[ShortFileNameIndex++] = Extension[1];

					if (ExtensionLength > 2)
						ShortFileName[ShortFileNameIndex++] = Extension[2];
				}

				ExtensionLength = 0;
				ProcessingExtension = FALSE;
			}

			/* if we are done traversing the entire path than we can bail */
			if (LongFileNameIndex == TotalLength)
				break;

			ShortFileName[ShortFileNameIndex++] = '\\';
			NumberOfSpaces = CurrentFileNameLength = 0;

			continue;
		}

		if (LongFileName[LongFileNameIndex] == '.')
		{
			ProcessingExtension = TRUE;
			ExtensionLength = 0;
			continue;
		}

		if (ProcessingExtension == TRUE)
		{
			if (ExtensionLength++ < 3)
				Extension[ExtensionLength - 1] = LongFileName[LongFileNameIndex];

			continue;
		}

		if (((CurrentFileNameLength++) - NumberOfSpaces) < 8)
		{
			if (LongFileName[LongFileNameIndex] != ' ')
				ShortFileName[ShortFileNameIndex++] = LongFileName[LongFileNameIndex];
			else
				++NumberOfSpaces;
		}
	}


	ShortFileName[ShortFileNameIndex++] = 0;


	return TRUE;
}

#endif



/*
 * GetNameFromHandle()
 *
 * Description:
 *		Resolve an object handle to an object name.
 *
 * Parameters:
 *		ObjectHandle - handle of an object whose name we are trying to obtain.
 *		OutBuffer - output buffer where an object name will be saved to.
 *		OutBufferSize - size of an output buffer (in bytes).
 *
 * Returns:
 *		TRUE to indicate success, FALSE if failed.
 */

PWSTR
GetNameFromHandle(IN HANDLE ObjectHandle, OUT PWSTR OutBuffer, IN USHORT OutBufferSize)
{
	PVOID						Object = NULL;
	NTSTATUS					rc;
	POBJECT_NAME_INFORMATION	pONI = (POBJECT_NAME_INFORMATION) OutBuffer;
	ULONG						len;


	rc = ObReferenceObjectByHandle(ObjectHandle, GENERIC_READ, NULL, KernelMode, &Object, NULL);
	if (! NT_SUCCESS(rc))
	{
		LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("%d GetNameFromHandle: ObReferenceObjectByHandle failed\n", (ULONG) PsGetCurrentProcessId()));
		return NULL;
	}


	rc = ObQueryNameString(Object, pONI, OutBufferSize - sizeof(OBJECT_NAME_INFORMATION)*sizeof(WCHAR), &len);
	if (! NT_SUCCESS(rc))
	{
		LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("%d GetNameFromHandle: ObQueryNameString failed\n", (ULONG) PsGetCurrentProcessId()));
		return NULL;
	}

	
//	_snprintf(OutBuffer, OutBufferSize, "%S", pONI->Name.Buffer);
//	OutBuffer[OutBufferSize - 1] = 0;

//	LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("%S (%s)\n", pONI->Name.Buffer, OutBuffer));


	ObDereferenceObject(Object);


	return pONI->Name.Buffer;
//	return TRUE;
}



/*
 * StripFileMacros()
 *
 * Description:
 *		Strip file names of %SystemRoot% and %SystemDrive% macros as well as any specifications.
 *
 * Parameters:
 *		Path - ASCII file path to parse.
 *		Buffer - pointer to an Object where the final result will be saved.
 *		BufferSize - size of the output Buffer.
 *
 * Returns:
 *		Pointer to a stripped ASCII path.
 */

PCHAR
StripFileMacros(IN PCHAR Path, OUT PCHAR Buffer, IN USHORT BufferSize)
{
	if (_strnicmp(Path, "%systemdrive%:", 14) == 0)
	{
		return Path + 14;
	}


	if (_strnicmp(Path, "%systemroot%\\", 13) == 0)
	{
		if (_snprintf(Buffer, MAX_PATH, "%s%s", SystemRootUnresolved, Path + 12) < 0)
			return NULL;

		Path = Buffer;
	}


	if (Path[1] == ':' && Path[2] == '\\' && (isalpha(Path[0]) || Path[0] == '?' || Path[0] == '*'))
	{
		Path += 2;
	}


	return Path;
}



/*
 * FixupFilename()
 *
 * Description:
 *		Get canonical name for a file (without the drive specification, i.e. \windows\blah.exe)
 *
 * Parameters:
 *		szFileName - filename to resolve.
 *		szResult - output buffer.
 *		szResultSize - size of an output buffer.
 *
 * Returns:
 *		TRUE to indicate success, FALSE if failed.
 */

BOOLEAN
FixupFilename(IN PCHAR szFileName, OUT PCHAR szResult, IN USHORT szResultSize)
{
	/* skip over \??\ */
	if (_strnicmp(szFileName, "\\??\\", 4) == 0)
	{
		szFileName += 4;
	}


	/* replace "\SystemRoot" references with the actual system root directory */
	if (_strnicmp(szFileName, "\\SystemRoot\\", 12) == 0)
	{
		_snprintf(szResult, szResultSize, "%s\\%s", SystemRootDirectory, szFileName + 12);
		szResult[ szResultSize - 1 ] = 0;

		return TRUE;
	}


	/* skip over X: drive specifications */
	if (isalpha(szFileName[0]) && szFileName[1] == ':' && szFileName[2] == '\\')
	{
		szFileName += 2;
	}


	strncpy(szResult, szFileName, szResultSize);
	szResult[ szResultSize - 1 ] = 0;


	return TRUE;
}



/*
 * AreMalformedExtensionsAllowed()
 *
 * Description:
 *		Check whether the current process is allowed to run binaries with malformed file extensions.
 *
 * Parameters:
 *		None.
 *
 * Returns:
 *		FALSE if binaries with malformed extensions are not allowed to run. TRUE otherwise.
 */

BOOLEAN
AreMalformedExtensionsAllowed()
{
	PIMAGE_PID_ENTRY	CurrentProcess;
	BOOLEAN				MalformedExtensionsAllowed = FALSE;


	/* check the global policy first */
	if (! IS_EXTENSION_PROTECTION_ON(gSecPolicy))
		return TRUE;


	/* now check the process specific policy */
	CurrentProcess = FindImagePidEntry(CURRENT_PROCESS_PID, 0);

	if (CurrentProcess != NULL)
	{
		MalformedExtensionsAllowed = ! IS_EXTENSION_PROTECTION_ON(CurrentProcess->SecPolicy);
	}
	else
	{
		LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("%d AreMalformedExtensionsAllowed: CurrentProcess = NULL!\n", (ULONG) PsGetCurrentProcessId()));
	}


	return MalformedExtensionsAllowed;
}



/*
 * VerifyExecutableName()
 *
 * Description:
 *		Make sure the executed binary does not have a funny filename.
 *		Look out for non-standard extensions (.exe, etc) and double
 *		extensions that are commonly "ab"used by malware.
 *
 * Parameters:
 *		szFileName - filename to verify.
 *
 * Returns:
 *		TRUE to indicate success, FALSE if failed.
 */

#define	CHECK_LEARNING_MODE()								\
	if (LearningMode == TRUE)								\
	{														\
		TURN_EXTENSION_PROTECTION_OFF(NewPolicy);			\
		return TRUE;										\
	}

BOOLEAN
VerifyExecutableName(IN PCHAR szFileName)
{
	SHORT		i, len;
	BOOLEAN		FirstExtension = TRUE;


	if (LearningMode == FALSE && AreMalformedExtensionsAllowed() == TRUE)
	{
		/* no need to check anything further, malformed extensions are allowed */
		return TRUE;
	}


	if ((len = (SHORT) strlen(szFileName)) == 0)
		return TRUE;


	for (i = len - 1; i >= 0; i--)
	{
		/* bail out once we reach the end of the filename */
		if (szFileName[i] == '\\')
			break;

		if (szFileName[i] == '.')
		{
			if (FirstExtension == FALSE)
			{
				CHECK_LEARNING_MODE();

				LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing a binary with more than one extension '%s'\n", szFileName));

				LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_2EXTS, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);

				return FALSE;
			}

			if (len - i != 4)
			{
				CHECK_LEARNING_MODE();

				LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing a binary with an unknown extension '%s'\n", szFileName));

				LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_UNKNOWN, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);

				return FALSE;
			}
			else
			{
				if (_stricmp(szFileName + i + 1, "exe") != 0 &&
					_stricmp(szFileName + i + 1, "com") != 0 &&
					_stricmp(szFileName + i + 1, "bat") != 0 &&
					_stricmp(szFileName + i + 1, "scr") != 0 &&
					_stricmp(szFileName + i + 1, "dir") != 0 &&
					_stricmp(szFileName + i + 1, "tmp") != 0 &&
					_stricmp(szFileName + i + 1, "_mp") != 0)
				{
					CHECK_LEARNING_MODE();

					LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing a binary with an unknown extension '%s'\n", szFileName));

					LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_UNKNOWN, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);

					return FALSE;
				}
			}

			FirstExtension = FALSE;
		}
	}


	if (FirstExtension == TRUE)
	{
		CHECK_LEARNING_MODE();

		LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing binary without an extension '%s'\n", szFileName));

		LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_NOEXT, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);

		return FALSE;
	}


	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -