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

📄 procname.c

📁 臭氧层主动防御系统驱动源代码!臭氧层主动防御系统驱动源代码!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
 *
 * Module Name:
 *
 *		procname.c
 *
 * Abstract:
 *
 *		This module defines various types used by process id to process name conversion routines.
 *
 *		All processes are tracked in a global hash table.
 *		At startup ZwQuerySystemInformation(SystemProcessesAndThreadsInformation..) is used to
 *		enumerate all the existing processes. After that NtCreateProcess() is hooked and used
 *		to keep track of newly created processes while PsSetCreateProcessNotifyRoutine()
 *		callbacks are used to keep track of terminating processes.
 *
 *		See http://www.microsoft.com/msj/0199/nerd/nerd0199.aspx for more info.
 *
 * Author:
 *
 *		Eugene Tsyrklevich 23-Feb-2004
 *
 * Revision History:
 *
 *		07-Apr-2004 ET - Copied from process.h
 */


#include <NTDDK.h>
#include "procname.h"
#include "hookproc.h"
#include "process.h"
#include "policy.h"
#include "sysinfo.h"
#include "learn.h"
#include "misc.h"
#include "log.h"


void	FindProcessNameOffset();


#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, InitProcessNameEntries)
#pragma alloc_text (INIT, FindProcessNameOffset)
#pragma alloc_text (INIT, EnumerateExistingProcesses)
#pragma alloc_text (PAGE, RemoveProcessNameEntries)
#endif


ULONG			SystemProcessId;

/* 67 * 144 = 10 kilobytes */
IMAGE_PID_ENTRY	gImagePidHtbl[IMAGE_PID_HASHTABLE_SIZE];

//XXX investigate KeAcquireInStackQueuedSpinLock
KSPIN_LOCK		gImagePidHtblSpinLock;


/*
 * FindImagePidEntry()
 *
 * Description:
 *		Looks for a process entry in the global process hash table with a specified process id.
 *
 * Parameters:
 *		ProcessId - process id of the process to look for.
 *
 * Returns:
 *		Pointer to a process entry if one is found, NULL otherwise.
 */

PIMAGE_PID_ENTRY
FindImagePidEntry(ULONG ProcessId, ULONG ParentId)
{
	PIMAGE_PID_ENTRY	p;
	KIRQL				irql;


//LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("FindImagePidEntry(%d %d) 1\n", ProcessId, ParentId));
	KeAcquireSpinLock(&gImagePidHtblSpinLock, &irql);
//LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("FindImagePidEntry 2\n"));


	p = gImagePidHtbl[(ULONG) ProcessId % IMAGE_PID_HASHTABLE_SIZE].next;

	while (p)
	{
		if (p->ProcessId == ProcessId)
		{
			if (ParentId == 0 || p->ParentId == ParentId)
			{
				if (ParentId != 0)
				{
					LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("%d FindImagePidEntry(%d, %d) found an entry (%d)\n", CURRENT_PROCESS_PID, ProcessId, ParentId, p->ParentId));
				}

				KeReleaseSpinLock(&gImagePidHtblSpinLock, irql);
				return p;
			}

			LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("%d FindImagePidEntry: ProcessId %d clash. Parent id %d vs %d\n", CURRENT_PROCESS_PID, ProcessId, ParentId, p->ParentId));
		}

		p = p->next;
	}


	KeReleaseSpinLock(&gImagePidHtblSpinLock, irql);


	return NULL;
}



/*
 * ProcessInsertImagePidEntry()
 *
 * Description:
 *		Insert the new process entry into the global process hash table.
 *
 * Parameters:
 *		ProcessId - process id of the new process.
 *		NewProcessEntry - the entry to insert into the hash table.
 *
 * Returns:
 *		TRUE to indicate success, FALSE if failed.
 */

BOOLEAN
ProcessInsertImagePidEntry(ULONG ProcessId, PIMAGE_PID_ENTRY NewProcessEntry)
{
	PIMAGE_PID_ENTRY	p, prev;
	KIRQL				irql;


//LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("ProcessInsertImagePidEntry(%d %x) 1\n", ProcessId, NewProcessEntry));
	KeAcquireSpinLock(&gImagePidHtblSpinLock, &irql);
//LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("ProcessInsertImagePidEntry 2\n"));

	prev = &gImagePidHtbl[(ULONG) ProcessId % IMAGE_PID_HASHTABLE_SIZE];
	p = prev->next;

	while (p)
	{
		// if an entry with our ProcessId already exists, bail out

		if (p->ProcessId == (ULONG) ProcessId)
		{
			LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("%d ProcessInsertImagePidEntry: ProcessId (%d) clash. New image name is '%S' (%d). Old image name is '%S' (%d)\n", CURRENT_PROCESS_PID, ProcessId, NewProcessEntry->ImageName, NewProcessEntry->ParentId, p->ImageName, p->ParentId));

			if (ProcessId != 0)
			{
				KeReleaseSpinLock(&gImagePidHtblSpinLock, irql);
				return FALSE;
			}
		}

		prev = p;
		p = p->next;
	}

	prev->next = NewProcessEntry;


	KeReleaseSpinLock(&gImagePidHtblSpinLock, irql);


	return TRUE;
}



/*
 * CreateNewProcessEntry()
 *
 * Description:
 *		Allocates and initializes a new process entry.
 *
 * Parameters:
 *		ProcessId - process id of the new process.
 *		ProcessName - process image name.
 *
 * Returns:
 *		Pointer to a heap allocated IMAGE_PID_ENTRY structure. NULL if failed.
 */

PIMAGE_PID_ENTRY
CreateNewProcessEntry(ULONG ProcessId, ULONG ParentId, PUNICODE_STRING ProcessName, BOOLEAN NewProcess)
{
	PIMAGE_PID_ENTRY	ProcessEntry;


	ASSERT(ProcessName);


	ProcessEntry = ExAllocatePoolWithTag(NonPagedPool, sizeof(IMAGE_PID_ENTRY) + ProcessName->Length, _POOL_TAG);
	if (ProcessEntry == NULL)
	{
		LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("CreateNewProcessEntry: Out of memory. Forgeting about process %d (%S)", ProcessId, ProcessName->Buffer));
		return NULL;
	}

	RtlZeroMemory(ProcessEntry, sizeof(IMAGE_PID_ENTRY));

	ProcessEntry->ProcessId = ProcessId;
	ProcessEntry->ParentId = ParentId;
	ProcessEntry->FirstThread = NewProcess;

	KeInitializeEvent(&ProcessEntry->UserlandRequestDoneEvent, SynchronizationEvent, FALSE);

	wcscpy(ProcessEntry->ImageName, ProcessName->Buffer);
	ProcessEntry->ImageName[ ProcessName->Length/sizeof(WCHAR) ] = L'\0';

	KeInitializeSpinLock(&ProcessEntry->SecPolicy.SpinLock);


	return ProcessEntry;
}



/*
 * CreateAndLoadNewProcessEntry()
 *
 * Description:
 *		Creates a new process entry and inserts it into the global process hash table.
 *
 * Parameters:
 *		ProcessId - process id of the new process.
 *		ProcessName - process image name.
 *
 * Returns:
 *		Pointer to a heap allocated IMAGE_PID_ENTRY structure. NULL if failed.
 */

PIMAGE_PID_ENTRY
CreateAndLoadNewProcessEntry(ULONG ProcessId, PUNICODE_STRING ProcessName, BOOLEAN NewProcess)
{
	PIMAGE_PID_ENTRY	ProcessEntry;


	ASSERT(ProcessName);


	ProcessEntry = CreateNewProcessEntry(ProcessId, 0, ProcessName, NewProcess);
	if (ProcessEntry == NULL)
		return NULL;


	if (LearningMode == FALSE && FindAndLoadSecurityPolicy(&ProcessEntry->SecPolicy, ProcessName->Buffer, NULL) == FALSE)
	{
		LOG(LOG_SS_PROCESS, LOG_PRIORITY_VERBOSE, ("CreateAndLoadNewProcessEntry: Failed to load security policy for %S\n", ProcessName->Buffer));
	}


	if (ProcessInsertImagePidEntry(ProcessId, ProcessEntry) == FALSE)
	{
		ExFreePoolWithTag(ProcessEntry, _POOL_TAG);
		return NULL;
	}


	return ProcessEntry;
}



/*
 * CreateProcessNotifyProc()
 *
 * Description:
 *		PsSetCreateProcessNotifyRoutine() callback. Used to remove process entries from the global
 *		hashtable of currently running processes. On Windows 2000, this routine also replaces PIDs
 *		of 0 with the real PIDs. This is necessary since win2k does not assign PIDs at a point
 *		where process.c!PostProcessNtCreateProcess() is called.
 *
 *		NOTE: PsSetCreateProcessNotifyRoutine() adds a driver-supplied callback routine to,
 *		or removes it from, a list of routines to be called whenever a process is created or deleted.
 *
 * Parameters:
 *		ParentId - the parent process ID.
 *		ProcessId - process ID that was created / deleted.
 *		Create - indicates whether the process was created (TRUE) or deleted (FALSE).
 *
 * Returns:
 *		Nothing.
 */

VOID
CreateProcessNotifyProc
(
    IN HANDLE  ParentId,
    IN HANDLE  ProcessId,
    IN BOOLEAN  Create
)
{
	PIMAGE_PID_ENTRY	p, prev, tmp;
	ULONG				RequiredPid;
	BOOLEAN				FoundNewProcess = FALSE;
	KIRQL				irql;


	LOG(LOG_SS_PROCESS, LOG_PRIORITY_VERBOSE, ("%d CreateProccessNotifyProc(%d, %d, %d)\n", CURRENT_PROCESS_PID, ParentId, ProcessId, Create));


	/* if the entry is being removed look for ProcessId, otherwise look for 0 */
	RequiredPid = Create == FALSE ? (ULONG) ProcessId : 0;


	/*
	 * find an entry with pid=ProcessId
	 */

	KeAcquireSpinLock(&gImagePidHtblSpinLock, &irql);

	prev = &gImagePidHtbl[(ULONG) RequiredPid % IMAGE_PID_HASHTABLE_SIZE];
	p = prev->next;

	while (p)
	{
		if (p->ProcessId != (ULONG) RequiredPid)
		{
			prev = p;
			p = p->next;
			continue;
		}

		if (p->ParentId != 0 && p->ParentId != (ULONG) ParentId)
		{
			LOG(LOG_SS_PROCESS, LOG_PRIORITY_DEBUG, ("%d CreateProccessNotifyProc(): ProcessId %d collision. %d vs %d\n", CURRENT_PROCESS_PID, p->ProcessId, p->ParentId, ParentId));

			prev = p;
			p = p->next;
			continue;
		}

⌨️ 快捷键说明

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