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

📄 hookproc.c

📁 臭氧层主动防御系统驱动源代码!臭氧层主动防御系统驱动源代码!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Copyright (c) 2004 Security Architects Corporation. All rights reserved.
 *
 * Module Name:
 *
 *		hookproc.c
 *
 * Abstract:
 *
 *		This module implements various service operation (system call) hooking routines.
 *
 *		Since not all the Zw* services are exported, we use a hack to find the required information.
 *		ntdll.dll contains stubs for calling all the system services. All stubs start with
 *		"mov eax, function_index" instruction where function_index is an index into a global
 *		system call table. By parsing ntdll.dll and extracting all the function indeces
 *		we can map all the Zw* names to their appropriate system call table indeces.
 *
 * Author:
 *
 *		Eugene Tsyrklevich 16-Feb-2004
 *
 * Revision History:
 *
 *		None.
 */

#include <NTDDK.h>
#include "hookproc.h"
#include "sysinfo.h"
#include "ntproto.h"
#include "learn.h"
#include "file.h"
#include "registry.h"
#include "section.h"
#include "sysinfo.h"
#include "semaphore.h"
#include "dirobj.h"
#include "symlink.h"
#include "mutant.h"
#include "event.h"
#include "port.h"
#include "job.h"
#include "token.h"
#include "timer.h"
#include "driverobj.h"
#include "process.h"
#include "procname.h"
#include "time.h"
#include "atom.h"
#include "vdm.h"
#include "debug.h"
#include "i386.h"
#include "misc.h"
#include "log.h"


#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, InitSyscallsHooks)
#pragma alloc_text (INIT, InstallSyscallsHooks)
#pragma alloc_text (PAGE, RemoveSyscallsHooks)
#endif


#if DBG
int		HookedRoutineRunning = 0;
#endif

PCHAR	NTDLL_Base;

int ZwCallsNumber = 0;



/*
 * FindFunctionOffset()
 *
 * Description:
 *		Finds a Zw* system call offset in a system service table.
 *
 *		Implementation of all the Zw* system services (such as ZwOpenFile or ZwCreateProcess())
 *		start with a "mov eax, function_offset" instruction. Function offset is extracted from
 *		the first instruction.
 *
 * Parameters:
 *		Function - Pointer to the function code.
 *
 * Returns:
 *		Integer function offset (-1 in case of a failure).
 */

/* "MOV EAX,IMM32" opcode */
#define	OPCODE_MOV	0xB8

/* macro shortcut for bailing out of FindFunctionOffset in case of an error */

#define	ABORT_FindFunctionOffset(msg) {																\
		LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Error occured in FindFunctionOffset():"));		\
		LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, msg);												\
		return -1;																					\
	}

int
FindFunctionOffset(PULONG_PTR Function)
{
	PUCHAR		Instruction;
	ULONG		num, ServiceIDNumber, ServiceTableIndex;


	/*
	 * Make sure that the service code starts with a MOV EAX,IMM32 instruction:
	 *
	 * lkd> u ZwCreateFile
	 * nt!ZwCreateFile:
	 * 804f86f4 b825000000       mov     eax,0x25
	 */

	Instruction = (PUCHAR) Function;

	if (*Instruction != OPCODE_MOV)

		ABORT_FindFunctionOffset(("Invalid opcode %x\n", *Instruction));


	/*
	 * Extract the Service Descriptor Table index (4 bytes following the mov opcode)
	 *
	 * The index format is as follows:
	 *
	 * Leading 18 bits are all zeroes
	 * Following 2 bits are system service table index (3 bits on Win64)
	 * Following 12 bits are service number
	 */

	num = * (PULONG) ++Instruction;


	/* only SERVICE_TABLE_INDEX_BITS LSB bits should be set */

	ServiceTableIndex = num >> SERVICE_ID_NUMBER_BITS;

	if (ServiceTableIndex >= NUMBER_SERVICE_TABLES)

		ABORT_FindFunctionOffset(("Invalid SSDT index: %x (%x)\n", ServiceTableIndex, num));


	/* XXX temporary? There exist 4 (8 on IA64) service tables. All the Zw* system services are in table 0 */
	if (ServiceTableIndex != 0)

		ABORT_FindFunctionOffset(("Invalid SSDT index2: %x (%x)\n", ServiceTableIndex, num));


	/* Verify Service ID Number is in range */

	ServiceIDNumber = num & SERVICE_ID_NUMBER_MASK;

//XXX shouldn't we be using the shadow table instead??
//shadow table Zw* base address is the same in addition to GUI table
	if (ServiceIDNumber > KeServiceDescriptorTable[ServiceTableIndex].NumberOfServices)

		ABORT_FindFunctionOffset(("Invalid service id number %d (max is %d)\n", ServiceIDNumber, KeServiceDescriptorTable[ServiceTableIndex].NumberOfServices));


	return ServiceIDNumber;
}



#if 0

/*
 * HookSystemService()
 *
 * Description:
 *		Replaces an existing sytem service pointer (n a global system service table) with another function pointer.
 *
 * Parameters:
 *		OldService - Pointer to the service code to mediate.
 *		NewService - Pointer to the new function code.
 *
 * Returns:
 *		Current OldService indexed system service function pointer.
 */

/* macro shortcut for bailing out of HookSystemService in case of an error */

#define	ABORT_HookSystemService(msg) {																\
		LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Error occured in HookSystemService():"));		\
		LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, (msg));											\
		return NULL;																				\
	}

PVOID
HookSystemService(PVOID OldService, PVOID NewService)
{
	PULONG_PTR	ssdt;
	PULONG_PTR	retptr = NULL;
	ULONG		ServiceIDNumber;


	if (OldService == NULL || NewService == NULL)

		ABORT_HookSystemService(("NULL detected. OldService=%x NewService=%x", OldService, NewService));


	ServiceIDNumber = FindFunctionOffset(OldService);

	if (ServiceIDNumber == -1)

		ABORT_HookSystemService(("FindFunctionOffset(%x) failed", OldService));


	ssdt = KeServiceDescriptorTable[0].ServiceTableBase;


	retptr = (PULONG_PTR) ssdt[ServiceIDNumber];

	if (retptr == NULL)

		ABORT_HookSystemService(("ssdt[index] = NULL\n"));


	if (((ULONG) retptr & SystemAddressStart) == 0)

		ABORT_HookSystemService(("invalid code instruction specified\n"));


	retptr = ExchangeReadOnlyMemoryPointer((PVOID *) &ssdt[ServiceIDNumber], NewService);


	return retptr;
}

#endif



/*
 * HookSystemServiceByIndex()
 *
 * Description:
 *		Replaces an existing sytem service (n a global system service table) with another function pointer.
 *
 * Parameters:
 *		ServiceIDNumber - Index of a system service to mediate.
 *		NewService - Pointer to the new function code.
 *
 * Returns:
 *		Current ServiceIDNumber indexed system service function pointer.
 */

/* macro shortcut for bailing out of HookSystemServiceByIndex in case of an error */

#define	ABORT_HookSystemServiceByIndex(msg) {															\
		LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Error occured in HookSystemServiceByIndex():"));		\
		LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, msg);													\
		return NULL;																					\
	}

PVOID
HookSystemServiceByIndex(ULONG ServiceIDNumber, PVOID NewService)
{
	PULONG_PTR	ssdt;
	PULONG_PTR	retptr = NULL;
	ULONG		ServiceTableIndex = 0;


	ssdt = KeServiceDescriptorTable[ServiceTableIndex].ServiceTableBase;


	/* Verify Service ID Number is in range */

//XXX shouldn't we be using the shadow table instead??
	if (ServiceIDNumber > KeServiceDescriptorTable[ServiceTableIndex].NumberOfServices)

		ABORT_HookSystemServiceByIndex(("Invalid service id number %d (max is %d)\n", ServiceIDNumber, KeServiceDescriptorTable[ServiceTableIndex].NumberOfServices));


	retptr = (PULONG_PTR) ssdt[ServiceIDNumber];

	if (retptr == NULL)

		ABORT_HookSystemServiceByIndex(("ssdt[index] = NULL\n"));


	if (((ULONG) retptr & SystemAddressStart) == 0)

		ABORT_HookSystemServiceByIndex(("invalid code instruction specified\n"));

	
	retptr = ExchangeReadOnlyMemoryPointer((PVOID *) &ssdt[ServiceIDNumber], NewService);


	return retptr;
}


#if 0
/*
 * FindSystemServiceByIndex()
 *
 * Description:XXX
 *		Replaces an existing sytem service (n a global system service table) with another function pointer.
 *
 * Parameters:
 *		ServiceIDNumber - Index of a system service to mediate.
 *		NewService - Pointer to the new function code.
 *
 * Returns:
 *		Current ServiceIDNumber indexed system service function pointer.
 */

/* macro shortcut for bailing out of HookSystemServiceByIndex in case of an error */

#define	ABORT_FindSystemServiceByIndex(msg) { LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, ("Error occured in FindSystemServiceByIndex():")); LOG(LOG_SS_HOOKPROC, LOG_PRIORITY_DEBUG, msg); return NULL; }

PULONG
FindSystemServiceByIndex(ULONG ServiceIDNumber)
{
	PULONG_PTR	ssdt;
	PULONG_PTR	retptr = NULL;
	ULONG		ServiceTableIndex = 0;


	ssdt = KeServiceDescriptorTable[ServiceTableIndex].ServiceTableBase;


	/* Verify Service ID Number is in range */

//XXX shouldn't we be using the shadow table instead??
	if (ServiceIDNumber > KeServiceDescriptorTable[ServiceTableIndex].NumberOfServices)

		ABORT_FindSystemServiceByIndex(("Invalid service id number %d (max is %d)\n", ServiceIDNumber, KeServiceDescriptorTable[ServiceTableIndex].NumberOfServices));


	retptr = (PULONG_PTR) ssdt[ServiceIDNumber];

	if (retptr == NULL)

		ABORT_FindSystemServiceByIndex(("ssdt[index] = NULL\n"));


	if (((ULONG) retptr & SystemAddressStart) == 0)

		ABORT_FindSystemServiceByIndex(("invalid code instruction specified\n"));


	return (PULONG) ssdt[ServiceIDNumber];
}
#endif


/*
 * HookSystemServiceByName()
 *
 * Description:
 *		Replaces an existing sytem service (n a global system service table) with another function pointer.
 *
 * Parameters:
 *		ServiceName - Name of a Zw* system service to mediate.
 *		HookFunction - Pointer to the mediator function code.

⌨️ 快捷键说明

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