From 1ad600c81aa4e0a767293ebd5b73a3496988efbe Mon Sep 17 00:00:00 2001 From: TuxSH Date: Thu, 6 Oct 2016 00:16:21 +0200 Subject: [PATCH] Make the exception dump parser output the disassembly of the dumped code (when it's possible) --- exceptions/exception_dump_parser.py | 60 ++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/exceptions/exception_dump_parser.py b/exceptions/exception_dump_parser.py index f704471..9220273 100644 --- a/exceptions/exception_dump_parser.py +++ b/exceptions/exception_dump_parser.py @@ -22,9 +22,9 @@ # Notices displayed by works containing it. __author__ = "TuxSH" -__copyright__ = "Copyright (c) 2016 TuxSH" +__copyright__ = "Copyright (c) 2016 TuxSH" __license__ = "GPLv3" -__version__ = "v1.0" +__version__ = "v1.2" """ Parses Luma3DS exception dumps @@ -33,6 +33,9 @@ Parses Luma3DS exception dumps import argparse from struct import unpack_from +import os +import subprocess + # Source of hexdump: https://gist.github.com/ImmortalPC/c340564823f283fe530b # Credits for hexdump go to the original authors # Slightly edited by TuxSH @@ -76,14 +79,14 @@ def hexdump(addr, src, length=16, sep='.' ): text += chr(c) else: text += sep - result.append(('%08X: %-'+str(length*(2+1)+1)+'s |%s|') % (addr + i, hexa, text)) + result.append(('%08x: %-'+str(length*(2+1)+1)+'s |%s|') % (addr + i, hexa, text)) return '\n'.join(result) - + def makeRegisterLine(A, rA, B, rB): return "{0:<15}{1:<20}{2:<15}{3:<20}".format(A, "{0:08x}".format(rA), B, "{0:08x}".format(rB)) - + handledExceptionNames = ("FIQ", "undefined instruction", "prefetch abort", "data abort") registerNames = tuple("r{0}".format(i) for i in range(13)) + ("sp", "lr", "pc", "cpsr") + ("dfsr", "ifsr", "far") + ("fpexc", "fpinst", "fpinst2") svcBreakReasons = ("(svcBreak: panic)", "(svcBreak: assertion failed)", "(svcBreak: user-related)") @@ -96,23 +99,24 @@ if __name__ == "__main__": with open(args.filename, "rb") as f: data = f.read() if unpack_from("<2I", data) != (0xdeadc0de, 0xdeadcafe): raise SystemExit("Invalid file format") - + version, processor, exceptionType, _, nbRegisters, codeDumpSize, stackDumpSize, additionalDataSize = unpack_from("<8I", data, 8) nbRegisters //= 4 - + if version < (1 << 16) | 2: raise SystemExit("Incompatible format version, please use the appropriate parser.") - + registers = unpack_from("<{0}I".format(nbRegisters), data, 40) - codeDump = data[40 + 4 * nbRegisters : 40 + 4 * nbRegisters + codeDumpSize] - stackOffset = 40 + 4 * nbRegisters + codeDumpSize + codeOffset = 40 + 4 * nbRegisters + codeDump = data[codeOffset : codeOffset + codeDumpSize] + stackOffset = codeOffset + codeDumpSize stackDump = data[stackOffset : stackOffset + stackDumpSize] addtionalDataOffset = stackOffset + stackDumpSize additionalData = data[addtionalDataOffset : addtionalDataOffset + additionalDataSize] - + if processor == 9: print("Processor: ARM9") else: print("Processor: ARM11 (core {0})".format(processor >> 16)) - + typeDetailsStr = "" if exceptionType == 2: if (registers[16] & 0x20) == 0 and codeDumpSize >= 4: @@ -125,23 +129,41 @@ if __name__ == "__main__": instr = unpack_from("= len(handledExceptionNames) else handledExceptionNames[exceptionType], typeDetailsStr)) if additionalDataSize != 0: print("Current process: {0} ({1:016x})".format(additionalData[:8].decode("ascii"), unpack_from("