mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-26 16:30:17 +00:00
113 lines
3.1 KiB
Python
113 lines
3.1 KiB
Python
|
# SPDX-License-Identifier: MIT
|
||
|
import re
|
||
|
from construct import *
|
||
|
|
||
|
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[23], 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="")
|