mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-09-12 20:57:39 +02:00
Merge pull request #1581 from volatilityfoundation/issues/issue1580
Layers: Make the low-stub method less brittle
This commit is contained in:
@@ -392,38 +392,42 @@ class KernelPDBScanner(interfaces.automagic.AutomagicInterface):
|
||||
# Try locating kernel base via x64 Low Stub in lower 1MB starting from second page (4KB)
|
||||
# If "Discard Low Memory" setting is disabled in BIOS, the Low Stub may be at the third/fourth or further pages
|
||||
for offset in range(0x1000, 0x100000, 0x1000):
|
||||
jmp_and_completion_values = int.from_bytes(
|
||||
physical_layer.read(offset, 0x8), "little"
|
||||
)
|
||||
if (
|
||||
0xFFFFFFFFFFFF00FF & jmp_and_completion_values
|
||||
!= constants.windows.JMP_AND_COMPLETION_SIGNATURE
|
||||
):
|
||||
continue
|
||||
cr3_value = int.from_bytes(
|
||||
physical_layer.read(
|
||||
offset + constants.windows.PROCESSOR_START_BLOCK_CR3_OFFSET, 0x8
|
||||
),
|
||||
"little",
|
||||
)
|
||||
try:
|
||||
jmp_and_completion_values = int.from_bytes(
|
||||
physical_layer.read(offset, 0x8), "little"
|
||||
)
|
||||
if (
|
||||
0xFFFFFFFFFFFF00FF & jmp_and_completion_values
|
||||
!= constants.windows.JMP_AND_COMPLETION_SIGNATURE
|
||||
):
|
||||
continue
|
||||
cr3_value = int.from_bytes(
|
||||
physical_layer.read(
|
||||
offset + constants.windows.PROCESSOR_START_BLOCK_CR3_OFFSET, 0x8
|
||||
),
|
||||
"little",
|
||||
)
|
||||
|
||||
# Compare previously observed valid page table address that's stored in vlayer._initial_entry
|
||||
# with PROCESSOR_START_BLOCK->ProcessorState->SpecialRegisters->Cr3
|
||||
# which was observed to be an invalid page address, so add 1 (to make it valid too)
|
||||
if (cr3_value + 1) != vlayer._initial_entry:
|
||||
# Compare previously observed valid page table address that's stored in vlayer._initial_entry
|
||||
# with PROCESSOR_START_BLOCK->ProcessorState->SpecialRegisters->Cr3
|
||||
# which was observed to be an invalid page address, so add 1 (to make it valid too)
|
||||
if (cr3_value + 1) != vlayer._initial_entry:
|
||||
continue
|
||||
potential_kernel_hint = int.from_bytes(
|
||||
physical_layer.read(
|
||||
offset
|
||||
+ constants.windows.PROCESSOR_START_BLOCK_LM_TARGET_OFFSET,
|
||||
0x8,
|
||||
),
|
||||
"little",
|
||||
)
|
||||
if 0x3 & potential_kernel_hint:
|
||||
continue
|
||||
kernel_hint = potential_kernel_hint & 0xFFFFFFFFFFFF
|
||||
kernel_base = kernel_hint & (~0x1FFFFF) & 0xFFFFFFFFFFFF
|
||||
break
|
||||
except exceptions.InvalidAddressException:
|
||||
continue
|
||||
potential_kernel_hint = int.from_bytes(
|
||||
physical_layer.read(
|
||||
offset + constants.windows.PROCESSOR_START_BLOCK_LM_TARGET_OFFSET,
|
||||
0x8,
|
||||
),
|
||||
"little",
|
||||
)
|
||||
if 0x3 & potential_kernel_hint:
|
||||
continue
|
||||
kernel_hint = potential_kernel_hint & 0xFFFFFFFFFFFF
|
||||
kernel_base = kernel_hint & (~0x1FFFFF) & 0xFFFFFFFFFFFF
|
||||
break
|
||||
|
||||
if kernel_base:
|
||||
# Scanning 32mb in 2mb chunks for the 'ntoskrnl' base address
|
||||
|
||||
Reference in New Issue
Block a user