1#!/usr/bin/env python 2 3import json 4import os 5import re 6import subprocess 7import sys 8 9 10class CrashLogPatcher: 11 12 SYMBOL_REGEX = re.compile(r'^([0-9a-fA-F]+) T _(.*)$') 13 UUID_REGEX = re.compile(r'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*') 14 15 def __init__(self, data, binary, offsets): 16 self.data = data 17 self.binary = binary 18 self.offsets = offsets 19 20 def patch_executable(self): 21 self.data = self.data.replace("@EXEC@", self.binary) 22 self.data = self.data.replace("@NAME@", os.path.basename(self.binary)) 23 24 def patch_uuid(self): 25 output = subprocess.check_output(['dwarfdump', '--uuid', self.binary]) 26 m = self.UUID_REGEX.match(output) 27 if m: 28 self.data = self.data.replace("@UUID@", m.group(1)) 29 30 def patch_addresses(self): 31 if not self.offsets: 32 return 33 output = subprocess.check_output(['nm', self.binary]) 34 for line in output.splitlines(): 35 m = self.SYMBOL_REGEX.match(line) 36 if m: 37 address = m.group(1) 38 symbol = m.group(2) 39 if symbol in self.offsets: 40 patch_addr = int(m.group(1), 16) + int( 41 self.offsets[symbol]) 42 self.data = self.data.replace("@{}@".format(symbol), 43 str(hex(patch_addr))) 44 45 46if __name__ == '__main__': 47 binary = sys.argv[1] 48 crashlog = sys.argv[2] 49 offsets = json.loads(sys.argv[3]) if len(sys.argv) > 3 else None 50 51 with open(crashlog, 'r') as file: 52 data = file.read() 53 54 p = CrashLogPatcher(data, binary, offsets) 55 p.patch_executable() 56 p.patch_uuid() 57 p.patch_addresses() 58 59 with open(crashlog, 'w') as file: 60 file.write(p.data) 61