linux-rootkit

Feature-rich interactive rootkit that targets Linux kernel 4.19, accompanied by a dynamic kernel memory analysis GDB plugin for in vivo introspection (e.g. using QEMU)
git clone git://git.deurzen.net/linux-rootkit
Log | Files | Refs

commit 2f2d91f4501be8ee3c71578fa65003006ee01d52
parent 715f54206041178485c2a42f7c4a8417dd7426f2
Author: Tizian Leonhardt <tizianleonhardt@web.de>
Date:   Fri,  5 Feb 2021 19:37:02 +0100

Remove rk-data for now (since gdb can handle this..)

Diffstat:
Mproject/extract_sizeret.py | 93-------------------------------------------------------------------------------
1 file changed, 0 insertions(+), 93 deletions(-)

diff --git a/project/extract_sizeret.py b/project/extract_sizeret.py @@ -70,100 +70,7 @@ class RKPrintData(gdb.Command): def invoke(self, arg, from_tty): global mem_map - - try: - addr = int(arg, 16) - except: - print("Error: address empty or not a hexadecimal number") - return None - - if addr not in mem_map: - print("Error: address is not in memory map") - - - type, size, _ = mem_map[addr] - - # Get rid of any asterisks and 'type = ' prefix - type = type[(len("type = ")):].replace(' *', '').replace('*', '') - - if not "struct" in type: - print(f"Printing hexdump of base type '{type}'") - gdb.execute(f"x/{size}x {addr}") - else: - self.data_lookup(type, addr, 0) - - def data_lookup(self, type, addr, reclevel): - # Only recurse 3 levels - if reclevel > 3: - return None - - try: - contents = gdb.execute(f"ptype {type}", to_string=True).splitlines() - except: - print("Could not infer type!") - return None - - # Print type declarator - "type = ", get rid of last curly bracket - print(reclevel * '\t', contents.pop(0)[len("type = "):]) - contents = contents[:-1] - - basetype = ["struct", '*'] - - for line in contents: - sz = 0 - - # Case basetype - if not any(b in line for b in basetype) and not self.is_struct(line): - sz = self.basetype(line, addr, reclevel) - - #Case pointer - elif '*' in line: - sz = self.pointer(line, addr, reclevel) - - #Case struct - else: - t = self.type_from_line(line) - self.data_lookup(t, addr, reclevel + 1) - - addr += sz - - print(reclevel * '\t', "}") - - def basetype(self, line, addr, reclevel): - # We only need type information, no name needed - t = self.type_from_line(line) - - # Retrieve size and read memory accordingly - sz = int(gdb.parse_and_eval(f"sizeof({t})")) - dt = gdb.selected_inferior().read_memory(addr, sz) - self.print_line(line, dt, reclevel) - - return sz - - def pointer(self, line, addr, reclevel): - # 8 byte addresses - POINTER_SZ = 8 - - t = self.type_from_line(line) - dt = gdb.selected_inferior().read_memory(addr, 8) - self.print_line(line, dt, reclevel) - - return POINTER_SZ - - def type_from_line(self, line): - t = line.split(" ")[:-1] - return " ".join(t) - - # Check whether a type (ex.: wait_queue_head_t) is really a struct - def is_struct(self, line): - t = self.type_from_line(line) - return "struct" in gdb.execute(f"ptype {t}", to_string=True) - - def print_line(self, line, data, reclevel): - print(reclevel * '\t', f"{line.replace(';', '')} => 0x{bytes(data).hex()}") - - RKPrintData()