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

📄 log.c

📁 臭氧层主动防御系统驱动源代码!臭氧层主动防御系统驱动源代码!
💻 C
字号:
/*
 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
 *
 * Module Name:
 *
 *		log.c
 *
 * Abstract:
 *
 *		This module implements various alert logging routines.
 *
 * Author:
 *
 *		Eugene Tsyrklevich 24-Mar-2004
 *
 * Revision History:
 *
 *		None.
 */


#include "log.h"
#include "procname.h"
#include "policy.h"	// CDrive declaration


#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, InitLog)
#pragma alloc_text (PAGE, ShutdownLog)
#pragma alloc_text (PAGE, LogPostBootup)
#endif


KSPIN_LOCK			gLogSpinLock;

PKEVENT				LogUserEvent = NULL;
HANDLE				LogUserEventHandle = NULL;

PSECURITY_ALERT		LogList = NULL;				/* alert queue */
PSECURITY_ALERT		LastAlert = NULL;			/* pointer to the last queued alert, used for quick inserts */

USHORT				NumberOfAlerts;				/* number of queued alerts */



/*
 * GetObjectAccessAlertPriority()
 *
 * Description:
 *		Figure out a priority for object access alert category.
 *
 * Parameters:
 *		AlertSubSystem
 *		Operation
 *		ActionTaken
 *
 * Returns:
 *		Chosen priority.
 */

ALERT_PRIORITY
GetObjectAccessAlertPriority(UCHAR AlertSubSystem, UCHAR Operation, ACTION_TYPE ActionTaken)
{
	switch (AlertSubSystem)
	{
		case RULE_FILE:
		case RULE_DIRECTORY:
		case RULE_NAMEDPIPE:
		case RULE_REGISTRY:
		case RULE_SECTION:
		case RULE_JOB:
		case RULE_PORT:
		case RULE_SYMLINK:

			/* default actions are given low priority */
			if (ActionTaken & ACTION_DEFAULT)
				return ALERT_PRIORITY_LOW;

			/* non-read operations are marked medium priority */
			if (Operation != OP_READ)
				return ALERT_PRIORITY_MEDIUM;

			/* whilst read operations are marked low priority */
			return ALERT_PRIORITY_LOW;


		/* high priority rules */
		case RULE_DLL:
		case RULE_PROCESS:
		case RULE_DRIVER:
		case RULE_NETWORK:
		case RULE_SERVICE:

			return ALERT_PRIORITY_HIGH;


		case RULE_TIME:
		case RULE_TOKEN:

			return ALERT_PRIORITY_MEDIUM;


		/* low priority rules */
		case RULE_MAILSLOT:
		case RULE_EVENT:
		case RULE_SEMAPHORE:
		case RULE_MUTANT:
		case RULE_DIROBJ:
		case RULE_ATOM:
		case RULE_SYSCALL:
		case RULE_TIMER:
			
			return ALERT_PRIORITY_LOW;


		default:
			LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, ("GetAlertPriority: Unknown alert subsystem %d\n", AlertSubSystem));
			return ALERT_PRIORITY_MEDIUM;
	}
}



/*
 * FilterObjectName()
 *
 * Description:
 *		.
 *
 * Parameters:
 *		.
 *
 * Returns:
 *		Nothing.
 */
//XXX move elsewhere
PCHAR
FilterObjectName(PCHAR ObjectName)
{
	if (_strnicmp(ObjectName, "\\??\\PIPE\\", 9) == 0)
		return ObjectName + 3;

	if (_strnicmp(ObjectName, "\\??\\", 4) == 0)
		return ObjectName + 4;

	if (_strnicmp(ObjectName, "\\DosDevices\\", 12) == 0)
		return ObjectName + 12;

	if (_strnicmp(ObjectName, "\\BaseNamedObjects\\", 18) == 0)
		return ObjectName + 18;

	if (_strnicmp(ObjectName, CDrive, CDriveLength) == 0 && CDriveLength)
	{
		/* replace any possible \device\harddiskvolumeX references with a DOS C:\ name */
		ObjectName[CDriveLength-2] = 'C';
		ObjectName[CDriveLength-1] = ':';

		ObjectName += CDriveLength - 2;
	}


	return ObjectName;
}



/*
 * LogAlert()
 *
 * Description:
 *		.
 *
 * Parameters:
 *		.
 *
 * Returns:
 *		Nothing.
 */

VOID
LogAlert(UCHAR AlertSubSystem, UCHAR OperationType, UCHAR AlertRuleNumber, ACTION_TYPE ActionTaken, ALERT_PRIORITY AlertPriority, PWSTR PolicyFilename, USHORT PolicyLineNumber, PCHAR ObjectName)
{
	USHORT				Size;
	PSECURITY_ALERT		pAlert;
	KIRQL				irql;

#define	NAME_BUFFER_SIZE	256
	ANSI_STRING			asObjectName;
	UNICODE_STRING		usObjectName;
	WCHAR				ProcessName[NAME_BUFFER_SIZE], ObjectNameW[NAME_BUFFER_SIZE] = { 0 };
	USHORT				ObjectNameLength = 0, ProcessNameLength = 0, PolicyNameLength = 0;

/*
	if (PolicyFilename == NULL)
	{
		LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, (("LogAlert: NULL PolicyFilename\n"));
		return;
	}
*/

	/* \KnownDlls section rules need to be converted to DLLs */
	if (AlertSubSystem == RULE_SECTION)
	{
		if (_strnicmp(ObjectName, "\\KnownDlls\\", 11) == 0)
		{
			ObjectName += 11;
			AlertSubSystem = RULE_DLL;
			OperationType = OP_LOAD;
		}
	}


	if (ObjectName)
	{
		ObjectName = FilterObjectName(ObjectName);

		usObjectName.Length = 0;
		usObjectName.MaximumLength = sizeof(ObjectNameW);
		usObjectName.Buffer = ObjectNameW;

		RtlInitAnsiString(&asObjectName, ObjectName);

		RtlAnsiStringToUnicodeString(&usObjectName, &asObjectName, FALSE);
		ObjectNameW[ asObjectName.Length ] = 0;
	}


	wcsncpy(ProcessName, GetCurrentProcessName(), NAME_BUFFER_SIZE - 1);
	ProcessName[NAME_BUFFER_SIZE - 1] = 0;


	/*
	 * extra +1 for ProcessName & PolicyName zero termination
	 * (ObjectName zero is covered by SECURITY_ALERT wchar[1] declaration)
	 */

	if (ObjectName)
		ObjectNameLength = (USHORT) wcslen(ObjectNameW);

	ProcessNameLength = (USHORT) wcslen(ProcessName);

	if (PolicyFilename)
		PolicyNameLength = (USHORT) wcslen(PolicyFilename);

	Size = sizeof(SECURITY_ALERT) +	(ObjectNameLength + ProcessNameLength + 1 + PolicyNameLength + 1) * sizeof(WCHAR);


	if ((pAlert = (PSECURITY_ALERT) GetCurrentUserSid(&Size)) == NULL)
	{
		LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, ("NULL UserInfo. Security Alert\n"));
		return;
	}


	pAlert->Next = NULL;
	pAlert->Size = Size;
	pAlert->AlertSubsystem = AlertSubSystem;
	pAlert->AlertType = OperationType;
	pAlert->AlertRuleNumber = AlertRuleNumber;
	pAlert->Priority = AlertPriority;
	pAlert->ObjectNameLength = ObjectNameLength;
	pAlert->ProcessNameLength = ProcessNameLength;
	pAlert->PolicyNameLength = PolicyNameLength;
	pAlert->ProcessId = (ULONG) PsGetCurrentProcessId();
	pAlert->Action = ActionTaken;
	pAlert->PolicyLineNumber = PolicyLineNumber;


	if (ObjectName)
		wcscpy(pAlert->ObjectName, ObjectNameW);

	/* process name follows the object name */
	wcscpy(pAlert->ObjectName + ObjectNameLength + 1, ProcessName);

	/* policy name follows the process name */
	if (PolicyFilename)
		wcscpy(pAlert->ObjectName + ObjectNameLength + 1 + ProcessNameLength + 1, PolicyFilename);

	/* save the alert for user agent to pick-up */
	if (ObjectName)
	{
		LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, ("%S Alert. Name %S. Object type %d. Alert type %d.\n", ProcessName, pAlert->ObjectName, pAlert->AlertSubsystem, pAlert->AlertType));
	}
	else
	{
		LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, ("%S Alert. Object type %d. Alert type %d.\n", ProcessName, pAlert->AlertSubsystem, pAlert->AlertType));
	}


	KeAcquireSpinLock(&gLogSpinLock, &irql);
	{
		/*
		 * Put a ceiling on how many alerts we can queue, otherwise we can run out of memory
		 * if userland service is down
		 */

		if (NumberOfAlerts > MAXIMUM_OUTSTANDING_ALERTS)
		{
			LOG(LOG_SS_MISC, LOG_PRIORITY_DEBUG, ("LogAlert: Exceeded maximum number of queued alerts. Dropping.\n"));

			ExFreePoolWithTag(pAlert, _POOL_TAG);

			KeReleaseSpinLock(&gLogSpinLock, irql);

			return;
		}

		++NumberOfAlerts;

		/*
		 * Append alerts to the end of the list so that they show up in a proper order when
		 * picked up by the userland service
		 */

		if (LogList == NULL)
		{
			/* first alert on the list */
			LastAlert = LogList = pAlert;
		}
		else
		{
			LastAlert->Next = pAlert;
			LastAlert = pAlert;
		}

//		pAlert->Next = LogList;
//		LogList = pAlert;
	}
	KeReleaseSpinLock(&gLogSpinLock, irql);


	/*
	 * Pulse the event to notify the user agent.
	 * User-mode apps can't reset a kernel mode event, which is why we're pulsing it here.
	 */

	if (LogUserEvent)
	{
		KeSetEvent(LogUserEvent, 0, FALSE);
		KeClearEvent(LogUserEvent);
	}
}



/*
 * LogPostBootup()
 *
 * Description:
 *		Initializes logging related data once computer is done booting up.
 *
 *		\BaseNamedObjects object directory is not created until the Win32

⌨️ 快捷键说明

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