commit b87e243dc41bc1972ec1d819ab1aba7907b5890b
parent 7821b701696cd858df9b95561a51631bab117fe1
Author: Tizian Leonhardt <tizianleonhardt@web.de>
Date: Sat, 23 Jan 2021 20:02:03 +0100
Re-merge comparison
Diffstat:
1 file changed, 69 insertions(+), 3 deletions(-)
diff --git a/mem_forensics/memcheck-gdb.py b/mem_forensics/memcheck-gdb.py
@@ -623,8 +623,76 @@ class RkCheckFunctions(gdb.Command):
self.fill_altinstr_dict()
self.fill_paravirt_dict()
+ for symbol in self.s.iter_symbols():
+ if symbol.entry["st_info"]["type"] == "STT_FUNC":
+ name = symbol.name
+ size = symbol.entry["st_size"]
+ value = symbol.entry["st_value"]
+ else:
+ continue
+
+ if name is None or ".cold." in name or ".part." in name or ".constprop." in name:
+ continue
+
+ self.compare_function(name, size, value)
+
def compare_function(self, name, size, value):
- print("nop")
+ addr = self.get_v_addr(name)
+
+ if addr is None:
+ print(f"could not retrieve virtual address address for symbol `{name}`")
+ return None
+
+ # read in live bytes from start address of the function + 5B (to offset the call to __fentry__)
+ live_bytes = gdb.execute(f"xbfunc {addr} {size}", to_string=True).split()
+ objdump = subprocess.check_output(f"objdump -z --disassemble={name} {file_g}", shell=True).split(b"\n")[:-1]
+
+ start = None
+ for i, s in enumerate(objdump):
+ if name in s.decode(sys.stdout.encoding):
+ start = i
+ break
+
+ objdump = objdump[start+1:]
+
+ end = None
+ for i, s in enumerate(objdump):
+ if b'' == s:
+ end = i
+ break
+
+ if end is not None:
+ objdump = objdump[:end]
+
+ # exclude_objdump = []
+ # for i, s in enumerate(objdump):
+ # bytes_start = s.decode(sys.stdout.encoding).find(':')
+ # if b"<" in s and b">" in s or b"0x" in s or b"ffffff" in s[bytes_start:]:
+ # exclude_objdump.append(i)
+
+ # exclude_live_bytes = []
+ # for i in exclude_objdump:
+ # bytes = objdump[i].split(b"\t")[1]
+ # bytes = bytes.strip().split(b" ")
+ # for j in range(len(bytes)):
+ # exclude_live_bytes.append(i + j)
+
+ # objdump = [elf_byte for i, elf_byte in enumerate(objdump) if i not in exclude_objdump]
+ objdump = [line.split(b"\t") for line in objdump]
+
+ # live_bytes = [live_byte for i, live_byte in enumerate(live_bytes) if i not in exclude_live_bytes]
+ live_bytes = "".join(live_bytes)
+
+ elf_bytes = [line[1].decode(sys.stdout.encoding).strip().replace(' ', '') for line in objdump]
+ elf_bytes = "".join(elf_bytes)
+
+ int3_chain = ''.join('c' * len(live_bytes))
+ if live_bytes == int3_chain:
+ return None
+
+ if live_bytes != elf_bytes:
+ print(f"function `{name} compromised, live bytes not equal to ELF bytes")
+ print(f"expected: {elf_bytes}, live: {live_bytes}")
def get_v_addr(self, symbol):
try:
@@ -713,6 +781,4 @@ class RkCheckFunctions(gdb.Command):
i = i + paravirt_patch_site_sz
- print(self.paravirt_dict)
-
RkCheckFunctions()