learn.c

来自「臭氧层主动防御系统驱动源代码!臭氧层主动防御系统驱动源代码!」· C语言 代码 · 共 1,415 行 · 第 1/2 页

C
1,415
字号
/*
 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
 *
 * Module Name:
 *
 *		learn.c
 *
 * Abstract:
 *
 *		This module implements various policy-auto-generation routines.
 *		Policy auto generation works by monitoring all system calls and remembering their
 *		argument values. These are then saved in a policy file.
 *
 * Author:
 *
 *		Eugene Tsyrklevich 24-Feb-2004
 *
 * Revision History:
 *
 *		None.
 */


#include <NTDDK.h>
#include "learn.h"
#include "accessmask.h"
#include "hookproc.h"
#include "procname.h"
#include "process.h"
#include "log.h"


#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, InitLearningMode)
#endif


//XXX on a terminal server, global\* might need to be handled specially

WCHAR				ProcessToMonitor[MAX_PROCESS_NAME] = L"";

BOOLEAN				LearningMode = FALSE;
HANDLE				hFile;
INT64				offset;

BOOLEAN				IsGuiThread = FALSE;	/* does the process we are profiling contain any GUI threads? */

SECURITY_POLICY		NewPolicy;



/*
 * InitLearningMode()
 *
 * Description:
 *		Initialize a learning/training mode. Training mode is used to create process policies that
 *		describe all the resources used by a process.
 *
 *		Called during driver initialization (DriverEntry()) or from DriverDeviceControl().
 *
 * Parameters:
 *		None.
 *
 * Returns:
 *		TRUE to indicate success, FALSE if failed.
 */

BOOLEAN
InitLearningMode()
{
	LOG(LOG_SS_LEARN, LOG_PRIORITY_VERBOSE, ("InitLearningMode: Entered.\n"));


	/* initialize the NewPolicy */
	RtlZeroMemory(&NewPolicy, sizeof(NewPolicy));

	KeInitializeSpinLock(&NewPolicy.SpinLock);

	NewPolicy.ProtectionFlags = PROTECTION_ALL_ON;


	/*
	 * Load an existing policy (if there is one) and use it as a template
	 */

	if (FindAndLoadSecurityPolicy(&NewPolicy, ProcessToMonitor, NULL) == FALSE)
	{
		LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("InitLearningMode: Learning about '%S'. An existing policy not found.\n", ProcessToMonitor));

		NewPolicy.DefaultPolicyAction = ACTION_LOG;
	}
	else
	{
		LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("InitLearningMode: Learning about '%S'. Using a pre-existing policy.\n", ProcessToMonitor));
	}


	return TRUE;
}



/*************************************************************************************************
 *
 * Path Filters
 * Used to convert kernel object names into their userland representation
 * (i.e. registry \REGISTRY\USER will be converted to HKEY_USERS
 *
 *************************************************************************************************/



/*
 * FilterFilePath()
 *
 * Description:
 *		Convert kernel file paths to their userland representation (i.e. removing \??\, \DosDevices\, references).
 *
 * Parameters:
 *		path - Pointer to a source character file path.
 *
 * Returns:
 *		Pointer to a post-processed file path.
 */

PCHAR
FilterFilePath(PCHAR path)
{
	CHAR	buffer[MAX_PATH];


	if (path[0] != '\\' && path[0] != '%')
	{
//		KdPrint(("FilterFilePath: special filename %s\n", path));
//		return NULL;
	}


	if (_strnicmp(path, "\\??\\pipe", 8) == 0)
	{
		return path + 3;
	}

	if (_strnicmp(path, "\\??\\", 4) == 0)
	{
		path += 4;
	}
	else if (_strnicmp(path, "\\DosDevices\\", 12) == 0)
	{
		path += 12;
	}
	else if (_strnicmp(path, CDrive, CDriveLength) == 0 && CDriveLength)
	{
		/* replace any possible \device\harddiskvolumeX references with a DOS C:\ name */
		//XXX what about d:\ and so on?

		path[CDriveLength-2] = 'C';
		path[CDriveLength-1] = ':';

		path += CDriveLength - 2;
	}



	if (_strnicmp(path, SystemRootDirectory, SystemRootDirectoryLength) == 0 && SystemRootDirectoryLength)
	{
		/* replace \windows (systemroot) references with SystemRoot */

		strcpy(buffer, "%SystemRoot%");
		strcat(buffer, path + SystemRootDirectoryLength);

		path = buffer;
	}
	else if (_strnicmp(path, SystemRootUnresolved, SystemRootUnresolvedLength) == 0 && SystemRootUnresolvedLength)
	{
		/* replace c:\windows (systemroot) references with SystemRoot */

		strcpy(buffer, "%SystemRoot%");
		strcat(buffer, path + SystemRootUnresolvedLength);

		path = buffer;
	}
	else if (_strnicmp(path, "\\SystemRoot\\", 12) == 0)
	{
		strcpy(buffer, "%SystemRoot%");
		strcat(buffer, path + 11);

		path = buffer;
	}
	else if ((path[0] == SystemDrive || path[0] == (CHAR) tolower(SystemDrive)) && path[1] == ':')
	{
		/* replace any system drive references with "SystemDrive" */
		strcpy(buffer, "%SystemDrive%");
		strcat(buffer, path + 1);

		path = buffer;
	}


	return path;
}



/*
 * FilterMailslotPath()
 *
 * Description:
 *		Convert kernel mailslot paths to their userland representation.
 *
 * Parameters:
 *		path - Pointer to a source character path.
 *
 * Returns:
 *		Pointer to a post-processed path.
 */

PCHAR
FilterMailslotPath(PCHAR path)
{
	if (_strnicmp(path, "\\mailslot\\", 10) == 0)
		return path + 10;

	if (_strnicmp(path, "\\??\\mailslot\\", 13) == 0)
		return path + 13;

	if (_strnicmp(path, "\\device\\mailslot\\", 17) == 0)
		return path + 17;

	return path;
}



/*
 * FilterNamedpipePath()
 *
 * Description:
 *		Convert kernel namedpipe paths to their userland representation.
 *
 * Parameters:
 *		path - Pointer to a source character path.
 *
 * Returns:
 *		Pointer to a post-processed path.
 */

PCHAR
FilterNamedpipePath(PCHAR path)
{
	if (_strnicmp(path, "\\pipe\\", 6) == 0)
		return path + 6;

	if (_strnicmp(path, "\\??\\pipe\\", 9) == 0)
		return path + 9;

	if (_strnicmp(path, "\\device\\namedpipe\\", 18) == 0)
		return path + 18;

	return path;
}



/*
 * FilterRegistryPath()
 *
 * Description:
 *		Convert kernel registry paths to their userland equivalents
 *		(i.e. replacing \REGISTRY\USER\ kernel path with its userland HKEY_USERS\ representation).
 *
 * Parameters:
 *		path - Pointer to a source character registry path.
 *
 * Returns:
 *		Pointer to a post-processed registry path.
 */

PCHAR
FilterRegistryPath(PCHAR path)
{
	static char	buffer[MAX_PATH];


//XXX use reverse symlink lookup for this?!?!?

	if (_strnicmp(path, "\\REGISTRY\\", 10) == 0)
	{
		/* replace \Registry\User\ with HKEY_USERS\ */
		if (_strnicmp(path + 10, "USER\\", 5) == 0)
		{
			strcpy(path + 4, "HKEY_USERS");
			path[14] = '\\';
			return path + 4;
		}

		/* replace \Registry\Machine\ with HKEY_LOCAL_MACHINE\ */
		if (_strnicmp(path + 10, "MACHINE\\", 8) == 0)
		{
			strcpy(buffer, "HKEY_LOCAL_MACHINE\\");
			strncat(buffer, path + 18, MAX_PATH - 20);

			return buffer;
		}
	}


	return path;
}



/*
 * FilterBaseNamedObjectsPath()
 *
 * Description:
 *		Convert kernel paths to their userland representation (by removing \BaseNamedObjects\ kernel reference).
 *
 * Parameters:
 *		path - Pointer to a source character event or semaphore path.
 *
 * Returns:
 *		Pointer to a post-processed path.
 */

PCHAR
FilterBaseNamedObjectsPath(PCHAR path)
{
	if (_strnicmp(path, "\\BaseNamedObjects\\", 18) == 0)
	{
		return path + 18;
	}

	return path;
}



/*
 * FilterDll()
 *
 * Description:
 *		Convert kernel DLL path to its userland representation
 *		(i.e. removing \KnownDlls\ kernel reference).
 *
 * Parameters:
 *		path - Pointer to a source character DLL path.
 *
 * Returns:
 *		Pointer to a post-processed DLL path.
 */

PCHAR
FilterDll(PCHAR path)
{
	if (_strnicmp(path, "\\KnownDlls\\", 11) == 0)
	{
		return path + 11;
	}

	return path;
}



/*
 * FilterPath()
 *
 * Description:
 *		Filter stub.
 *
 * Parameters:
 *		path - Pointer to a source character path.
 *
 * Returns:
 *		Pointer to an unmodified path.
 */

PCHAR
FilterPath(PCHAR path)
{
	return path;
}



/*************************************************************************************************
 *
 * Operation Filters
 * Convert operations (such as OP_READ, OP_WRITE) into their ASCII representation.
 * (i.e. file OP_READ will be translated to "read" while atom OP_READ will become "find"
 *
 *************************************************************************************************/



/*
 * FilterOperation()
 *
 * Description:
 *		Convert operations (such as OP_READ, OP_WRITE) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_READ_WRITE) &&
		(IS_BIT_SET(OperationType, OP_DELETE) || IS_BIT_SET(OperationType, OP_EXECUTE)))

		return "all";


	if (IS_BIT_SET(OperationType, OP_DELETE))
		return "delete";

	if (IS_BIT_SET(OperationType, OP_READ_WRITE))
		return "rw";

	if (IS_BIT_SET(OperationType, OP_READ))
		return "read";

	if (IS_BIT_SET(OperationType, OP_WRITE))
		return "write";

	if (IS_BIT_SET(OperationType, OP_EXECUTE))
		return "execute";


	//XXX what about when multiple bits are set? read + delete?
	LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterOperation: invalid operation type %d\n", OperationType));


	return "all";
}



/*
 * FilterSimpleOperation()
 *
 * Description:
 *		Convert operations (such as OP_READ, OP_WRITE) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterSimpleOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_READ_WRITE))
		return "all";

	if (IS_BIT_SET(OperationType, OP_READ))
		return "read";

	if (IS_BIT_SET(OperationType, OP_WRITE))
		return "write";

	LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterSimpleOperation: invalid operation type %d\n", OperationType));


	return "all";
}



/*
 * FilterCreateOpenOperation()
 *
 * Description:
 *		Convert OP_CREATE and OP_OPEN) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterCreateOpenOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_CREATE) &&
		IS_BIT_SET(OperationType, OP_OPEN))

		return "all";

	if (IS_BIT_SET(OperationType, OP_CREATE))
		return "create";

	if (IS_BIT_SET(OperationType, OP_OPEN))
		return "open";


	LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterCreateOpenOperation: invalid operation type %d\n", OperationType));


	return "all";
}



/*
 * FilterDirectoryOperation()
 *
 * Description:
 *		Convert operations (such as OP_DIR_CREATE) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterDirectoryOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_DIR_CREATE))
		return "create";

	return "all";
}



/*
 * FilterProcessOperation()
 *
 * Description:
 *		Convert operations (such as OP_PROC_OPEN) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterProcessOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_PROC_OPEN) &&
		IS_BIT_SET(OperationType, OP_PROC_EXECUTE))

		return "all";


	if (IS_BIT_SET(OperationType, OP_PROC_OPEN))
		return "open";

	if (IS_BIT_SET(OperationType, OP_PROC_EXECUTE))
		return "execute";


	return "all";
}



/*
 * FilterNetworkOperation()
 *
 * Description:
 *		Convert operations (such as OP_CONNECT) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterNetworkOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_TCPCONNECT))
		return "tcpconnect";

	if (IS_BIT_SET(OperationType, OP_UDPCONNECT))
		return "udpconnect";

	if (IS_BIT_SET(OperationType, OP_CONNECT))
		return "connect";

	if (IS_BIT_SET(OperationType, OP_BIND))
		return "bind";


	LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterNetworkOperation: invalid operation type %d\n", OperationType));


	return "all";
}



/*
 * FilterPortOperation()
 *
 * Description:
 *		Convert port operations (such as OP_PORT_CONNECT) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterPortOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_PORT_CREATE) &&
		IS_BIT_SET(OperationType, OP_PORT_CONNECT))

		return "all";


	if (IS_BIT_SET(OperationType, OP_PORT_CREATE))
		return "create";

	if (IS_BIT_SET(OperationType, OP_PORT_CONNECT))
		return "connect";


	LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterPortOperation: invalid operation type %d\n", OperationType));


	return "all";
}



/*
 * FilterAtomOperation()
 *
 * Description:
 *		Convert atom operations (such as OP_READ, OP_WRITE) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterAtomOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_ADD) &&
		IS_BIT_SET(OperationType, OP_FIND))

		return "all";

	if (IS_BIT_SET(OperationType, OP_ADD))
		return "add";

	if (IS_BIT_SET(OperationType, OP_FIND))
		return "find";


	LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterAtomOperation: invalid operation type %d\n", OperationType));


	return "all";
}



/*
 * FilterDriverOperation()
 *
 * Description:
 *		Convert driver object operations (such as OP_READ, OP_WRITE) into their ASCII representation.
 *
 * Parameters:
 *		OperationType - operation type.
 *
 * Returns:
 *		Pointer to an ASCII string.
 */

PCHAR
FilterDriverOperation(UCHAR OperationType)
{
	if (IS_BIT_SET(OperationType, OP_LOAD))
		return "load";

	if (IS_BIT_SET(OperationType, OP_REGLOAD))
		return "regload";

	LOG(LOG_SS_LEARN, LOG_PRIORITY_DEBUG, ("FilterDriverOperation: invalid operation type %d\n", OperationType));

	return "load";
}


⌨️ 快捷键说明

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