81 lines · python
1#!/usr/bin/env python2 3import json4import os5import re6import subprocess7import sys8import argparse9 10 11class CrashLogPatcher: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, json):16 self.data = data17 self.binary = binary18 self.offsets = offsets19 self.json = json20 21 def patch_executable(self):22 self.data = self.data.replace("@EXEC@", self.binary)23 self.data = self.data.replace("@NAME@", os.path.basename(self.binary))24 25 def patch_uuid(self):26 output = subprocess.check_output(["dwarfdump", "--uuid", self.binary]).decode(27 "utf-8"28 )29 m = self.UUID_REGEX.match(output)30 if m:31 self.data = self.data.replace("@UUID@", m.group(1))32 33 def patch_addresses(self):34 if not self.offsets:35 return36 output = subprocess.check_output(["nm", self.binary]).decode("utf-8")37 for line in output.splitlines():38 m = self.SYMBOL_REGEX.match(line)39 if m:40 address = m.group(1)41 symbol = m.group(2)42 if symbol in self.offsets:43 patch_addr = int(m.group(1), 16) + int(self.offsets[symbol])44 if self.json:45 patch_addr = patch_addr - 0x10000000046 representation = int47 else:48 representation = hex49 self.data = self.data.replace(50 "@{}@".format(symbol), str(representation(patch_addr))51 )52 53 def remove_metadata(self):54 self.data = self.data[self.data.index("\n") + 1 :]55 56 57if __name__ == "__main__":58 parser = argparse.ArgumentParser(description="Crashlog Patcher")59 parser.add_argument("--binary", required=True)60 parser.add_argument("--crashlog", required=True)61 parser.add_argument("--offsets", required=True)62 parser.add_argument("--json", default=False, action="store_true")63 parser.add_argument("--no-metadata", default=False, action="store_true")64 args = parser.parse_args()65 66 offsets = json.loads(args.offsets)67 68 with open(args.crashlog, "r") as file:69 data = file.read()70 71 p = CrashLogPatcher(data, args.binary, offsets, args.json)72 p.patch_executable()73 p.patch_uuid()74 p.patch_addresses()75 76 if args.no_metadata:77 p.remove_metadata()78 79 with open(args.crashlog, "w") as file:80 file.write(p.data)81