def getSource(name): files = list(filter(lambda x: name.lower() in x.name.lower(), getAsmFiles())) if len(files) > 1: print("Error: Ambiguous filename:", name) print("Please specify filename in greater detail.") for f in files: print(f) quit() if len(files) == 0: print("Error: No files including", name) quit() return files[0]
def fixAssembly(path): asmText = open(path).read() blocks = parseAsm(path) if ".text" not in blocks: return textBlock = blocks[".text"] newBlock = blocks[".text"] lines = textBlock.splitlines() funcs = getAllAsmFunctions(lines) globalRenames = [] for f in funcs: funcName = sanitizeLabel(f["name"]) if f["address"] not in textBlock: print("Already Decompiled", funcName) continue lbl = getAddressLabel(lines, f["address"]) if lbl != None and lbl == funcName: continue print(f["address"], f["scope"], lbl, funcName) if lbl == None: line = getFullLine(lines, "/* " + f["address"]) newLabel = "\n" + funcName + ":\n" newBlock = newBlock.replace(line, newLabel + line) print(line) pass else: # check to see if this is a global label if ".global " + lbl in textBlock: globalRenames.append({"old": lbl, "new": funcName}) line = getFullLine(lines, lbl + ":") newBlock = newBlock.replace(line, "\n" + line) newBlock = newBlock.replace(lbl, funcName) pass asmText = asmText.replace(textBlock, newBlock) open(path, "w").write(asmText) # replace global labels if len(globalRenames) > 0: files = getAsmFiles() for f in files: text = open(f).read() for r in globalRenames: text = text.replace(r["old"], r["new"]) open(f, "w").write(text)
from files import getAsmFiles from parseasm import * import os def separateAsm(filepath): sections = parseAsm(filepath) out = str(filepath).replace("\\asm\\", "\\data\\") text = open(filepath).read() print(out) for s in sections: if s != ".text": text = text.replace(sections[s], "") open(filepath, "w").write(text.strip() + "\n") f = open(out, "w+") for s in sections: if s != ".text": f.write(sections[s].strip() + "\n") f.close() for asm in getAsmFiles(): path = str(asm) if "Core" not in path and "Game" not in path: continue separateAsm(path)
def isGameFile(path): s = str(path) return "Game\\" in s or "Core\\" in s floatInstructions = sorted([ "fadd", "fadds", "fsub", "fsubs", "fmul", "fmuls", "fdiv", "fdivs", "fres", "frsqrte", "fsel", "fmadd", "fmadds", "fmsub", "fmsubs", "fnmadd", "fnmadds", "fnmsub", "fnmsubs", "frsp", "fctiw", "fctiwz", "fcmpu", "fcmpo", "mffs", "mcrfs", "mtfsfi", "mtfsf", "mtfsb0", "mtfsb1", "fmr", "fneg", "fabs", "fnabs", "psq_lx", "psq_lux", "psq_stx", "psq_stux", "psq_l", "psq_lu", "psq_st", "psq_stu" ]) files = list(filter(isGameFile, getAsmFiles())) def getShortestFuncs(dict, label, limit=20): funcs = dict[label] names = funcs.keys() result = sorted(names, key=lambda x: funcs[x])[:limit] return result lookup = {} addrs = {} for f in floatInstructions: lookup[f] = {}
from files import getAsmFiles fs = getAsmFiles() fs = sorted(fs, key=lambda x: -len(open(x).readlines())) for f in fs: print(f, len(open(f).readlines()))
def run(path): asms = getAsmFiles() fixAssembly(path) subprocess.run(["python", "inlineasm.py", path.name])