mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-12-27 13:43:05 +00:00
e06e58e864
We need to find a better way of doing this... Signed-off-by: Hector Martin <marcan@marcan.st>
117 lines
3.2 KiB
Python
117 lines
3.2 KiB
Python
# SPDX-License-Identifier: MIT
|
|
import re
|
|
from construct import *
|
|
|
|
__all__ = []
|
|
|
|
DebuggerState = Struct(
|
|
"panic_options" / Hex(Int64ul),
|
|
"current_op" / Hex(Int32ul),
|
|
"proceed_on_sync_failre" / Int32ul,
|
|
"message" / Hex(Int64ul),
|
|
"panic_str" / Hex(Int64ul),
|
|
"panic_args" / Hex(Int64ul),
|
|
"panic_data_ptr" / Hex(Int64ul),
|
|
"panic_caller" / Hex(Int64ul),
|
|
"entry_count" / Hex(Int32ul),
|
|
"kern_return" / Hex(Int32sl)
|
|
)
|
|
|
|
# Darwin va_list is just a stack pointer...
|
|
VaList = Struct(
|
|
"stack" / Hex(Int64ul),
|
|
)
|
|
|
|
def decode_debugger_state(u, ctx):
|
|
p = u.proxy
|
|
iface = u.iface
|
|
|
|
def hv_readmem(addr, size):
|
|
addr = p.hv_translate(addr, False, False)
|
|
assert addr != 0
|
|
return iface.readmem(addr, size)
|
|
|
|
p_state = p.hv_translate(ctx.regs[25], False, False)
|
|
assert p_state != 0
|
|
di = iface.readstruct(p_state, DebuggerState)
|
|
print(di)
|
|
|
|
message = hv_readmem(di.message, 1024).split(b"\x00")[0].decode("ascii")
|
|
print()
|
|
print(f"Message: {message}")
|
|
|
|
print("===== Panic string =====")
|
|
decode_panic(u, di.panic_str, di.panic_args)
|
|
print("========================")
|
|
|
|
def decode_panic_call(u, ctx):
|
|
decode_panic(u, ctx.regs[0], ctx.regs[1])
|
|
|
|
def decode_panic(u, p_string, p_args):
|
|
p = u.proxy
|
|
iface = u.iface
|
|
|
|
def hv_readmem(addr, size):
|
|
addr = p.hv_translate(addr, False, False)
|
|
assert addr != 0
|
|
return iface.readmem(addr, size)
|
|
|
|
string = hv_readmem(p_string, 1024).split(b"\x00")[0].decode("ascii")
|
|
p_args = p.hv_translate(p_args, False, False)
|
|
|
|
args = iface.readstruct(p_args, VaList)
|
|
|
|
stack = hv_readmem(args.stack, 504)
|
|
|
|
def va_arg(t):
|
|
nonlocal stack
|
|
d, stack = stack[:8], stack[8:]
|
|
return t.parse(d)
|
|
|
|
utypes = {
|
|
"hh": Int8ul,
|
|
"h": Int16ul,
|
|
None: Int32ul,
|
|
"l": Int64ul,
|
|
"ll": Int64ul,
|
|
"q": Int64ul,
|
|
"s": Int64ul,
|
|
"t": Int64ul,
|
|
}
|
|
|
|
stypes = {
|
|
"hh": Int8sl,
|
|
"h": Int16sl,
|
|
None: Int32sl,
|
|
"l": Int64sl,
|
|
"ll": Int64sl,
|
|
"q": Int64sl,
|
|
"s": Int64sl,
|
|
"t": Int64sl,
|
|
}
|
|
|
|
#print(string)
|
|
|
|
def format_arg(match):
|
|
pat, flags, width, mod, conv = match.group(0, 1, 2, 3, 4)
|
|
if conv == "%":
|
|
return "%"
|
|
elif conv == "s":
|
|
return hv_readmem(va_arg(Int64ul), 1024).split(b"\x00")[0].decode("ascii")
|
|
elif conv in "di":
|
|
v = va_arg(stypes[mod])
|
|
return f"%{flags or ''}{width or ''}{conv or ''}" % v
|
|
elif conv in "ouxX":
|
|
v = va_arg(utypes[mod])
|
|
return f"%{flags or ''}{width or ''}{conv or ''}" % v
|
|
elif conv in "p":
|
|
return f"0x{va_arg(Int64ul):x}"
|
|
else:
|
|
return f"[{pat!r}:{va_arg(Int64ul):x}]"
|
|
|
|
string = re.sub('%([-#0 +]*)([1-9][0-9]*)?(hh|h|l|ll|q|L|j|z|Z|t)?([diouxXeEfFgGaAcsCSpnm%])',
|
|
format_arg, string)
|
|
print(string + "\n", end="")
|
|
|
|
__all__.extend(k for k, v in globals().items()
|
|
if (callable(v) or isinstance(v, type)) and v.__module__ == __name__)
|