def asmPatch(file, workfolder, banks=[0x0], banksize=0x4000): common.logMessage("Applying ASM patch ...") wlagb = common.bundledExecutable("wla-gb.exe") if not os.path.isfile(wlagb): common.logError("wla-gb not found") return wlalink = common.bundledExecutable("wlalink.exe") if not os.path.isfile(wlalink): common.logError("wlalink not found") return # Create the output file ofile = file.replace(".asm", ".o") if os.path.isfile(ofile): os.remove(ofile) common.execute( wlagb + " -o {ofile} {binpatch}".format(binpatch=file, ofile=ofile), False) if not os.path.isfile(ofile): return # Run the linker and create a temporary patched ROM tempfile = file.replace(".asm", ".txt") deletetemp = False if not os.path.isfile(tempfile): deletetemp = True with open(tempfile, "w") as f: f.write("[objects]\n") f.write(ofile + "\n") temprom = "temprom.gb" common.execute( wlalink + " -r {tempfile} {temprom}".format(tempfile=tempfile, temprom=temprom), False) if deletetemp: os.remove(tempfile) os.remove(ofile) # Extract the banks we're interested in from the temp ROM with common.Stream(temprom, "rb") as f: for i in banks: bankname = "bank_" if i < 0x10: bankname += "0" bankname += format(i, 'x') f.seek(i * banksize) with common.Stream(workfolder + bankname + ".bin", "wb") as fout: fout.write(f.read(banksize)) os.remove(temprom) common.logMessage("Done!")
def extractBRFNT(infile, outfile): brfnt2tpl = common.bundledExecutable("brfnt2tpl.exe") if not os.path.isfile(brfnt2tpl): common.logError("brfnt2tpl not found") return common.execute(brfnt2tpl + " {file}".format(file=infile), False) common.execute( "wimgt DECODE " + infile.replace(".brfnt", ".tpl") + " -D " + outfile, False) os.remove(infile.replace(".brfnt", ".tpl")) os.remove(infile.replace(".brfnt", ".vbfta"))
def signBIN(binout, ebinout, tag): common.logMessage("Signing BIN ...") sign_np = common.bundledExecutable("sign_np.exe") if not os.path.isfile(sign_np): common.logMessage("sign_np not found, copying BOOT to EBOOT...") common.copyFile(binout, ebinout) else: common.execute( sign_np + " -elf {binout} {ebinout} {tag}".format( binout=binout, ebinout=ebinout, tag=str(tag)), False) common.logMessage("Done!")
def extractRom(romfile, extractfolder, workfolder=""): common.logMessage("Extracting ROM", romfile, "...") ndstool = common.bundledExecutable("ndstool.exe") if not os.path.isfile(ndstool): common.logError("ndstool not found") return common.makeFolder(extractfolder) common.execute(ndstool + " -x {rom} -9 {folder}arm9.bin -7 {folder}arm7.bin -y9 {folder}y9.bin -y7 {folder}y7.bin -t {folder}banner.bin -h {folder}header.bin -d {folder}data -y {folder}overlay". format(rom=romfile, folder=extractfolder), False) if workfolder != "": common.copyFolder(extractfolder, workfolder) common.logMessage("Done!")
def repackRom(romfile, rompatch, workfolder, patchfile=""): common.logMessage("Repacking ROM", rompatch, "...") ndstool = common.bundledExecutable("ndstool.exe") if not os.path.isfile(ndstool): common.logError("ndstool not found") return common.execute(ndstool + " -c {rom} -9 {folder}arm9.bin -7 {folder}arm7.bin -y9 {folder}y9.bin -y7 {folder}y7.bin -t {folder}banner.bin -h {folder}header.bin -d {folder}data -y {folder}overlay". format(rom=rompatch, folder=workfolder), False) common.logMessage("Done!") # Create xdelta patch if patchfile != "": common.xdeltaPatch(patchfile, romfile, rompatch)
def repackBRFNT(outfile, workfile): brfnt2tpl = common.bundledExecutable("brfnt2tpl.exe") if not os.path.isfile(brfnt2tpl): common.logError("brfnt2tpl not found") return common.execute(brfnt2tpl + " {file}".format(file=outfile), False) tplfile = outfile.replace(".brfnt", ".tpl") tpl = readTPL(tplfile) writeTPL(tplfile, tpl, workfile) common.execute( brfnt2tpl + " {file}".format(file=outfile.replace(".brfnt", ".tpl")), False) os.remove(outfile.replace(".brfnt", ".tpl")) os.remove(outfile.replace(".brfnt", ".vbfta"))
def repackUMD(isofile, isopatch, workfolder, patchfile=""): common.logMessage("Repacking ISO", isopatch, "...") common.copyFile(isofile, isopatch) umdreplace = common.bundledExecutable("UMD-replace.exe") if not os.path.isfile(umdreplace): common.logError("UMD-replace not found") return files = common.getFiles(workfolder) for file in common.showProgress(files): common.execute( umdreplace + " \"{imagename}\" \"/{filename}\" \"{newfile}\"".format( imagename=isopatch, filename=file, newfile=workfolder + file), False) common.logMessage("Done!") # Create xdelta patch if patchfile != "": common.xdeltaPatch(patchfile, isofile, isopatch)
def run(asmfile): # Support a syntax similar to armips, but simplified: # .open file: opens a file # .org 0x100: seek opened file to 0x100 # Everything between this and the next .org/.close # is compiled and wrote to the file with nasm # .import 0x200 file: imports the specified file and writes it to the address # .close: close the opened file (required) tempfile = "asm.tmp" tempout = "asm.bin" with codecs.open(asmfile, "r", "utf-8") as asmf: lines = asmf.readlines() currf = None i = 0 while i < len(lines): line = lines[i].strip() if line == ".close": common.logDebug("Closing file") if currf is not None: currf.close() currf = None elif line.startswith(".open"): parameters = shlex.split(line[5:].strip()) filename = parameters[0] common.logDebug("Opening file", filename) if not os.path.isfile(filename): common.logError("File", filename, "not found.") break currf = common.Stream(filename, "rb+").__enter__() elif line.startswith(".import"): filename = line[7:].strip() parameters = shlex.split(line[7:].strip()) filename = parameters[1] if not os.path.isfile(filename): common.logError("File", filename, "not found.") break importpos = parameters[0] if importpos.startswith("0x"): importpos = int(importpos.replace("0x", ""), 16) else: importpos = int(importpos) currf.seek(importpos) with common.Stream(filename, "rb") as importfile: currf.write(importfile.read()) elif line.startswith(".org"): orgpos = line[4:].strip() if orgpos.startswith("0x"): orgpos = int(orgpos.replace("0x", ""), 16) else: orgpos = int(orgpos) common.logDebug("Seeking to", orgpos) currf.seek(orgpos) # Read up until the next .org or .close and send to nasm j = i + 1 nasmlines = "[BITS 16]\ncpu 186\norg " + str(orgpos) + "\n" while j < len(lines): nasmline = lines[j].strip() if nasmline.startswith(".org") or nasmline.startswith( ".close") or nasmline.startswith(".import"): i = j - 1 break else: if nasmline != "" and not nasmline.startswith(";"): nasmlines += nasmline + "\n" j += 1 common.logDebug("NASM lines:", nasmlines.strip().replace("\n", " | ")) # Write the nasm lines to a file and compile them with codecs.open(tempfile, "w", "utf-8") as tempf: tempf.write(nasmlines) nasm = common.bundledExecutable("nasm.exe") common.execute(nasm + " -O1 -o " + tempout + " -f bin " + tempfile, False) # Read the temp file and write it to the opened one with common.Stream(tempout, "rb") as tempf: currf.write(tempf.read()) os.remove(tempfile) os.remove(tempout) i += 1 if currf is not None: currf.close()