Beispiel #1
0
def main() -> int:
    # Create the argument parser
    parser = argparse.ArgumentParser(
        description="Utility for attaching a trojan to a commercial Naomi ROM.",
    )
    parser.add_argument(
        'bin',
        metavar='BIN',
        type=str,
        help='The binary file we should attach the trojan to.',
    )
    parser.add_argument(
        'exe',
        metavar='EXE',
        type=str,
        help=
        'The executable binary blob we should attach to the end of the commercial ROM.',
    )
    parser.add_argument(
        '--offset',
        type=str,
        default='0x0c021000',
        help=
        'Where to attach the springboard, in main memory. This is the hook for the trojan.',
    )
    parser.add_argument(
        '--output-file',
        metavar='BIN',
        type=str,
        help=
        'A different file to output to instead of updating the binary specified directly.',
    )

    # Grab what we're doing
    args = parser.parse_args()

    # Grab the rom, parse it
    with open(args.bin, "rb") as fp:
        data = fp.read()
    naomi = NaomiRom(data)

    # Grab the attachment. This should be an executable binary blob. The easiest way to get
    # one of these is to compile a program using the toolchain in the homebrew/ directory,
    # and then copy out the naomi.bin file from the build/ directory and use that. Note that
    # in order to use this method, you will want to change the two executable start
    # addresses in naomi.ld to 0x0D000000 or any non-relative jumps will go to the wrong
    # code. Note also that if the game uses this address, you will run into trouble. You
    # might need to code a different springboard to a safe memory region if you run into
    # trouble using 0x0D000000.
    with open(args.exe, "rb") as fp:
        exe = fp.read()

    # Grab the springboard file. This was made by compiling the following
    # SH-4 code and then extracting the executable bytes.
    """
    .section .text
    .globl start

start:
    # Jump to location 0x0D000000
    mov #13,r0
    shll16 r0
    shll8 r0
    jmp @r0
    nop
    """
    springfile = bytes(
        [0x0d, 0xe0, 0x28, 0x40, 0x18, 0x40, 0x2b, 0x40, 0x09, 0x00])

    # We need to add a EXE init section to the ROM
    executable = naomi.main_executable
    patchoffset = executable.sections[0].load_address - executable.sections[
        0].offset
    if len(executable.sections) >= 8:
        print("ROM already has the maximum number of init sections!",
              file=sys.stderr)
        return 1

    for sec in executable.sections:
        if sec.load_address == 0x0D000000:
            print("ROM already is trojan'd, cowardly giving up!",
                  file=sys.stderr)
            return 1

    # Add a new section to the end of the rom for this binary data
    executable.sections.append(
        NaomiRomSection(
            offset=len(data),
            load_address=0x0D000000,
            length=len(exe),
        ))
    naomi.main_executable = executable

    # Now, just append it to the end of the file
    newdata = change(
        naomi.data + data[naomi.HEADER_LENGTH:] + exe,
        springfile,
        int(args.offset, 16) - patchoffset,
    )

    if args.output_file:
        print(f"Added trojan to the end of {args.output_file}.",
              file=sys.stderr)
        with open(args.output_file, "wb") as fp:
            fp.write(newdata)
    else:
        print(f"Added trojan to the end of {args.bin}.", file=sys.stderr)
        with open(args.bin, "wb") as fp:
            fp.write(newdata)

    return 0
Beispiel #2
0
def main() -> int:
    # Create the argument parser
    parser = argparse.ArgumentParser(description=(
        "Utility for attaching an SRAM dump to an Atomiswave conversion Naomi ROM. "
        "Use this to set up preferred settings in an emulator, and then send those "
        "settings to your Naomi when you netboot."), )
    parser.add_argument(
        'bin',
        metavar='BIN',
        type=str,
        help='The binary file we should attach the SRAM to.',
    )
    parser.add_argument(
        'sram',
        metavar='SRAM',
        type=str,
        help='The SRAM file we should attach to the binary.',
    )
    parser.add_argument(
        '--output-file',
        metavar='BIN',
        type=str,
        help=
        'A different file to output to instead of updating the binary specified directly.',
    )

    # Grab what we're doing
    args = parser.parse_args()

    # Grab the rom, parse it
    with open(args.bin, "rb") as fp:
        data = fp.read()
    naomi = NaomiRom(data)

    # Grab the SRAM
    with open(args.sram, "rb") as fp:
        sram = fp.read()
    if len(sram) != SRAM_SIZE:
        print(f"SRAM file is not the right size, should be {SRAM_SIZE} bytes!",
              file=sys.stderr)
        return 1

    # First, find out if there's already an SRAM portion to the file
    executable = naomi.main_executable
    for section in executable.sections:
        if section.load_address == SRAM_LOCATION:
            # This is a SRAM load chunk
            if section.length != SRAM_SIZE:
                print("Found SRAM init section, but it is the wrong size!",
                      file=sys.stderr)
                return 1

            # We can just update the data to overwrite this section
            newdata = data[:section.offset] + sram + data[(section.offset +
                                                           section.length):]
            break
    else:
        # We need to add a SRAM init section to the ROM
        if len(executable.sections) >= 8:
            print("ROM already has the maximum number of init sections!",
                  file=sys.stderr)
            return 1

        # Add a new section to the end of the rom for this SRAM section
        executable.sections.append(
            NaomiRomSection(
                offset=len(data),
                load_address=SRAM_LOCATION,
                length=SRAM_SIZE,
            ))
        naomi.main_executable = executable

        # Now, just append it to the end of the file
        newdata = naomi.data + data[naomi.HEADER_LENGTH:] + sram

    if args.output_file:
        print(f"Added SRAM init to the end of {args.output_file}.",
              file=sys.stderr)
        with open(args.output_file, "wb") as fp:
            fp.write(newdata)
    else:
        print(f"Added SRAM init to the end of {args.bin}.", file=sys.stderr)
        with open(args.bin, "wb") as fp:
            fp.write(newdata)

    return 0