@@ -78,6 +78,7 @@ AppendKernelPatchMessage(
78
78
VOID
79
79
EFIAPI
80
80
PrintKernelPatchInfo (
81
+ VOID
81
82
)
82
83
{
83
84
ASSERT (gST -> ConOut != NULL );
@@ -101,6 +102,7 @@ PrintKernelPatchInfo(
101
102
BOOLEAN
102
103
EFIAPI
103
104
WaitForKey (
105
+ VOID
104
106
)
105
107
{
106
108
// Hack: because we call this at TPL_NOTIFY in ExitBootServices, we cannot use WaitForEvent()
@@ -339,42 +341,51 @@ ZydisInit(
339
341
UINT8 *
340
342
EFIAPI
341
343
BacktrackToFunctionStart (
342
- IN CONST UINT8 * StartAddress ,
343
- IN CONST UINT8 * LowerBound
344
+ IN CONST UINT8 * ImageBase ,
345
+ IN PEFI_IMAGE_NT_HEADERS NtHeaders ,
346
+ IN CONST UINT8 * AddressInFunction
344
347
)
345
348
{
346
349
// Test for null. This allows callers to do 'FindPattern(..., &Address); X = Backtrack(Address, ...)' with a single failure branch
347
- if (StartAddress == NULL )
350
+ if (AddressInFunction == NULL )
351
+ return NULL ;
352
+ if (NtHeaders -> OptionalHeader .NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION )
348
353
return NULL ;
349
354
350
- ASSERT (StartAddress > LowerBound );
355
+ CONST PRUNTIME_FUNCTION FunctionTable = (PRUNTIME_FUNCTION )(ImageBase + NtHeaders -> OptionalHeader .DataDirectory [EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION ].VirtualAddress );
356
+ CONST UINT32 FunctionTableSize = NtHeaders -> OptionalHeader .DataDirectory [EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION ].Size ;
357
+ if (FunctionTableSize == 0 )
358
+ return NULL ;
351
359
352
- UINT8 * Address ;
353
- BOOLEAN Found = FALSE;
354
- for (Address = (UINT8 * )StartAddress ; Address >= LowerBound ; -- Address )
360
+ // Do a binary search until we find the function that contains our address
361
+ CONST UINT32 RelativeAddress = (UINT32 )(AddressInFunction - ImageBase );
362
+ PRUNTIME_FUNCTION FunctionEntry = NULL ;
363
+ INT32 Low = 0 ;
364
+ INT32 High = (FunctionTableSize / sizeof (RUNTIME_FUNCTION )) - 1 ;
365
+
366
+ while (High >= Low )
355
367
{
356
- if ((* (Address - 1 ) == 0xCC || // Previous byte is int 3 padding, or
357
- (* (Address - 2 ) == 0x90 && * (Address - 1 ) == 0x90 ) || // Previous 2 bytes are nop padding, or
358
- (* (Address - 4 ) == 0x00 && * (Address - 3 ) == 0x00 && // Previous 4+ bytes are 00 padding (rare, only happens at start of a section), or
359
- * (Address - 2 ) == 0x00 && * (Address - 1 ) == 0x00 ) ||
360
- (* (Address - 1 ) == 0xC3 && * (Address - 3 ) != 0x8D ) // Previous byte is 'ret', or
361
- #if defined(MDE_CPU_IA32 ) || defined (_M_IX86 )
362
- || (* (Address - 3 ) == 0xC2 && * (Address - 1 ) == 0x00 ) // Previous 3 bytes are 'ret XX' (x86)
363
- #endif
364
- )
365
- & & // *and*
366
- (* Address == 0x40 || * Address == 0x55 || // Current byte is either 'push [ebp|ebx|rbp|rbx]', 'mov REG, XX' or 'sub REG, XX'
367
- (Address < StartAddress && * Address == 0x44 && * (Address + 1 ) == 0x89 ) ||
368
- (Address < StartAddress && * Address == 0x48 && * (Address + 1 ) == 0x83 ) ||
369
- (Address < StartAddress && * Address == 0x48 && * (Address + 1 ) == 0x89 ) ||
370
- (Address < StartAddress && * Address == 0x48 && * (Address + 1 ) == 0x8B ) ||
371
- (Address < StartAddress && * Address == 0x49 && * (Address + 1 ) == 0x89 ) ||
372
- (Address < StartAddress && * Address == 0x4C && * (Address + 1 ) == 0x8B )))
373
- {
374
- Found = TRUE;
368
+ CONST INT32 Middle = (Low + High ) >> 1 ;
369
+ FunctionEntry = & FunctionTable [Middle ];
370
+
371
+ if (RelativeAddress < FunctionEntry -> BeginAddress )
372
+ High = Middle - 1 ;
373
+ else if (RelativeAddress >= FunctionEntry -> EndAddress )
374
+ Low = Middle + 1 ;
375
+ else
375
376
break ;
377
+ }
378
+
379
+ if (High >= Low )
380
+ {
381
+ // If the function entry specifies indirection, get the address of the master function entry
382
+ if ((FunctionEntry -> u .UnwindData & RUNTIME_FUNCTION_INDIRECT ) != 0 )
383
+ {
384
+ FunctionEntry = (PRUNTIME_FUNCTION )(FunctionEntry -> u .UnwindData + ImageBase - 1 );
376
385
}
386
+
387
+ return (UINT8 * )ImageBase + FunctionEntry -> BeginAddress ;
377
388
}
378
389
379
- return Found ? Address : NULL ;
390
+ return NULL ;
380
391
}
0 commit comments