mirror of https://github.com/pwndbg/pwndbg.git
Added command to list slabs (#1442)
parent
6a6107b4bf
commit
caa22ce04e
@ -0,0 +1,42 @@
|
|||||||
|
import argparse
|
||||||
|
|
||||||
|
from tabulate import tabulate
|
||||||
|
|
||||||
|
import pwndbg.commands
|
||||||
|
import pwndbg.gdblib.kernel.slab
|
||||||
|
from pwndbg.gdblib.kernel.slab import oo_objects
|
||||||
|
from pwndbg.gdblib.kernel.slab import oo_order
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Prints information about the SLUB allocator")
|
||||||
|
parser.add_argument(
|
||||||
|
"filter_",
|
||||||
|
metavar="filter",
|
||||||
|
type=str,
|
||||||
|
nargs="?",
|
||||||
|
help="Only show caches that contain the given filter string",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pwndbg.commands.ArgparsedCommand(parser)
|
||||||
|
@pwndbg.commands.OnlyWhenQemuKernel
|
||||||
|
@pwndbg.commands.OnlyWithKernelDebugSyms
|
||||||
|
def slab(filter_=None):
|
||||||
|
results = []
|
||||||
|
for cache in pwndbg.gdblib.kernel.slab.caches():
|
||||||
|
name = pwndbg.gdblib.memory.string(cache["name"]).decode("ascii")
|
||||||
|
if filter_ and filter_ not in name:
|
||||||
|
continue
|
||||||
|
order = oo_order(int(cache["oo"]["x"]))
|
||||||
|
objects = oo_objects(int(cache["oo"]["x"]))
|
||||||
|
results.append(
|
||||||
|
[
|
||||||
|
name,
|
||||||
|
objects,
|
||||||
|
int(cache["size"]),
|
||||||
|
int(cache["object_size"]),
|
||||||
|
int(cache["inuse"]),
|
||||||
|
order,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
print(tabulate(results, headers=["Name", "# Objects", "Size", "Obj Size", "# inuse", "order"]))
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import gdb
|
||||||
|
|
||||||
|
|
||||||
|
def offset_of(typename: str, fieldname: str):
|
||||||
|
ptr_type = gdb.lookup_type(typename).pointer()
|
||||||
|
dummy = gdb.Value(0).cast(ptr_type)
|
||||||
|
return int(dummy[fieldname].address)
|
||||||
|
|
||||||
|
|
||||||
|
def container_of(ptr, typename: str, fieldname: str):
|
||||||
|
ptr_type = gdb.lookup_type(typename).pointer()
|
||||||
|
obj_addr = int(ptr) - offset_of(typename, fieldname)
|
||||||
|
return gdb.Value(obj_addr).cast(ptr_type)
|
||||||
|
|
||||||
|
|
||||||
|
def for_each_entry(head, typename, field):
|
||||||
|
addr = head["next"]
|
||||||
|
while addr != head.address:
|
||||||
|
yield container_of(addr, typename, field)
|
||||||
|
addr = addr.dereference()["next"]
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
import gdb
|
||||||
|
|
||||||
|
from pwndbg.gdblib.kernel.macros import for_each_entry
|
||||||
|
|
||||||
|
|
||||||
|
def caches():
|
||||||
|
slab_caches = gdb.lookup_global_symbol("slab_caches").value()
|
||||||
|
for slab_cache in for_each_entry(slab_caches, "struct kmem_cache", "list"):
|
||||||
|
yield slab_cache
|
||||||
|
|
||||||
|
|
||||||
|
OO_SHIFT = 16
|
||||||
|
OO_MASK = (1 << OO_SHIFT) - 1
|
||||||
|
|
||||||
|
|
||||||
|
def oo_order(x: int) -> int:
|
||||||
|
return int(x) >> OO_SHIFT
|
||||||
|
|
||||||
|
|
||||||
|
def oo_objects(x: int) -> int:
|
||||||
|
return int(x) & OO_MASK
|
||||||
Loading…
Reference in new issue