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