Skip to content
This repository was archived by the owner on Oct 18, 2020. It is now read-only.

Commit 4cdeec0

Browse files
committed
Fixed a bug where Linux task address spaces wouldn't inherit the profile.
Fixed a bug where get_available_addresses in the XEN AS would return MFNs, breaking plugins that depend on it, like memdump. Fixed an issue where phys_addr in Linux profiles would return negative values. BUG= [email protected] Review URL: https://codereview.appspot.com/264190043
1 parent 65b0090 commit 4cdeec0

File tree

2 files changed

+48
-14
lines changed

2 files changed

+48
-14
lines changed

rekall-core/rekall/plugins/addrspaces/amd64.py

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ class XenParaVirtAMD64PagedMemory(AMD64PagedMemory):
325325
def __init__(self, **kwargs):
326326
super(XenParaVirtAMD64PagedMemory, self).__init__(**kwargs)
327327
self.page_offset = self.session.GetParameter("page_offset")
328-
self.m2p_mapping = {}
329328
self._xen_features = None
330329
self.rebuilding_map = False
331330
if self.page_offset:
@@ -386,13 +385,17 @@ def _RebuildM2PMapping(self):
386385
reference.
387386
"""
388387

389-
self.session.logging.debug(
390-
"Rebuilding the machine to physical mapping...")
388+
if self.session.GetParameter("m2p_mapping"):
389+
return
391390

392391
if self.rebuilding_map:
393392
raise RuntimeError("RebuildM2PMapping recursed... aborting.")
394393

395394
self.rebuilding_map = True
395+
396+
self.session.logging.debug(
397+
"Rebuilding the machine to physical mapping...")
398+
396399
try:
397400
p2m_top_location = self.session.profile.get_constant_object(
398401
"p2m_top", "Pointer", vm=self)
@@ -507,9 +510,9 @@ def _RebuildM2PMapping(self):
507510
continue
508511

509512
new_mapping[mfn] = pfn
510-
511-
self.m2p_mapping = new_mapping
512-
self.session.SetCache("mapping", self.m2p_mapping)
513+
self.session.logging.debug("Caching m2p_mapping (%d entries)...",
514+
len(new_mapping))
515+
self.session.SetCache("m2p_mapping", new_mapping)
513516
finally:
514517
self.rebuilding_map = False
515518

@@ -529,13 +532,14 @@ def m2p(self, machine_address):
529532
This translates host physical addresses to guest physical.
530533
Requires a machine to physical mapping to have been calculated.
531534
"""
532-
if not self.m2p_mapping:
535+
m2p_mapping = self.session.GetParameter("m2p_mapping", cached=True)
536+
if not m2p_mapping:
533537
self._RebuildM2PMapping()
534538
machine_address = obj.Pointer.integer_to_address(machine_address)
535539
mfn = machine_address / 0x1000
536-
pfn = self.m2p_mapping.get(mfn)
540+
pfn = m2p_mapping.get(mfn)
537541
if pfn is None:
538-
return 0
542+
return obj.NoneObject("No PFN mapping found for MFN %d" % mfn)
539543
return (pfn * 0x1000) | (0xFFF & machine_address)
540544

541545
def read_pte(self, vaddr, collection=None):
@@ -551,7 +555,7 @@ def read_pte(self, vaddr, collection=None):
551555
def vtop(self, vaddr):
552556
vaddr = obj.Pointer.integer_to_address(vaddr)
553557

554-
if not self.session.GetParameter("mapping"):
558+
if not self.session.GetParameter("m2p_mapping"):
555559
# Simple shortcut for linux. This is required for the first set
556560
# of virtual to physical resolutions while we're building the
557561
# mapping.
@@ -565,3 +569,28 @@ def vtop(self, vaddr):
565569
self._RebuildM2PMapping()
566570

567571
return super(XenParaVirtAMD64PagedMemory, self).vtop(vaddr)
572+
573+
def _get_available_PTEs(self, pte_table, vaddr, start=0):
574+
"""Returns PFNs for each PTE entry."""
575+
tmp3 = vaddr
576+
for i, pte_value in enumerate(pte_table):
577+
# Each of the PTE values has to be translated back to a PFN, since
578+
# they are MFNs.
579+
pte_value = self.m2p(pte_value)
580+
581+
# When no translation was found, we skip the PTE, since we don't
582+
# know where it's pointing to.
583+
if pte_value == None:
584+
continue
585+
586+
if not pte_value & self.valid_mask:
587+
continue
588+
589+
vaddr = tmp3 | i << 12
590+
next_vaddr = tmp3 | ((i + 1) << 12)
591+
if start >= next_vaddr:
592+
continue
593+
594+
yield (vaddr,
595+
(pte_value & 0xffffffffff000) | (vaddr & 0xfff),
596+
0x1000)

rekall-core/rekall/plugins/overlays/linux/linux.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ def get_process_address_space(self):
734734
try:
735735
process_as = self.obj_vm.__class__(
736736
base=self.obj_vm.base, session=self.obj_vm.session,
737-
dtb=directory_table_base)
737+
dtb=directory_table_base, profile=self.obj_profile)
738738

739739
except AssertionError:
740740
return obj.NoneObject("Unable to get process AS")
@@ -1099,9 +1099,14 @@ def phys_addr(self, va):
10991099
phys_addr detects the relocation and returns the correct physical
11001100
address.
11011101
"""
1102-
return (obj.Pointer.integer_to_address(va)
1103-
- obj.Pointer.integer_to_address(self.GetPageOffset())
1104-
+ self.GetRelocationDelta())
1102+
va_addr = obj.Pointer.integer_to_address(va)
1103+
page_offset_addr = obj.Pointer.integer_to_address(
1104+
self.GetPageOffset())
1105+
1106+
if va_addr >= page_offset_addr:
1107+
return (va_addr - page_offset_addr + self.GetRelocationDelta())
1108+
else:
1109+
return obj.NoneObject("Unable to translate VA 0x%x", va)
11051110

11061111
def GetRelocationDelta(self):
11071112
"""Returns the number of bytes the kernel base is shifted."""

0 commit comments

Comments
 (0)