11#include " Efi.hpp"
2-
3- static void DisablePatchGuard (void * ImageBase, uint64_t ImageSize)
4- {
5- /*
6- nt!KeInitAmd64SpecificState
7- INIT:0000000140A4F601 8B C2 mov eax, edx
8- INIT:0000000140A4F603 99 cdq
9- INIT:0000000140A4F604 41 F7 F8 idiv r8d
10- INIT:0000000140A4F607 89 44 24 30 mov [rsp+28h+arg_0], eax
11- INIT:0000000140A4F60B EB 00 jmp short $+2
12- */
13-
14- auto KeInitAmd64SpecificStateJmp = FIND_PATTERN (ImageBase, ImageSize, " \x8B\xC2\x99\x41\xF7\xF8 " );
15-
16- if (KeInitAmd64SpecificStateJmp != nullptr )
17- {
18- // Prevent the mov from modifying the return address
19- memset (RVA<void *>(KeInitAmd64SpecificStateJmp, 6 ), 0x90 , 4 ); // nop x4
20- }
21- else
22- {
23- Die ();
24- }
25-
26- /*
27- nt!KiSwInterrupt
28- .text:00000001403FD24E FB sti
29- .text:00000001403FD24F 48 8D 4D 80 lea rcx, [rbp+0E8h+var_168]
30- .text:00000001403FD253 E8 E8 C2 FD FF call KiSwInterruptDispatch
31- .text:00000001403FD258 FA cli
32- */
33-
34- auto KiSwInterruptDispatchCall = FIND_PATTERN (ImageBase, ImageSize, " \xFB\x48\x8D\xCC\xCC\xE8\xCC\xCC\xCC\xCC\xFA " );
35-
36- if (KiSwInterruptDispatchCall != nullptr )
37- {
38- // Prevent KiSwInterruptDispatch from being executed
39- memset (KiSwInterruptDispatchCall, 0x90 , 11 ); // nop x11
40- }
41- else
42- {
43- Die ();
44- }
45-
46- // NOTE: EfiGuard has some additional patches, but they do not seem necessary
47- // https://github.com/Mattiwatti/EfiGuard/blob/25bb182026d24944713e36f129a93d08397de913/EfiGuardDxe/PatchNtoskrnl.c#L30-L47
48- }
49-
50- static void DisableDSE (void * ImageBase, uint64_t ImageSize)
51- {
52- /*
53- nt!SepInitializeCodeIntegrity
54- PAGE:0000000140799EBB 4C 8D 05 DE 39 48 00 lea r8, SeCiCallbacks
55- PAGE:0000000140799EC2 8B CF mov ecx, edi
56- PAGE:0000000140799EC4 48 FF 15 95 71 99 FF call cs:__imp_CiInitialize
57- */
58-
59- auto CiInitializeCall = FIND_PATTERN (ImageBase, ImageSize, " \x4C\x8D\x05\xCC\xCC\xCC\xCC\x8B\xCF " );
60-
61- if (CiInitializeCall != nullptr )
62- {
63- // Change CodeIntegrityOptions to zero for CiInitialize call
64- *RVA<uint16_t *>(CiInitializeCall, 7 ) = 0xC931 ; // xor ecx, ecx
65- }
66- else
67- {
68- Die ();
69- }
70-
71- /*
72- nt!SeValidateImageData
73- PAGE:00000001406EBD15 loc_1406EBD15:
74- PAGE:00000001406EBD15 48 83 C4 48 add rsp, 48h
75- PAGE:00000001406EBD19 C3 retn
76- PAGE:00000001406EBD1A CC db 0CCh
77- PAGE:00000001406EBD1B loc_1406EBD1B:
78- PAGE:00000001406EBD1B B8 28 04 00 C0 mov eax, 0C0000428h
79- PAGE:00000001406EBD20 EB F3 jmp short loc_1406EBD15
80- PAGE:00000001406EBD20 SeValidateImageData endp
81- */
82-
83- auto SeValidateImageDataRet = FIND_PATTERN (ImageBase, ImageSize, " \x48\x83\xC4\x48\xC3\xCC\xB8\x28\x04\x00\xC0 " );
84-
85- if (SeValidateImageDataRet != nullptr )
86- {
87- // Ensure SeValidateImageData returns a success status
88- *RVA<uint32_t *>(SeValidateImageDataRet, 7 ) = 0 ; // mov eax, 0
89- }
90- else
91- {
92- Die ();
93- }
94- }
95-
96- static void HookNtoskrnl (void * ImageBase, uint64_t ImageSize)
97- {
98- DisablePatchGuard (ImageBase, ImageSize);
99- DisableDSE (ImageBase, ImageSize);
100- }
2+ #include " PatchNtoskrnl.hpp"
1013
1024static bool IsNtoskrnl (const wchar_t * ImageName)
1035{
@@ -127,10 +29,10 @@ static EFI_STATUS BlImgLoadPEImageExHook(void* a1, void* a2, wchar_t* LoadFile,
12729
12830 DetourCreate (BlImgLoadPEImageEx, BlImgLoadPEImageExHook, BlImgLoadPEImageExOriginal);
12931
130- // Check if loaded file is ntoskrnl and hook it
32+ // Check if loaded file is ntoskrnl and patch it
13133 if (!EFI_ERROR (Status) && IsNtoskrnl (LoadFile))
13234 {
133- HookNtoskrnl (*ImageBase, *ImageSize);
35+ PatchNtoskrnl (*ImageBase, *ImageSize);
13436 }
13537
13638 return Status;
@@ -184,39 +86,24 @@ static void PatchSelfIntegrity(void* ImageBase, uint64_t ImageSize)
18486 .text:000000001002AE76 33 FF xor edi, edi
18587 .text:000000001002AE78 48 83 65 C8 00 and qword ptr [rbp+Device.Type], 0
18688 .text:000000001002AE7D 48 83 65 48 00 and [rbp+arg_10], 0
187- We try to find this first :
89+ We try to find this:
18890 .text:000000001002AE82 83 4D 38 FF or [rbp+arg_0], 0FFFFFFFFh
18991 .text:000000001002AE86 83 4D 40 FF or [rbp+a1], 0FFFFFFFFh
19092 */
191-
19293 auto VerifySelfIntegrityMid = FIND_PATTERN (ImageBase, ImageSize, " \x83\x4D\xCC\xFF\x83\x4D\xCC\xFF " );
193- if (VerifySelfIntegrityMid != nullptr )
194- {
195- // Find the function start (NOTE: would be cleaner to use the RUNTIME_FUNCTION in the exception directory)
196- // mov [rsp+8], ecx
197- constexpr auto WalkBack = 0x30 ;
198- auto BmFwVerifySelfIntegrity = FIND_PATTERN (VerifySelfIntegrityMid - WalkBack, WalkBack, " \x89\x4C\x24\x08 " );
199- if (BmFwVerifySelfIntegrity != nullptr )
200- {
201- memcpy (BmFwVerifySelfIntegrity, " \x33\xC0\xC3 " , 3 ); // xor eax, eax; ret
202- }
203- else
204- {
205- Die ();
206- }
207- }
208- else
209- {
210- Die ();
211- }
94+ ASSERT (VerifySelfIntegrityMid != nullptr );
95+
96+ auto BmFwVerifySelfIntegrity = FindFunctionStart (ImageBase, VerifySelfIntegrityMid);
97+ ASSERT (BmFwVerifySelfIntegrity != nullptr );
98+
99+ PatchReturn0 (BmFwVerifySelfIntegrity);
212100}
213101
214102static EFI_STATUS LoadBootManager ()
215103{
216104 // Query bootmgfw from the filesystem
217105 EFI_DEVICE_PATH* BootmgfwPath = nullptr ;
218106 auto Status = EfiQueryDevicePath (L" \\ EFI\\ Microsoft\\ Boot\\ bootmgfw.efi" , &BootmgfwPath);
219-
220107 if (EFI_ERROR (Status))
221108 {
222109 return Status;
@@ -226,7 +113,6 @@ static EFI_STATUS LoadBootManager()
226113 EFI_HANDLE BootmgfwHandle = nullptr ;
227114 Status = gBS ->LoadImage (TRUE , gImageHandle , BootmgfwPath, nullptr , 0 , &BootmgfwHandle);
228115 gBS ->FreePool (BootmgfwPath);
229-
230116 if (EFI_ERROR (Status))
231117 {
232118 return Status;
@@ -237,7 +123,6 @@ static EFI_STATUS LoadBootManager()
237123
238124 // Start the boot manager
239125 Status = gBS ->StartImage (BootmgfwHandle, nullptr , nullptr );
240-
241126 if (EFI_ERROR (Status))
242127 {
243128 gBS ->UnloadImage (BootmgfwHandle);
0 commit comments