Added command to list slabs (#1442)

pull/1454/head
Gulshan Singh 3 years ago committed by GitHub
parent 6a6107b4bf
commit caa22ce04e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -558,6 +558,7 @@ def load_commands():
import pwndbg.commands.search
import pwndbg.commands.segments
import pwndbg.commands.shell
import pwndbg.commands.slab
import pwndbg.commands.stack
import pwndbg.commands.start
import pwndbg.commands.telescope

@ -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

@ -7,5 +7,6 @@ pycparser==2.21
pyelftools==0.29
Pygments==2.13.0
ROPGadget==7.1
tabulate==0.8.10
unicorn==2.0.1; python_version >= '3.7'
unicorn==2.0.0rc7; python_version < '3.7'

Loading…
Cancel
Save