mirror of https://github.com/pwndbg/pwndbg.git
actually adding the remamed file
parent
8ec80e7b04
commit
c48e84016b
@ -0,0 +1,118 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
import pwndbg.aglib.kernel
|
||||
import pwndbg.aglib.regs
|
||||
import pwndbg.color as C
|
||||
import pwndbg.color.message as M
|
||||
from pwndbg.commands import CommandCategory
|
||||
from pwndbg.lib.regs import BitFlags
|
||||
|
||||
parser = argparse.ArgumentParser(description="Performs pagewalk.")
|
||||
parser.add_argument("vaddr", type=str, help="virtual address to walk")
|
||||
parser.add_argument("--pgd", dest="entry", type=str, default=None, help="")
|
||||
|
||||
|
||||
pageflags = BitFlags([("NX", 63), ("PS", 7), ("A", 5), ("W", 1), ("P", 0)])
|
||||
|
||||
|
||||
def print_pagetable_entry(name: str, paddr: int | None, vaddr: int):
|
||||
flags = ""
|
||||
arrow_right = pwndbg.chain.c.arrow(f"{pwndbg.chain.config_arrow_right}")
|
||||
if paddr is not None:
|
||||
flags = f"{arrow_right} {name + 'e'}: {C.context.format_flags(paddr, pageflags, paddr)}"
|
||||
print(f"{C.blue(name)} @ {C.yellow(hex(vaddr))} {flags}")
|
||||
|
||||
|
||||
def pg_indices(vaddr, nr_level):
|
||||
result = [vaddr & (0x1000 - 1)]
|
||||
vaddr >>= 12
|
||||
for _ in range(nr_level):
|
||||
result.append(vaddr & (0x1FF))
|
||||
vaddr >>= 9
|
||||
return result
|
||||
|
||||
|
||||
@pwndbg.commands.Command(parser, category=CommandCategory.KERNEL)
|
||||
@pwndbg.commands.OnlyWhenQemuKernel
|
||||
@pwndbg.commands.OnlyWhenPagingEnabled
|
||||
def pagewalk(vaddr, entry=None):
|
||||
vaddr = int(pwndbg.dbg.selected_frame().evaluate_expression(vaddr))
|
||||
# https://blog.zolutal.io/understanding-paging/
|
||||
base = pwndbg.aglib.kernel.physmap_base()
|
||||
level = 4
|
||||
names = (
|
||||
"Page",
|
||||
"PT",
|
||||
"PMD",
|
||||
"PUD",
|
||||
"PGD",
|
||||
)
|
||||
if pwndbg.aglib.kernel.uses_5lvl_paging():
|
||||
level = 5
|
||||
names = (
|
||||
"Page",
|
||||
"PT",
|
||||
"PMD",
|
||||
"P4D",
|
||||
"PUD",
|
||||
"PGD",
|
||||
)
|
||||
if entry is None:
|
||||
entry = pwndbg.aglib.regs["cr3"]
|
||||
else:
|
||||
entry = int(pwndbg.dbg.selected_frame().evaluate_expression(entry))
|
||||
if entry > base:
|
||||
# user inputted a physmap address as pointer to pgd
|
||||
entry -= base
|
||||
offset = 0
|
||||
entry_mask = ~((1 << 12) - 1) & ((1 << 51) - 1)
|
||||
for i in range(level, 0, -1):
|
||||
cur = (entry & entry_mask) + base
|
||||
if entry & (1 << 7) > 0:
|
||||
break
|
||||
shift = (i - 1) * 9 + 12
|
||||
offset = vaddr & ((1 << shift) - 1)
|
||||
idx = (vaddr & (0x1FF << shift)) >> shift
|
||||
entry = 0
|
||||
try:
|
||||
table = pwndbg.aglib.memory.get_typed_pointer("unsigned long", cur)
|
||||
entry = int(table[idx])
|
||||
print_pagetable_entry(names[i], entry, cur)
|
||||
except Exception as e:
|
||||
print(M.warn(f"Exception while page walking: {e}"))
|
||||
entry = 0
|
||||
if entry == 0:
|
||||
print(M.warn("address is not mapped"))
|
||||
return
|
||||
virtual = base + (entry & entry_mask) + offset
|
||||
print(f"pagewalk result: {C.green(hex(virtual))} [phys: {C.yellow(hex(virtual - base))}]")
|
||||
|
||||
|
||||
p2v_parser = argparse.ArgumentParser(
|
||||
description="Translate physical address to its corresponding virtual address."
|
||||
)
|
||||
p2v_parser.add_argument("paddr", type=str, help="")
|
||||
|
||||
|
||||
@pwndbg.commands.Command(p2v_parser, category=CommandCategory.KERNEL)
|
||||
@pwndbg.commands.OnlyWhenQemuKernel
|
||||
@pwndbg.commands.OnlyWhenPagingEnabled
|
||||
def p2v(paddr):
|
||||
paddr = pwndbg.dbg.selected_frame().evaluate_expression(paddr)
|
||||
return pwndbg.aglib.kernel.phys_to_virt(int(paddr))
|
||||
|
||||
|
||||
v2p_parser = argparse.ArgumentParser(
|
||||
description="Translate virtual address to its corresponding physical address."
|
||||
)
|
||||
v2p_parser.add_argument("vaddr", type=str, help="")
|
||||
|
||||
|
||||
@pwndbg.commands.Command(v2p_parser, category=CommandCategory.KERNEL)
|
||||
@pwndbg.commands.OnlyWhenQemuKernel
|
||||
@pwndbg.commands.OnlyWhenPagingEnabled
|
||||
def v2p(vaddr):
|
||||
vaddr = pwndbg.dbg.selected_frame().evaluate_expression(vaddr)
|
||||
return pwndbg.aglib.kernel.virt_to_phys(int(vaddr))
|
||||
Loading…
Reference in new issue