1c7cbf32fSJonas Devlieghere#!/usr/bin/env python 2c7cbf32fSJonas Devlieghere 3c7cbf32fSJonas Devlieghereimport json 4c7cbf32fSJonas Devlieghereimport os 5c7cbf32fSJonas Devlieghereimport re 6c7cbf32fSJonas Devlieghereimport subprocess 7c7cbf32fSJonas Devlieghereimport sys 8a4d1e609SJonas Devlieghereimport argparse 9c7cbf32fSJonas Devlieghere 10c7cbf32fSJonas Devlieghere 11c7cbf32fSJonas Devlieghereclass CrashLogPatcher: 12c7cbf32fSJonas Devlieghere 13c7cbf32fSJonas Devlieghere SYMBOL_REGEX = re.compile(r'^([0-9a-fA-F]+) T _(.*)$') 14c7cbf32fSJonas Devlieghere UUID_REGEX = re.compile(r'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*') 15c7cbf32fSJonas Devlieghere 16a4d1e609SJonas Devlieghere def __init__(self, data, binary, offsets, json): 17c7cbf32fSJonas Devlieghere self.data = data 18c7cbf32fSJonas Devlieghere self.binary = binary 19c7cbf32fSJonas Devlieghere self.offsets = offsets 20a4d1e609SJonas Devlieghere self.json = json 21c7cbf32fSJonas Devlieghere 22c7cbf32fSJonas Devlieghere def patch_executable(self): 23c7cbf32fSJonas Devlieghere self.data = self.data.replace("@EXEC@", self.binary) 24c7cbf32fSJonas Devlieghere self.data = self.data.replace("@NAME@", os.path.basename(self.binary)) 25c7cbf32fSJonas Devlieghere 26c7cbf32fSJonas Devlieghere def patch_uuid(self): 272fa38fa9SRaphael Isemann output = subprocess.check_output(['dwarfdump', '--uuid', self.binary]).decode("utf-8") 28c7cbf32fSJonas Devlieghere m = self.UUID_REGEX.match(output) 29c7cbf32fSJonas Devlieghere if m: 30c7cbf32fSJonas Devlieghere self.data = self.data.replace("@UUID@", m.group(1)) 31c7cbf32fSJonas Devlieghere 32c7cbf32fSJonas Devlieghere def patch_addresses(self): 33c7cbf32fSJonas Devlieghere if not self.offsets: 34c7cbf32fSJonas Devlieghere return 35c77aefb0SRaphael Isemann output = subprocess.check_output(['nm', self.binary]).decode("utf-8") 36c7cbf32fSJonas Devlieghere for line in output.splitlines(): 37c7cbf32fSJonas Devlieghere m = self.SYMBOL_REGEX.match(line) 38c7cbf32fSJonas Devlieghere if m: 39c7cbf32fSJonas Devlieghere address = m.group(1) 40c7cbf32fSJonas Devlieghere symbol = m.group(2) 41c7cbf32fSJonas Devlieghere if symbol in self.offsets: 42c7cbf32fSJonas Devlieghere patch_addr = int(m.group(1), 16) + int( 43c7cbf32fSJonas Devlieghere self.offsets[symbol]) 44a4d1e609SJonas Devlieghere if self.json: 45a4d1e609SJonas Devlieghere patch_addr = patch_addr - 0x100000000 46a4d1e609SJonas Devlieghere representation = int 47a4d1e609SJonas Devlieghere else: 48a4d1e609SJonas Devlieghere representation = hex 49a4d1e609SJonas Devlieghere self.data = self.data.replace( 50a4d1e609SJonas Devlieghere "@{}@".format(symbol), str(representation(patch_addr))) 51c7cbf32fSJonas Devlieghere 52*730fca46SJonas Devlieghere def remove_metadata(self): 53*730fca46SJonas Devlieghere self.data= self.data[self.data.index('\n') + 1:] 54*730fca46SJonas Devlieghere 55c7cbf32fSJonas Devlieghere 56c7cbf32fSJonas Devlieghereif __name__ == '__main__': 57a4d1e609SJonas Devlieghere parser = argparse.ArgumentParser(description='Crashlog Patcher') 58a4d1e609SJonas Devlieghere parser.add_argument('--binary', required=True) 59a4d1e609SJonas Devlieghere parser.add_argument('--crashlog', required=True) 60a4d1e609SJonas Devlieghere parser.add_argument('--offsets', required=True) 61a4d1e609SJonas Devlieghere parser.add_argument('--json', default=False, action='store_true') 62*730fca46SJonas Devlieghere parser.add_argument('--no-metadata', default=False, action='store_true') 63a4d1e609SJonas Devlieghere args = parser.parse_args() 64c7cbf32fSJonas Devlieghere 65a4d1e609SJonas Devlieghere offsets = json.loads(args.offsets) 66a4d1e609SJonas Devlieghere 67a4d1e609SJonas Devlieghere with open(args.crashlog, 'r') as file: 68c7cbf32fSJonas Devlieghere data = file.read() 69c7cbf32fSJonas Devlieghere 70a4d1e609SJonas Devlieghere p = CrashLogPatcher(data, args.binary, offsets, args.json) 71c7cbf32fSJonas Devlieghere p.patch_executable() 72c7cbf32fSJonas Devlieghere p.patch_uuid() 73c7cbf32fSJonas Devlieghere p.patch_addresses() 74c7cbf32fSJonas Devlieghere 75*730fca46SJonas Devlieghere if args.no_metadata: 76*730fca46SJonas Devlieghere p.remove_metadata() 77*730fca46SJonas Devlieghere 78a4d1e609SJonas Devlieghere with open(args.crashlog, 'w') as file: 79c7cbf32fSJonas Devlieghere file.write(p.data) 80