예제 #1
0
def ls(isoFile, directory=b"/", columns=None, size=False):
    with gciso.IsoFile(isoFile) as iso:
        files = list(iso.listDir(directory))

        if directory[-1] != b"/":
            directory += b"/"

        maxNameLen = 0
        for file in files:
            nameLen = len(file)
            if size:
                nameLen += len(" ({})".format(iso.fileSize(directory + file)))
            maxNameLen = max(maxNameLen, nameLen)
        colWidth = maxNameLen + 5  # 3 spaces and b''

        if columns == None:
            columns = int(100 / colWidth)  # assume 100 characters width

        colFmt = "{{!s:<{}}}".format(colWidth)
        for i in range(0, len(files), columns):
            printCols = min(columns, len(files) - i)
            fmt = colFmt * printCols
            params = files[i:i + printCols]
            if size:
                params = map(
                    lambda x: "{!s} ({})".format(x, iso.fileSize(directory + x)
                                                 ), params)
            print(fmt.format(*params))
예제 #2
0
def read(isoFile, internalFile, dstFile, offset=0, length=None, banner=False):
    with gciso.IsoFile(isoFile) as iso:
        if banner:
            banner = iso.getBannerFile(internalFile)
            banner.getPILImage().save(dstFile)
        else:
            with open(dstFile, "wb") as dst:
                dst.write(iso.readFile(internalFile, offset, length))
예제 #3
0
def isoInfo(isoFile):
    with gciso.IsoFile(isoFile) as iso:
        print("Game Code:", iso.gameCode)
        print("Maker Code:", iso.makerCode)
        print("Disk Id:", iso.diskId)
        print("Version:", iso.version)
        print("Game Name:", iso.gameName)
        print()
        print("DOL offset:", _h(iso.dolOffset))
        print("DOL size:", _h(iso.dolSize))
        print("FST offset:", _h(iso.fstOffset))
        print("FST Size:", _h(iso.fstSize))
        print("Max FST Size:", _h(iso.maxFstSize))
        print("FST Entries:", _h(iso.numFstEntries))
        print()
        print("Apploader Date:", iso.apploaderDate)
        print("Apploader Entry Point:", _h(iso.apploaderEntryPoint))
        print("Apploader Code Size:", _h(iso.apploaderCodeSize))
        print("Apploader Trailer Size:", _h(iso.apploaderTrailerSize))
예제 #4
0
def bannerInfo(file, fileName=b"opening.bnr"):
    if file.endswith(".iso"):
        with gciso.IsoFile(file) as iso:
            banner = iso.getBannerFile(fileName)
    elif file.endswith(".bnr"):
        with open(file, "rb") as bannerFile:
            banner = gciso.BannerFile(bannerFile.read())
    else:
        quit("File extension must be .bnr or .iso!")

    print("Magic Bytes:", banner.magicBytes)
    metas = banner.meta
    if isinstance(metas, gciso.BannerFile.MetaData):
        metas = [metas]
    for i, meta in enumerate(metas):
        print("\nMetadata {}:".format(i))
        print("Game Name:", meta.gameName)
        print("Developer Name:", meta.developerName)
        print("Full Game Title:", meta.fullGameTitle)
        print("Full Developer Name:", meta.fullDeveloperName)
        print("Game Description:", meta.gameDescription)
예제 #5
0
def dolInfo(file, fileName=b"start.dol", order=None):
    if file.endswith(".iso"):
        with gciso.IsoFile(file) as iso:
            dol = iso.getDolFile(fileName)
    elif file.endswith(".dol"):
        with open(file, "rb") as dolFile:
            dol = gciso.DolFile(dolFile.read())
    else:
        quit("File extension must be .bnr or .iso!")

    print("BSS Memory Address: 0x{:x}".format(dol.bssMemAddress))
    print("BSS Size: 0x{:x}".format(dol.bssSize))
    print("Entry Point: 0x{:x}".format(dol.entryPoint))

    if order == None: order = SectionOrder.FILE
    assert isinstance(order, SectionOrder)
    if order == SectionOrder.FILE:
        sections = dol.sections
    elif order == SectionOrder.DOL_OFFSET:
        sections = dol.sectionsDolOrder
    elif order == SectionOrder.MEM_ADDRESS:
        sections = dol.sectionsMemOrder

    print("\nSections:")
    for i, section in enumerate(sections):
        print(
            "{} {} - DOL: {:>8} to {:>8}, Memory: 0x{:x} to 0x{:x} (size: 0x{:x})"
            .format(section.type.value, section.index, _h(section.dolOffset),
                    _h(section.endDolOffset), section.memAddress,
                    section.endMemAddress, section.size))
        if i + 1 < len(sections):
            if order == SectionOrder.DOL_OFFSET:
                gap = sections[i + 1].dolOffset - section.endDolOffset
                if gap > 0:
                    print("Gap (DOL): 0x{:x}".format(gap))
            if order == SectionOrder.MEM_ADDRESS:
                gap = sections[i + 1].memAddress - section.endMemAddress
                if gap > 0:
                    print("Gap (memory): 0x{:x}".format(gap))
예제 #6
0
    gciso = None

parser = argparse.ArgumentParser(
    description="Apply patch data to .dat file or .iso file.")
parser.add_argument("patchfile", help="The patch json file.")
parser.add_argument("targetfile",
                    help="The .dat/.iso file to apply the patch to.")
args = parser.parse_args()

with open(args.patchfile) as f:
    patchData = json.load(f)

if args.targetfile.lower().endswith(".iso"):
    if not gciso:
        quit("The gciso module must be installed to patch .iso files!")
    with gciso.IsoFile(args.targetfile) as isoFile:
        for file in patchData:
            filePatch = patchData[file]
            for i in range(0, len(filePatch), 2):
                offset, data = filePatch[i + 0], filePatch[i + 1]
                data = bytes.fromhex(data)
                isoFile.writeFile(file.encode("ascii"), offset, data)
elif args.targetfile.lower().endswith(".dat"):
    fileBase = os.path.basename(args.targetfile)
    if fileBase not in patchData:
        quit("No patch data for '{}'!".format(fileBase))
    filePatch = patchData[fileBase]
    with open(args.targetfile, "r+b") as f:
        for i in range(0, len(filePatch), 2):
            offset, data = filePatch[i + 0], filePatch[i + 1]
            data = bytes.fromhex(data)
예제 #7
0
def write(isoFile, internalFile, srcFile, offset=0, banner=False):
    if banner:
        raise NotImplementedError("Writing banners is not implemented yet!")
    with gciso.IsoFile(isoFile) as iso, open(srcFile, "rb") as src:
        iso.writeFile(internalFile, offset, srcFile.read())
예제 #8
0
 def setUp(self):
     self.isoFile = gciso.IsoFile(ISO_PATH)