@@ -8,12 +8,11 @@ UINT8 gOslFwpKernelSetupPhase1Backup[sizeof(gHookTemplate)] = { 0 };
8
8
9
9
10
10
// Signature for winload!OslFwpKernelSetupPhase1+XX, where the value of XX needs to be determined by backtracking.
11
- // Windows 10 only. On older OSes, and on Windows 10 as fallback, OslFwpKernelSetupPhase1 is found via xrefs to EfipGetRsdt
11
+ // Windows 10 RS4 and later only. On older OSes, and on Windows 10 as fallback, OslFwpKernelSetupPhase1 is found via xrefs to EfipGetRsdt
12
12
STATIC CONST UINT8 SigOslFwpKernelSetupPhase1 [] = {
13
- 0xE8 , 0xCC , 0xCC , 0xCC , 0xCC , // call BlpArchSwitchContext
14
- 0x48 , 0x8B , 0x05 , 0xCC , 0xCC , 0xCC , 0xCC , // mov rax, gBS
15
- 0xCC , 0x8B , 0xCC , // mov rdx, XX
16
- 0x48 , 0x8B , 0x0D , 0xCC , 0xCC , 0xCC , 0xCC // mov rcx, EfiImageHandle
13
+ 0x89 , 0xCC , 0x24 , 0x01 , 0x00 , 0x00 , // mov [REG+124h], r32
14
+ 0xE8 , 0xCC , 0xCC , 0xCC , 0xCC , // call BlBdStop
15
+ 0xCC , 0x8B , 0xCC // mov r32, r/m32
17
16
};
18
17
19
18
STATIC UNICODE_STRING ImgpFilterValidationFailureMessage = RTL_CONSTANT_STRING (L"*** Windows is unable to verify the signature of" ); // newline, etc etc...
@@ -405,7 +404,7 @@ FindOslFwpKernelSetupPhase1(
405
404
IN PEFI_IMAGE_NT_HEADERS NtHeaders ,
406
405
IN PEFI_IMAGE_SECTION_HEADER CodeSection ,
407
406
IN PEFI_IMAGE_SECTION_HEADER PatternSection ,
408
- IN BOOLEAN TryPatternMatch ,
407
+ IN UINT16 BuildNumber ,
409
408
OUT UINT8 * * OslFwpKernelSetupPhase1Address
410
409
)
411
410
{
@@ -415,9 +414,9 @@ FindOslFwpKernelSetupPhase1(
415
414
CONST UINT32 CodeSizeOfRawData = CodeSection -> SizeOfRawData ;
416
415
CONST UINT8 * PatternStartVa = ImageBase + PatternSection -> VirtualAddress ;
417
416
418
- if (TryPatternMatch )
417
+ if (BuildNumber >= 17134 )
419
418
{
420
- // On Windows 10, try simple pattern matching first since it will most likely work
419
+ // On Windows 10 RS4 and later , try simple pattern matching first since it will most likely work
421
420
UINT8 * Found = NULL ;
422
421
CONST EFI_STATUS Status = FindPattern (SigOslFwpKernelSetupPhase1 ,
423
422
0xCC ,
@@ -437,14 +436,69 @@ FindOslFwpKernelSetupPhase1(
437
436
}
438
437
}
439
438
439
+ // Initialize Zydis
440
+ Print (L"\r\n== Disassembling .text to find OslFwpKernelSetupPhase1 ==\r\n" );
441
+ ZYDIS_CONTEXT Context ;
442
+ ZyanStatus Status = ZydisInit (NtHeaders , & Context );
443
+ if (!ZYAN_SUCCESS (Status ))
444
+ {
445
+ Print (L"Failed to initialize disassembler engine.\r\n" );
446
+ return EFI_LOAD_ERROR ;
447
+ }
448
+
449
+ CONST VOID * BlBdStop = GetProcedureAddress ((UINTN )ImageBase , NtHeaders , "BlBdStop" );
450
+ if (BuildNumber >= 17134 && BlBdStop != NULL )
451
+ {
452
+ Context .Length = CodeSizeOfRawData ;
453
+ Context .Offset = 6 ;
454
+
455
+ // Start decode loop
456
+ while ((Context .InstructionAddress = (ZyanU64 )(CodeStartVa + Context .Offset ),
457
+ Status = ZydisDecoderDecodeFull (& Context .Decoder ,
458
+ (VOID * )Context .InstructionAddress ,
459
+ Context .Length - Context .Offset ,
460
+ & Context .Instruction ,
461
+ Context .Operands )) != ZYDIS_STATUS_NO_MORE_DATA )
462
+ {
463
+ if (!ZYAN_SUCCESS (Status ))
464
+ {
465
+ Context .Offset ++ ;
466
+ continue ;
467
+ }
468
+
469
+ // Check if this is 'call BlBdStop'
470
+ if (Context .Instruction .operand_count == 4 &&
471
+ Context .Operands [0 ].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && Context .Operands [0 ].imm .is_relative == ZYAN_TRUE &&
472
+ Context .Instruction .mnemonic == ZYDIS_MNEMONIC_CALL )
473
+ {
474
+ ZyanU64 OperandAddress = 0 ;
475
+ if (ZYAN_SUCCESS (ZydisCalcAbsoluteAddress (& Context .Instruction , & Context .Operands [0 ], Context .InstructionAddress , & OperandAddress )) &&
476
+ OperandAddress == (UINTN )BlBdStop )
477
+ {
478
+ // Check if the preceding instruction is 'mov [REG+124h], r32'
479
+ CONST UINT8 * CallBlBdStopAddress = (UINT8 * )Context .InstructionAddress ;
480
+ if ((CallBlBdStopAddress [-6 ] == 0x89 || CallBlBdStopAddress [-6 ] == 0x8B ) &&
481
+ * (UINT32 * )(& CallBlBdStopAddress [-4 ]) == 0x124 &&
482
+ (* OslFwpKernelSetupPhase1Address = BacktrackToFunctionStart (ImageBase , NtHeaders , CallBlBdStopAddress )) != NULL )
483
+ {
484
+ Print (L" Found OslFwpKernelSetupPhase1 at 0x%llX.\r\n\r\n" , (UINTN )(* OslFwpKernelSetupPhase1Address ));
485
+ return EFI_SUCCESS ;
486
+ }
487
+ }
488
+ }
489
+
490
+ Context .Offset += Context .Instruction .length ;
491
+ }
492
+ }
493
+
494
+ // On RS4 and later, the previous method really should have worked
495
+ ASSERT (BuildNumber < 17134 );
496
+
440
497
// On older versions, use some convoluted but robust logic to find OslFwpKernelSetupPhase1 by matching xrefs to EfipGetRsdt.
441
498
// This of course implies finding EfipGetRsdt first. After that, find all calls to this function, and for each, calculate
442
499
// the distance from the start of the function to the call. OslFwpKernelSetupPhase1 is reliably (Vista through 10)
443
500
// the function that has the smallest value for this distance, i.e. the call happens very early in the function.
444
- CHAR8 SectionName [EFI_IMAGE_SIZEOF_SHORT_NAME + 1 ];
445
- CopyMem (SectionName , PatternSection -> Name , EFI_IMAGE_SIZEOF_SHORT_NAME );
446
- SectionName [EFI_IMAGE_SIZEOF_SHORT_NAME ] = '\0' ;
447
- Print (L"\r\n== Searching for EfipGetRsdt pattern in %a ==\r\n" , SectionName );
501
+ Print (L"\r\n== Searching for EfipGetRsdt pattern in .text ==\r\n" );
448
502
449
503
// Search for EFI ACPI 2.0 table GUID: { 8868e871-e4f1-11d3-bc22-0080c73c8881 }
450
504
UINT8 * PatternAddress = NULL ;
@@ -468,16 +522,6 @@ FindOslFwpKernelSetupPhase1(
468
522
469
523
Print (L"\r\n== Disassembling .text to find EfipGetRsdt ==\r\n" );
470
524
UINT8 * LeaEfiAcpiTableGuidAddress = NULL ;
471
-
472
- // Initialize Zydis
473
- ZYDIS_CONTEXT Context ;
474
- ZyanStatus Status = ZydisInit (NtHeaders , & Context );
475
- if (!ZYAN_SUCCESS (Status ))
476
- {
477
- Print (L"Failed to initialize disassembler engine.\r\n" );
478
- return EFI_LOAD_ERROR ;
479
- }
480
-
481
525
Context .Length = CodeSizeOfRawData ;
482
526
Context .Offset = 0 ;
483
527
@@ -534,7 +578,6 @@ FindOslFwpKernelSetupPhase1(
534
578
}
535
579
536
580
Print (L" Found EfipGetRsdt at 0x%llX.\r\n" , (UINTN )EfipGetRsdt );
537
- Print (L"\r\n== Disassembling .text to find OslFwpKernelSetupPhase1 ==\r\n" );
538
581
UINT8 * CallEfipGetRsdtAddress = NULL ;
539
582
540
583
// Start decode loop
@@ -673,7 +716,7 @@ PatchWinload(
673
716
NtHeaders ,
674
717
CodeSection ,
675
718
PatternSection ,
676
- BuildNumber >= 10240 ,
719
+ BuildNumber ,
677
720
(UINT8 * * )& gOriginalOslFwpKernelSetupPhase1 );
678
721
if (EFI_ERROR (Status ))
679
722
{
0 commit comments