|
|
|
@ -26,6 +26,8 @@ import pwndbg.lib.kernel.kconfig
|
|
|
|
import pwndbg.lib.kernel.structs
|
|
|
|
import pwndbg.lib.kernel.structs
|
|
|
|
import pwndbg.lib.memory
|
|
|
|
import pwndbg.lib.memory
|
|
|
|
import pwndbg.search
|
|
|
|
import pwndbg.search
|
|
|
|
|
|
|
|
from pwndbg.aglib.kernel.paging import ArchPagingInfo
|
|
|
|
|
|
|
|
from pwndbg.lib.regs import BitFlags
|
|
|
|
|
|
|
|
|
|
|
|
_kconfig: pwndbg.lib.kernel.kconfig.Kconfig | None = None
|
|
|
|
_kconfig: pwndbg.lib.kernel.kconfig.Kconfig | None = None
|
|
|
|
|
|
|
|
|
|
|
|
@ -116,7 +118,7 @@ def get_first_kernel_ro() -> pwndbg.lib.memory.Page | None:
|
|
|
|
if base is None:
|
|
|
|
if base is None:
|
|
|
|
return None
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
for mapping in pwndbg.aglib.vmmap.get():
|
|
|
|
for mapping in pwndbg.aglib.kernel.paging.get_memory_map_raw():
|
|
|
|
if mapping.vaddr < base:
|
|
|
|
if mapping.vaddr < base:
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
@ -200,11 +202,6 @@ def is_kaslr_enabled() -> bool:
|
|
|
|
return "nokaslr" not in kcmdline()
|
|
|
|
return "nokaslr" not in kcmdline()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pwndbg.lib.cache.cache_until("start")
|
|
|
|
|
|
|
|
def kbase() -> int | None:
|
|
|
|
|
|
|
|
return pwndbg.aglib.kernel.paging.kbase()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_idt_entries() -> List[pwndbg.lib.kernel.structs.IDTEntry]:
|
|
|
|
def get_idt_entries() -> List[pwndbg.lib.kernel.structs.IDTEntry]:
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
Retrieves the IDT entries from memory.
|
|
|
|
Retrieves the IDT entries from memory.
|
|
|
|
@ -234,10 +231,6 @@ class ArchOps(ABC):
|
|
|
|
# use through kernel configuration, enabling support for additional models
|
|
|
|
# use through kernel configuration, enabling support for additional models
|
|
|
|
# in the page_to_pfn() and pfn_to_page() methods in the future.
|
|
|
|
# in the page_to_pfn() and pfn_to_page() methods in the future.
|
|
|
|
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
|
|
|
|
def page_size(self) -> int:
|
|
|
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
@abstractmethod
|
|
|
|
def per_cpu(self, addr: pwndbg.dbg_mod.Value, cpu=None) -> pwndbg.dbg_mod.Value:
|
|
|
|
def per_cpu(self, addr: pwndbg.dbg_mod.Value, cpu=None) -> pwndbg.dbg_mod.Value:
|
|
|
|
raise NotImplementedError()
|
|
|
|
raise NotImplementedError()
|
|
|
|
@ -266,10 +259,40 @@ class ArchOps(ABC):
|
|
|
|
def page_to_pfn(self, page: int) -> int:
|
|
|
|
def page_to_pfn(self, page: int) -> int:
|
|
|
|
raise NotImplementedError()
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
@pwndbg.lib.cache.cache_until("start")
|
|
|
|
|
|
|
|
def STRUCT_PAGE_SIZE(self):
|
|
|
|
|
|
|
|
return arch_paginginfo().STRUCT_PAGE_SIZE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
@pwndbg.lib.cache.cache_until("start")
|
|
|
|
|
|
|
|
def STRUCT_PAGE_SHIFT(self):
|
|
|
|
|
|
|
|
return arch_paginginfo().STRUCT_PAGE_SHIFT
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@property
|
|
|
|
def page_offset(self) -> int:
|
|
|
|
def page_offset(self) -> int:
|
|
|
|
|
|
|
|
return arch_paginginfo().physmap
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def page_shift(self) -> int:
|
|
|
|
|
|
|
|
return arch_paginginfo().page_shift
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def vmemmap(self) -> int:
|
|
|
|
|
|
|
|
return arch_paginginfo().vmemmap
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def kbase(self) -> int:
|
|
|
|
|
|
|
|
return arch_paginginfo().kbase
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def ptr_size(self) -> int:
|
|
|
|
raise NotImplementedError()
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def page_size(self) -> int:
|
|
|
|
|
|
|
|
return 1 << self.page_shift
|
|
|
|
|
|
|
|
|
|
|
|
def virt_to_pfn(self, virt: int) -> int:
|
|
|
|
def virt_to_pfn(self, virt: int) -> int:
|
|
|
|
return phys_to_pfn(virt_to_phys(virt))
|
|
|
|
return phys_to_pfn(virt_to_phys(virt))
|
|
|
|
|
|
|
|
|
|
|
|
@ -293,9 +316,6 @@ class ArchOps(ABC):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class x86Ops(ArchOps):
|
|
|
|
class x86Ops(ArchOps):
|
|
|
|
def page_size(self) -> int:
|
|
|
|
|
|
|
|
return 1 << self.page_shift
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def phys_to_virt(self, phys: int) -> int:
|
|
|
|
def phys_to_virt(self, phys: int) -> int:
|
|
|
|
return (phys + self.page_offset) % (1 << self.ptr_size)
|
|
|
|
return (phys + self.page_offset) % (1 << self.ptr_size)
|
|
|
|
|
|
|
|
|
|
|
|
@ -310,41 +330,16 @@ class x86Ops(ArchOps):
|
|
|
|
def ptr_size(self) -> int:
|
|
|
|
def ptr_size(self) -> int:
|
|
|
|
raise NotImplementedError()
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
|
|
|
|
def page_shift(self) -> int:
|
|
|
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
|
|
|
|
def page_offset(self) -> int:
|
|
|
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
@staticmethod
|
|
|
|
def paging_enabled() -> bool:
|
|
|
|
def paging_enabled() -> bool:
|
|
|
|
return int(pwndbg.aglib.regs.cr0) & BIT(31) != 0
|
|
|
|
return int(pwndbg.aglib.regs.cr0) & BIT(31) != 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class i386Ops(x86Ops):
|
|
|
|
class i386Ops(x86Ops):
|
|
|
|
@requires_kconfig()
|
|
|
|
|
|
|
|
def __init__(self) -> None:
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/page_32_types.h#L18
|
|
|
|
|
|
|
|
self._PAGE_OFFSET = int(kconfig()["CONFIG_PAGE_OFFSET"], 16)
|
|
|
|
|
|
|
|
self.START_KERNEL_map = self._PAGE_OFFSET
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@property
|
|
|
|
def ptr_size(self) -> int:
|
|
|
|
def ptr_size(self) -> int:
|
|
|
|
return 32
|
|
|
|
return 32
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def page_offset(self) -> int:
|
|
|
|
|
|
|
|
return self._PAGE_OFFSET
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def page_shift(self) -> int:
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/page_types.h#L10
|
|
|
|
|
|
|
|
return 12
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def virt_to_phys(self, virt: int) -> int:
|
|
|
|
def virt_to_phys(self, virt: int) -> int:
|
|
|
|
return (virt - self.page_offset) % (1 << 32)
|
|
|
|
return (virt - self.page_offset) % (1 << 32)
|
|
|
|
|
|
|
|
|
|
|
|
@ -360,51 +355,12 @@ class i386Ops(x86Ops):
|
|
|
|
|
|
|
|
|
|
|
|
class x86_64Ops(x86Ops):
|
|
|
|
class x86_64Ops(x86Ops):
|
|
|
|
def __init__(self) -> None:
|
|
|
|
def __init__(self) -> None:
|
|
|
|
self.STRUCT_PAGE_SIZE = pwndbg.aglib.typeinfo.load("struct page").sizeof
|
|
|
|
|
|
|
|
self.STRUCT_PAGE_SHIFT = int(math.log2(self.STRUCT_PAGE_SIZE))
|
|
|
|
|
|
|
|
self.phys_base = 0x1000000
|
|
|
|
self.phys_base = 0x1000000
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
self.START_KERNEL_map = pwndbg.aglib.kernel.kbase()
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
|
|
|
|
print("WARNING: an error ocurred when retrieving kbase")
|
|
|
|
|
|
|
|
self.START_KERNEL_map = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.START_KERNEL_map is None:
|
|
|
|
|
|
|
|
# put this here in case kbase also returns None
|
|
|
|
|
|
|
|
self.START_KERNEL_map = 0xFFFFFFFF80000000
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if pwndbg.aglib.kernel.has_debug_syms():
|
|
|
|
|
|
|
|
# if there are debug symbols
|
|
|
|
|
|
|
|
self._PAGE_OFFSET = pwndbg.aglib.kernel.paging.physmap_base()
|
|
|
|
|
|
|
|
self.VMEMMAP_START = pwndbg.aglib.symbol.lookup_symbol_value("vmemmap_base")
|
|
|
|
|
|
|
|
if self._PAGE_OFFSET is not None and self.VMEMMAP_START is not None:
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.uses_5lvl_paging():
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/page_64_types.h#L41
|
|
|
|
|
|
|
|
self._PAGE_OFFSET = 0xFF11000000000000
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/pgtable_64_types.h#L131
|
|
|
|
|
|
|
|
self.VMEMMAP_START = 0xFFD4000000000000
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/page_64_types.h#L42
|
|
|
|
|
|
|
|
self._PAGE_OFFSET = 0xFFFF888000000000
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/pgtable_64_types.h#L130
|
|
|
|
|
|
|
|
self.VMEMMAP_START = 0xFFFFEA0000000000
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@property
|
|
|
|
def ptr_size(self) -> int:
|
|
|
|
def ptr_size(self) -> int:
|
|
|
|
return 64
|
|
|
|
return 64
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def page_offset(self) -> int:
|
|
|
|
|
|
|
|
return self._PAGE_OFFSET
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
|
|
|
def page_shift(self) -> int:
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/page_64_types.h#L50
|
|
|
|
|
|
|
|
return 12
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@requires_debug_syms()
|
|
|
|
@requires_debug_syms()
|
|
|
|
def per_cpu(self, addr: pwndbg.dbg_mod.Value, cpu: int | None = None) -> pwndbg.dbg_mod.Value:
|
|
|
|
def per_cpu(self, addr: pwndbg.dbg_mod.Value, cpu: int | None = None) -> pwndbg.dbg_mod.Value:
|
|
|
|
if cpu is None:
|
|
|
|
if cpu is None:
|
|
|
|
@ -418,78 +374,25 @@ class x86_64Ops(x86Ops):
|
|
|
|
return pwndbg.dbg.selected_inferior().create_value(per_cpu_addr, addr.type)
|
|
|
|
return pwndbg.dbg.selected_inferior().create_value(per_cpu_addr, addr.type)
|
|
|
|
|
|
|
|
|
|
|
|
def virt_to_phys(self, virt: int) -> int:
|
|
|
|
def virt_to_phys(self, virt: int) -> int:
|
|
|
|
if virt < self.START_KERNEL_map:
|
|
|
|
if virt < self.kbase:
|
|
|
|
return (virt - self.page_offset) % (1 << 64)
|
|
|
|
return (virt - self.page_offset) % (1 << 64)
|
|
|
|
return ((virt - self.START_KERNEL_map) + self.phys_base) % (1 << 64)
|
|
|
|
return ((virt - self.kbase) + self.phys_base) % (1 << 64)
|
|
|
|
|
|
|
|
|
|
|
|
def pfn_to_page(self, pfn: int) -> int:
|
|
|
|
def pfn_to_page(self, pfn: int) -> int:
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
return (pfn << self.STRUCT_PAGE_SHIFT) + self.VMEMMAP_START
|
|
|
|
return (pfn << self.STRUCT_PAGE_SHIFT) + self.vmemmap
|
|
|
|
|
|
|
|
|
|
|
|
def page_to_pfn(self, page: int) -> int:
|
|
|
|
def page_to_pfn(self, page: int) -> int:
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
return (page - self.VMEMMAP_START) >> self.STRUCT_PAGE_SHIFT
|
|
|
|
return (page - self.vmemmap) >> self.STRUCT_PAGE_SHIFT
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
|
|
|
@requires_debug_syms()
|
|
|
|
|
|
|
|
def cpu_feature_capability(feature: int) -> bool:
|
|
|
|
|
|
|
|
boot_cpu_data = pwndbg.aglib.symbol.lookup_symbol("boot_cpu_data")
|
|
|
|
|
|
|
|
assert boot_cpu_data is not None, "Symbol boot_cpu_data not exists"
|
|
|
|
|
|
|
|
boot_cpu_data = boot_cpu_data.dereference()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
capabilities = boot_cpu_data["x86_capability"]
|
|
|
|
|
|
|
|
return (int(capabilities[feature // 32]) >> (feature % 32)) & 1 == 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
|
|
|
@requires_debug_syms()
|
|
|
|
|
|
|
|
def uses_5lvl_paging() -> bool:
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v6.2/source/arch/x86/include/asm/cpufeatures.h#L381
|
|
|
|
|
|
|
|
X86_FEATURE_LA57 = 16 * 32 + 16
|
|
|
|
|
|
|
|
# Separate to avoid using kconfig if possible
|
|
|
|
|
|
|
|
if not x86_64Ops.cpu_feature_capability(X86_FEATURE_LA57) or "no5lvl" in kcmdline():
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
return x86_64Ops._kconfig_5lvl_paging()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
|
|
|
@requires_kconfig()
|
|
|
|
|
|
|
|
def _kconfig_5lvl_paging() -> bool:
|
|
|
|
|
|
|
|
return kconfig().get("CONFIG_X86_5LEVEL") == "y"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Aarch64Ops(ArchOps):
|
|
|
|
class Aarch64Ops(ArchOps):
|
|
|
|
@requires_kconfig(default={})
|
|
|
|
@property
|
|
|
|
def __init__(self) -> None:
|
|
|
|
def ptr_size(self):
|
|
|
|
page_type = pwndbg.aglib.typeinfo.load("struct page")
|
|
|
|
return 64
|
|
|
|
assert page_type is not None, "Type 'struct page' not exists"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.STRUCT_PAGE_SIZE = page_type.sizeof
|
|
|
|
|
|
|
|
self.STRUCT_PAGE_SHIFT = int(math.log2(self.STRUCT_PAGE_SIZE))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.VA_BITS = int(kconfig()["ARM64_VA_BITS"])
|
|
|
|
|
|
|
|
self.PAGE_SHIFT = int(kconfig()["CONFIG_ARM64_PAGE_SHIFT"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addr = pwndbg.aglib.symbol.lookup_symbol_addr("memstart_addr")
|
|
|
|
|
|
|
|
assert addr is not None, "Symbol memstart_addr not exists"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.PHYS_OFFSET = pwndbg.aglib.memory.u(addr)
|
|
|
|
|
|
|
|
self.PAGE_OFFSET = (-1 << self.VA_BITS) + 2**64
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VA_BITS_MIN = 48 if self.VA_BITS > 48 else self.VA_BITS
|
|
|
|
|
|
|
|
PAGE_END = (-1 << (VA_BITS_MIN - 1)) + 2**64
|
|
|
|
|
|
|
|
VMEMMAP_SIZE = (PAGE_END - self.PAGE_OFFSET) >> (self.PAGE_SHIFT - self.STRUCT_PAGE_SHIFT)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if pwndbg.aglib.kernel.krelease() >= (5, 11):
|
|
|
|
|
|
|
|
# Linux 5.11 changed the calculation for VMEMMAP_START
|
|
|
|
|
|
|
|
# https://elixir.bootlin.com/linux/v5.11/source/arch/arm64/include/asm/memory.h#L53
|
|
|
|
|
|
|
|
self.VMEMMAP_SHIFT = self.PAGE_SHIFT - self.STRUCT_PAGE_SHIFT
|
|
|
|
|
|
|
|
self.VMEMMAP_START = -(1 << (self.VA_BITS - self.VMEMMAP_SHIFT)) % (1 << 64)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.VMEMMAP_START = (-VMEMMAP_SIZE - 2 * 1024 * 1024) + 2**64
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def page_size(self) -> int:
|
|
|
|
|
|
|
|
return 1 << self.PAGE_SHIFT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@requires_debug_syms()
|
|
|
|
@requires_debug_syms()
|
|
|
|
def per_cpu(self, addr: pwndbg.dbg_mod.Value, cpu: int | None = None) -> pwndbg.dbg_mod.Value:
|
|
|
|
def per_cpu(self, addr: pwndbg.dbg_mod.Value, cpu: int | None = None) -> pwndbg.dbg_mod.Value:
|
|
|
|
@ -504,32 +407,46 @@ class Aarch64Ops(ArchOps):
|
|
|
|
return pwndbg.dbg.selected_inferior().create_value(per_cpu_addr, addr.type)
|
|
|
|
return pwndbg.dbg.selected_inferior().create_value(per_cpu_addr, addr.type)
|
|
|
|
|
|
|
|
|
|
|
|
def virt_to_phys(self, virt: int) -> int:
|
|
|
|
def virt_to_phys(self, virt: int) -> int:
|
|
|
|
return virt - self.PAGE_OFFSET
|
|
|
|
return virt - self.page_offset
|
|
|
|
|
|
|
|
|
|
|
|
def phys_to_virt(self, phys: int) -> int:
|
|
|
|
def phys_to_virt(self, phys: int) -> int:
|
|
|
|
return phys + self.PAGE_OFFSET
|
|
|
|
return phys + self.page_offset
|
|
|
|
|
|
|
|
|
|
|
|
def phys_to_pfn(self, phys: int) -> int:
|
|
|
|
def phys_to_pfn(self, phys: int) -> int:
|
|
|
|
return phys >> self.PAGE_SHIFT
|
|
|
|
return phys >> self.page_shift
|
|
|
|
|
|
|
|
|
|
|
|
def pfn_to_phys(self, pfn: int) -> int:
|
|
|
|
def pfn_to_phys(self, pfn: int) -> int:
|
|
|
|
return pfn << self.PAGE_SHIFT
|
|
|
|
return pfn << self.page_shift
|
|
|
|
|
|
|
|
|
|
|
|
def pfn_to_page(self, pfn: int) -> int:
|
|
|
|
def pfn_to_page(self, pfn: int) -> int:
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
return (pfn << self.STRUCT_PAGE_SHIFT) + self.VMEMMAP_START
|
|
|
|
return (pfn << self.STRUCT_PAGE_SHIFT) + self.vmemmap
|
|
|
|
|
|
|
|
|
|
|
|
def page_to_pfn(self, page: int) -> int:
|
|
|
|
def page_to_pfn(self, page: int) -> int:
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# assumption: SPARSEMEM_VMEMMAP memory model used
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
# FLATMEM or SPARSEMEM not (yet) implemented
|
|
|
|
return (page - self.VMEMMAP_START) >> self.STRUCT_PAGE_SHIFT
|
|
|
|
return (page - self.vmemmap) >> self.STRUCT_PAGE_SHIFT
|
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
@staticmethod
|
|
|
|
def paging_enabled() -> bool:
|
|
|
|
def paging_enabled() -> bool:
|
|
|
|
return int(pwndbg.aglib.regs.SCTLR) & BIT(0) != 0
|
|
|
|
return int(pwndbg.aglib.regs.SCTLR) & BIT(0) != 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_arch_paginginfo: ArchPagingInfo = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pwndbg.lib.cache.cache_until("start")
|
|
|
|
|
|
|
|
def arch_paginginfo() -> ArchPagingInfo:
|
|
|
|
|
|
|
|
global _arch_paginginfo
|
|
|
|
|
|
|
|
if _arch_paginginfo is None:
|
|
|
|
|
|
|
|
if pwndbg.aglib.arch.name == "aarch64":
|
|
|
|
|
|
|
|
_arch_paginginfo = pwndbg.aglib.kernel.paging.Aarch64PagingInfo()
|
|
|
|
|
|
|
|
elif pwndbg.aglib.arch.name == "x86-64":
|
|
|
|
|
|
|
|
_arch_paginginfo = pwndbg.aglib.kernel.paging.x86_64PagingInfo()
|
|
|
|
|
|
|
|
return _arch_paginginfo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_arch_ops: ArchOps = None
|
|
|
|
_arch_ops: ArchOps = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -547,10 +464,18 @@ def arch_ops() -> ArchOps:
|
|
|
|
return _arch_ops
|
|
|
|
return _arch_ops
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def ptr_size() -> int:
|
|
|
|
|
|
|
|
ops = arch_ops()
|
|
|
|
|
|
|
|
if ops:
|
|
|
|
|
|
|
|
return ops.ptr_size
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def page_size() -> int:
|
|
|
|
def page_size() -> int:
|
|
|
|
ops = arch_ops()
|
|
|
|
ops = arch_ops()
|
|
|
|
if ops:
|
|
|
|
if ops:
|
|
|
|
return ops.page_size()
|
|
|
|
return ops.page_size
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
raise NotImplementedError()
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
@ -667,6 +592,15 @@ def virt_to_pfn(virt: int) -> int:
|
|
|
|
raise NotImplementedError()
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pwndbg.lib.cache.cache_until("stop")
|
|
|
|
|
|
|
|
def kbase() -> int | None:
|
|
|
|
|
|
|
|
ops = arch_ops()
|
|
|
|
|
|
|
|
if ops:
|
|
|
|
|
|
|
|
return ops.kbase
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
raise NotImplementedError()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def paging_enabled() -> bool:
|
|
|
|
def paging_enabled() -> bool:
|
|
|
|
arch_name = pwndbg.aglib.arch.name
|
|
|
|
arch_name = pwndbg.aglib.arch.name
|
|
|
|
if arch_name == "i386":
|
|
|
|
if arch_name == "i386":
|
|
|
|
|