Exemple #1
0
 def tostring_lz77(self):
     with open('tileset_temp.bin', 'wb') as f_temp:
         f_temp.write(self.to_bytes())
     nlzss.encode_file('tileset_temp.bin', 'tileset_temp_nlzss.bin')
     _, s = bin2c.bin2c('tileset_temp_nlzss.bin').split("=")
     os.remove('tileset_temp.bin')
     os.remove('tileset_temp_nlzss.bin')
     return s
Exemple #2
0
def lz77_compress_data(data: bytes):
    with open('uncomp_data_temp.bin', 'wb') as f_temp:
        f_temp.write(data)
    nlzss.encode_file('uncomp_data_temp.bin', 'lzcomp_data_temp.bin')
    with open('lzcomp_data_temp.bin', 'rb') as f_temp:
        data = f_temp.read()
    os.remove('lzcomp_data_temp.bin')
    os.remove('uncomp_data_temp.bin')
    return data
Exemple #3
0
def sign_file(name):
    final = name + '.bin'
    print("Processing " + final + " ...")
    file = open(name, 'rb')
    copy = file.read()
    file.close()
    print("Calculating CRC32 ...")
    crc32 = format(binascii.crc32(copy) & 0xFFFFFFFF, '08x')
    print("Calculating Size ...")
    size = os.path.getsize(name) + 12
    dest = open(final + '-1', 'wb+')
    dest.write(u32(0))
    dest.write(u32(size))
    dest.write(binascii.unhexlify(crc32))
    dest.write(copy)
    os.remove(name)
    dest.close()
    print("Compressing ...")
    nlzss.encode_file(final + '-1', final + '-1')
    file = open(final + '-1', 'rb')
    new = file.read()
    dest = open(final, "wb+")
    key = open(config["key_path"], 'rb')
    print("RSA Signing ...")
    private_key = rsa.PrivateKey.load_pkcs1(key.read(),
                                            "PEM")  # Loads the RSA key.
    signature = rsa.sign(new, private_key,
                         "SHA-1")  # Makes a SHA1 with ASN1 padding. Beautiful.
    dest.write(
        b"\0" * 64
    )  # Padding. This is where data for an encrypted WC24 file would go (such as the header and IV), but this is not encrypted so it's blank.
    dest.write(signature)
    dest.write(new)
    dest.close()
    file.close()
    key.close()
    if config["production"]:
        if file_type == "q" or file_type == "r":
            if arg == "n":
                folder = str(country_code).zfill(3)
            elif arg == "w":
                folder = "world"
            subprocess.call([
                "mkdir", "-p",
                "%s/%s/%s" % (config["file_path"], folder, get_year())
            ])  # If folder for the year does not exist, make it.
            path = "/".join([config["file_path"], folder, get_year(), final])
        elif file_type == "v":
            path = "/".join(
                [config["file_path"],
                 str(country_code).zfill(3), final])
    subprocess.call(["mv", final, path])
    os.remove(final + '-1')
Exemple #4
0
def write_dictionary(mode):
    for dictionary in dictionaries:
        for name, value in dictionary.items():
            with open(newsfilename + "-1", "ba+") as dest_file:
                dest_file.write(value)

    with open(newsfilename + "-1", "rb") as source_file:
        read = source_file.read()

    with open(newsfilename, "bw+") as dest_file:
        dest_file.write(u32(512))
        dest_file.write(u32(len(read) + 12))
        dest_file.write(
            binascii.unhexlify(format(binascii.crc32(read) & 0xFFFFFFFF, "08x"))
        )
        dest_file.write(read)

    if config["production"]:
        nlzss.encode_file(newsfilename, newsfilename)

        with open(newsfilename, "rb") as source_file:
            read = source_file.read()

        with open(config["key_path"], "rb") as source_file:
            private_key_data = source_file.read()

        private_key = rsa.PrivateKey.load_pkcs1(private_key_data, "PEM")

        signature = rsa.sign(read, private_key, "SHA-1")

        with open(newsfilename, "wb") as dest_file:
            dest_file.write(binascii.unhexlify("0".zfill(128)))
            dest_file.write(signature)
            dest_file.write(read)

    # Remove the rest of the other files

    os.remove(newsfilename + "-1")

    print("\n")
    print("Wrote " + newsfilename)
Exemple #5
0
 def compress(self):
     nlzss.encode_file(self.filename, self.filename)
Exemple #6
0
    def post(request):
        """Pack uploaded ROM into the provided WAD file as downloaded file."""
        if not request.FILES.get('rom'):
            return HttpResponseBadRequest("ROM file not provided")
        elif not request.FILES.get('wad'):
            return HttpResponseBadRequest("WAD file not provided")

        with tempfile.TemporaryDirectory() as dumpdir:
            romfile = os.path.join(dumpdir, 'rom.sfc')
            with open(romfile, 'wb') as f:
                shutil.copyfileobj(request.FILES['rom'], f)

            # Compress ROM file for US and EU (not JP)
            rom_to_copy = romfile
            if request.POST.get('region') in ('US', 'EU'):
                romcompressed = os.path.join(dumpdir, 'rom_compressed.sfc')
                nlzss.encode_file(romfile, romcompressed)
                rom_to_copy = romcompressed

            # Dump WAD file
            wadf = Wii.WAD.load(request.FILES['wad'].read())
            wadf.dumpDir(dumpdir)

            # Dump U8 archive
            u8file = os.path.join(dumpdir, '00000005.app')
            u8unpackdir = u8file + '_unpacked'
            u8archive = Wii.U8.loadFile(u8file)
            u8archive.dumpDir(u8unpackdir)

            # Copy randomized ROM over
            for f in os.listdir(u8unpackdir):
                if f.lower().endswith(".rom"):
                    wadrom = os.path.join(u8unpackdir, f)
                    shutil.copyfile(rom_to_copy, wadrom)
                    break

            # Put U8 archive back together
            newu8 = Wii.U8.loadDir(u8unpackdir)
            newu8.dumpFile(u8file)

            # Build new WAD
            newwadfile = os.path.join(dumpdir, 'smrpg_randomized.wad')
            newwad = Wii.WAD.loadDir(dumpdir)

            # Make new channel title with seed (sync for all languages).
            # Read title from ROM and make sure it's in the correct spot.  If not, leave the title alone.
            with open(romfile, 'rb') as f:
                f.seek(0x7fc0)
                title = f.read(20).strip()
                title = title.ljust(20)

            if not title.startswith(b'SMRPG-R'):
                return HttpResponseBadRequest(
                    "Bad ROM title {!r}".format(title))

            try:
                seed = int(title[7:].strip())
            except ValueError:
                return HttpResponseBadRequest(
                    "Bad ROM title {!r}".format(title))

            # Read first content file data to find the channel title data and update it.
            if newwad.contents[0][0x80:0x84] != b'IMET':
                return HttpResponseBadRequest(
                    "Can't find IMET in WAD contents file")

            imetpos = 0x80
            content = bytearray(newwad.contents[0])

            # Channel names start 29 bytes after the "IMET" string, and there are 7 of them in a row.
            jpos = imetpos + 29
            for i in list(range(7)):
                for j, char in enumerate(title):
                    pos = jpos + (i * 84) + (j * 2)
                    content[pos] = char

            # Update MD5 hash for this content file.
            data = content[64:1584]
            data += b'\x00' * 16
            md5 = Wii.Crypto.createMD5Hash(data)
            for i in range(16):
                content[1584 + i] = md5[i]

            newwad.contents[0] = bytes(content)

            # Generate random title ID for the WAD that doesn't conflict with existing channels.
            choices = list(string.ascii_letters + string.digits)
            # The first character of the four byte title ID should exclude existing ones to avoid conflicts.
            first_char_choices = list(
                set(choices) - {
                    'C', 'D', 'E', 'F', 'G', 'H', 'J', 'L', 'M', 'N', 'P', 'Q',
                    'R', 'S', 'W', 'X'
                })
            first_char_choices.sort()

            random.seed(seed)
            new_id = bytearray([
                0x00, 0x01, 0x00, 0x01,
                ord(random.choice(first_char_choices))
            ])
            for i in range(3):
                new_id.append(ord(random.choice(choices)))

            tid = int.from_bytes(new_id, 'big')
            newwad.tmd.setTitleID(tid)
            newwad.tik.setTitleID(tid)

            newwad.dumpFile(newwadfile, fakesign=False)

            # Return new WAD file
            response = HttpResponse(open(newwadfile, 'rb'),
                                    content_type='application/octet-stream')
            response[
                'Content-Disposition'] = 'attachment; filename="smrpg.wad"'
            return response
Exemple #7
0
                    type=str,
                    nargs="+",
                    help="AES IV in hex or a path.")
parser.add_argument(
    "-rsa",
    "--rsa-key-path",
    type=str,
    nargs="+",
    help=
    "RSA private key path. If not specified, it will use the private key in Private.pem if it exists."
)

args = parser.parse_args()

if args.compress is not None:
    encode_file(in_path=args.input[0], out_path="temp")
    filename = "temp"
else:
    filename = args.input[0]

with open(filename, "rb") as f:
    data = f.read()

if args.rsa_key_path is not None:
    rsa_key_path = args.rsa_key_path[0]
else:
    rsa_key_path = "Private.pem"

with open(rsa_key_path, "rb") as source_file:
    private_key_data = source_file.read()