Skip to content

Instantly share code, notes, and snippets.

@pagabuc
Created August 18, 2022 02:07
Show Gist options
  • Save pagabuc/425d7a139ea99cb57671c0079c67818d to your computer and use it in GitHub Desktop.
Save pagabuc/425d7a139ea99cb57671c0079c67818d to your computer and use it in GitHub Desktop.
Find kernel objects containing function pointers
# Written by pagabuc, run with the following:
# gdb --batch --nx -q -x extract_offsets.py ./vmlinux
# This script finds kernel objects that contain function pointers and with size between 1024 and 2048.
# Nested structure types are traversed recursively.
import gdb
import re
struct_regex = re.compile("(struct [a-zA-Z0-9_]*)")
def iter_struct_types():
types = gdb.execute('info types', to_string=True)
for t in types.split("\n"):
match = struct_regex.search(t)
if match:
yield match.group()
def is_function_pointer(field):
t = field.type.strip_typedefs()
return (t.code == gdb.TYPE_CODE_PTR) and (t.target().code == gdb.TYPE_CODE_FUNC)
def is_struct(field):
t = field.type.strip_typedefs()
return (t.code == gdb.TYPE_CODE_STRUCT)
def find_function_ptrs(t, chain="", bitpos=0):
pointers = []
for fname, field in gdb.types.deep_items(t):
step = chain + fname
if is_struct(field):
pointers += find_function_ptrs(field.type, step + '.',
bitpos + field.bitpos)
if is_function_pointer(field):
offset = int((bitpos + field.bitpos) / 8)
pointers.append((step, offset))
return pointers
def main():
types = set(iter_struct_types())
print("[+] Found %d structs" % len(types))
for s in types:
try:
t = gdb.lookup_type(s)
except gdb.error:
continue
# Filter on the size of the struct
if not (1024 < t.sizeof <= 2048):
continue
pointers = find_function_ptrs(t)
if len(pointers) > 0:
print("\n%s contains %d function pointers:" % (t, len(pointers)))
for chain, offset in pointers:
print(" [0x%04x] %s" % (offset, chain))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment