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