Created
August 18, 2022 02:07
-
-
Save pagabuc/425d7a139ea99cb57671c0079c67818d to your computer and use it in GitHub Desktop.
Find kernel objects containing function pointers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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