mirror of
https://github.com/SwareJonge/mkdd.git
synced 2024-11-26 23:00:25 +00:00
update getfunction.py
This commit is contained in:
parent
86ebaaeac3
commit
a5dd12f676
66
common.py
66
common.py
@ -41,14 +41,77 @@ class Binary(Enum):
|
||||
# ppcdis source output
|
||||
SourceDesc = Union[str, Tuple[str, int, int]]
|
||||
|
||||
|
||||
def get_containing_slice(addr: int) -> Tuple[Binary, SourceDesc]:
|
||||
"""Finds the binary containing an address and its source file
|
||||
Source file is empty string if not decompiled"""
|
||||
|
||||
dol_raw = get_cmd_stdout(f"{SLICES} {DOL_YML} {DOL_SLICES} -p {DOL_SRCDIR}/ --containing {addr:x}")
|
||||
dol_raw = get_cmd_stdout(
|
||||
f"{SLICES} {DOL_YML} {DOL_SLICES} -p {DOL_SRCDIR}/ --containing {addr:x}")
|
||||
containing = json.loads(dol_raw)
|
||||
return (Binary.DOL, containing)
|
||||
|
||||
|
||||
def lookup_sym(sym: str, dol: bool = False, rel: bool = False, source_name: str = None) -> int:
|
||||
"""Takes a symbol as a name or address and returns the address"""
|
||||
|
||||
# Get binary
|
||||
if dol:
|
||||
binary_name = DOL_YML
|
||||
else:
|
||||
binary_name = None
|
||||
|
||||
# Determine type
|
||||
try:
|
||||
return int(sym, 16)
|
||||
except ValueError:
|
||||
return get_address(sym, binary_name, source_name)
|
||||
|
||||
|
||||
def lookup_sym_full(sym: str, dol: bool = False, rel: bool = False, source_name: str = None
|
||||
) -> int:
|
||||
"""Takes a symbol as a name or address and returns both the name and address"""
|
||||
|
||||
# Get binary
|
||||
if dol:
|
||||
binary_name = DOL_YML
|
||||
else:
|
||||
binary_name = None
|
||||
|
||||
# Determine type
|
||||
try:
|
||||
return int(sym, 16), get_name(sym)
|
||||
except ValueError:
|
||||
return get_address(sym, binary_name, source_name), sym
|
||||
|
||||
|
||||
def get_address(name: str, binary: bool = None, source_name: bool = None) -> int:
|
||||
"""Finds the address of a symbol"""
|
||||
|
||||
args = [name]
|
||||
if binary is not None:
|
||||
args.append(f"-b {binary}")
|
||||
if source_name is not None:
|
||||
args.append(f"-n {source_name}")
|
||||
|
||||
raw = get_cmd_stdout(
|
||||
f"{SYMBOLSCRIPT} {SYMBOLS} --get-addr {' '.join(args)}")
|
||||
return json.loads(raw)
|
||||
|
||||
|
||||
def get_name(addr: int, binary: bool = None, source_name: bool = None) -> int:
|
||||
"""Finds the name of a symbol"""
|
||||
|
||||
args = [addr]
|
||||
if binary is not None:
|
||||
args.append(f"-b {binary}")
|
||||
if source_name is not None:
|
||||
args.append(f"-n {source_name}")
|
||||
|
||||
raw = get_cmd_stdout(
|
||||
f"{SYMBOLSCRIPT} {SYMBOLS} --get-name {' '.join(args)}")
|
||||
return json.loads(raw)
|
||||
|
||||
def find_headers(dirname: str, base=None) -> List[str]:
|
||||
"""Returns a list of all headers in a folder recursively"""
|
||||
|
||||
@ -138,6 +201,7 @@ ELF2DOL = f"{PYTHON} {PPCDIS}/elf2dol.py"
|
||||
FORCEACTIVEGEN = f"{PYTHON} {PPCDIS}/forceactivegen.py"
|
||||
SLICES = f"{PYTHON} {PPCDIS}/slices.py"
|
||||
PROGRESS = f"{PYTHON} {PPCDIS}/progress.py"
|
||||
SYMBOLSCRIPT = f"{PYTHON} {PPCDIS}/symbols.py"
|
||||
|
||||
# Codewarrior
|
||||
SDK_CW = os.path.join(TOOLS, "1.2.5")
|
||||
|
@ -4,47 +4,58 @@ Disassembles a single function
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from os import system, unlink
|
||||
import os.path
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
import common as c
|
||||
|
||||
def get_function(binary: c.Binary, srcflag: str, addr: int) -> str:
|
||||
# Get flags for binary
|
||||
if binary == c.Binary.DOL:
|
||||
binary = c.DOL_YML
|
||||
binflags = ""
|
||||
anlflags = f"{c.DOL_LABELS} {c.DOL_RELOCS}"
|
||||
else:
|
||||
binary = c.REL_YML
|
||||
binflags = c.PPCDIS_REL_FLAGS
|
||||
anlflags = f"{c.REL_LABELS} {c.REL_RELOCS}"
|
||||
|
||||
def get_function(binary: c.Binary, source: c.SourceDesc, addr: int, extra: bool, inline=False) -> str:
|
||||
# Get context
|
||||
ctx = c.DOL_CTX if binary == c.Binary.DOL else c.REL_CTX
|
||||
assert os.path.exists(ctx.labels), "Error: analysis has not ran!"
|
||||
|
||||
# Disassemble function
|
||||
with NamedTemporaryFile(suffix=".c", delete=False) as tmp:
|
||||
extraflag = "-e" if extra else ""
|
||||
srcflag = f"-n {source}" if isinstance(source, str) else ""
|
||||
inlineflag = "-i" if inline else ""
|
||||
with NamedTemporaryFile(suffix=".s", delete=False) as tmp:
|
||||
try:
|
||||
tmp.close()
|
||||
ret = system(
|
||||
f"{c.DISASSEMBLER} {binary} {anlflags} {tmp.name} -f {addr:x} "
|
||||
f"-m {c.SYMBOLS} {binflags} {srcflag} -q"
|
||||
f"{c.DISASSEMBLER} {ctx.binary} {ctx.labels} {ctx.relocs} {tmp.name} -f {addr:x} "
|
||||
f"-m {c.SYMBOLS} {srcflag} -q {extraflag} {inlineflag}"
|
||||
)
|
||||
assert ret == 0, f"Disassembly error code {ret}"
|
||||
with open(tmp.name) as f:
|
||||
asm = f.read()
|
||||
finally:
|
||||
unlink(tmp.name)
|
||||
|
||||
|
||||
return asm
|
||||
|
||||
if __name__=="__main__":
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser()
|
||||
hex_int = lambda s: int(s, 16)
|
||||
parser.add_argument("addr", type=hex_int)
|
||||
parser.add_argument("sym", type=str, help="Symbol name or address")
|
||||
parser.add_argument("-e", "--extra", action="store_true",
|
||||
help="Include referenced jumptables")
|
||||
parser.add_argument("-d", "--dol", action="store_true",
|
||||
help="Prioritise dol-local symbols")
|
||||
parser.add_argument("-r", "--rel", action="store_true",
|
||||
help="Prioritise rel-local symbols")
|
||||
parser.add_argument("-n", "--source-name", type=str,
|
||||
help="Prioritise source-local symbols")
|
||||
parser.add_argument("-i", "--inline", action="store_true",
|
||||
help="Output as inline assembly")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Find address
|
||||
assert not (args.dol and args.rel), "--dol and --rel are incompatible"
|
||||
addr = c.lookup_sym(args.sym, args.dol, args.rel, args.source_name)
|
||||
assert addr is not None, f"Symbol {args.sym} not found"
|
||||
|
||||
# Find containing binary
|
||||
binary, source = c.get_containing_slice(args.addr)
|
||||
binary, source = c.get_containing_slice(addr)
|
||||
|
||||
# Get source file name flag
|
||||
srcflag = f"-n {source}" if isinstance(source, str) else ""
|
||||
|
||||
print(get_function(binary, srcflag, args.addr))
|
||||
print(get_function(binary, source, addr, args.extra, args.inline))
|
||||
|
Loading…
Reference in New Issue
Block a user