Werewolf file: NES cartridge image and ZIP file in one

Original author: ViGrey
  • Transfer
This file is the NES console ROM . And at the same time a zip file. It is simultaneously fully functional both as an NES ROM and as a ZIP file.

What is in this zip file? The source code of the ROM.

What happens if you compile this source code? He will create an NES ROM, which is also a ZIP file containing the source code for this NES ROM.

Launched ROM

This NES ROM can be burned onto the NES cartridge and it will work on the NES. Even if you convert all the data from the cartridge, the NES image will still be a ZIP file.

Source of inspiration

The 0x14 release of PoC || GTFO was both a PDF, a ZIP file, and an NES ROM. It was this issue that inspired me to create an NES game from scratch for Tymkrs .

The method I used to create the NES ROM, which is also a ZIP file, is NOT the same method that was used in issue 0x14 PoC || GTFO . My method embeds the ZIP file in the NES ROM and allows you to write the NES image to the cartridge, saving the data of the ZIP file. In the method used by PoC || GTFO, the ZIP file data is stored outside the ROM NES file, therefore, the 0x14 PoC || GTFO release cannot be written to the cartridge with the ZIP file saved.

NES ROM File Format

This NES image uses the iNES file format. The iNES file format is actually quite simple.

At the beginning of the ROM, there is an iNES header that provides some information about the NES ROM so that emulators can understand the NES image data. The iNES header is followed by PRG data, which is NES ROM program logic data. Then comes the CHR data, i.e. sets of background tiles and sprites. All empty space in the PRG is filled with indentation, in addition, there can be several bytes at the end of the PRG data (in this NES ROM there are 6 necessary bytes at the end of the PRG data, which I can not change).

INES File Format

ZIP file format

There are a lot of components in ZIP files, so we will focus on the parts that are important to us.

For each file and directory contained in the ZIP file, there is a central directory file header (Central Directory File Header). You can find any header for the central directory file by searching for bytes of the signature signature 0x504B0102 in the ZIP file. An important piece of information is the local header offset (Local Header Offset), because when we embed a ZIP file in NES ROM, we will change each offset.

Central directory file header format. ZIP

ZIP files determine their beginning and end, going to the end of the file and moving to the beginning, until they reach the bytes 0x504B0506 of the signature of the end of the Central Directory Record. When embedding a ZIP file in NES ROM, it’s important for us to update the Central Directory Offset at the end of the central directory entry. We can also specify the comment length of the ZIP file (ZIP File Comment Length) and this number of bytes after the end of the data of the ZIP file will be the comment of the ZIP file.

ZIP Central Directory End Format

Hiding the ZIP file in NES ROM

If we find enough indentation in the PRG data, we can simply replace this empty data with a ZIP file. In my NES ROM, I counted the indentation bytes from the end of the PRG data until I got enough space to embed the ZIP file and wrote down how far I started embedding the ZIP file in NES ROM. Then I updated all the offsets of the data of the ZIP file, adding the distance at which the ZIP file begins in the NES image. After that, I set the comment length of the ZIP file to be equal to the size of the remaining part of the NES ROM data, that is, the end of the PRG data and all the CHR data.

NESZIP file format

This file remains an NES image because none of the required PRG data and CHR data are corrupted. It is also a zip file because all offsets are correct and all data after the zip file data is declared a comment of the zip file.

Let's test the file first to make sure it is both an NES ROM and a ZIP file. After downloading the file as NES ROM, I make a copy of it.

Copy of NES ROM

Renaming the file allows me to change the extension from .nes to .zip.

Change the extension of the copy of NES ROM to .zip

After replacing the extension with .zip, the file is considered a ZIP file.

When unpacking this file, a directory is created.

If we look at the contents of the directory, we will see the source code of the file. We just took the NES ROM, renamed it to a ZIP file, and successfully unpacked it.

Updating the data offsets of the zip file, I decided to have some fun with this zip file. The headings of the central directory files indicate the OS (Host OS) in which the ZIP file was created, so I decided to make the ZIP file claim to be created on Atari ST.

Create recursion

In fact, this part is the simplest. The packaged source code became a zip file small enough to be easily integrated into NES ROM, so I decided to make NES / ZIP recursive. To automate the process of creating a ZIP file of source code or to automate the process of embedding a ZIP file in NES ROM, it took not so much work.

To summarize

This project is a simple proof of concept, demonstrating the ability to embed a ZIP file in NES ROM in a way that creates a file that simultaneously becomes both a ZIP file and an NES image, and allows you to write data to a cartridge while preserving all their properties.

Since I decided to make this NES ROM compatible with NES-NROM-128 circuit boards (because of their simplicity), the process will work for almost any NES ROM if there are enough indentation in the PRG data to embed the ZIP file in it.

To implement this process on other NES ROMs, additional work may be required because different assemblers 6502 can indent PRG data in different ways. I have not tested this method with more complex NES games with bank switching. Also, I have not tested the ability to add padding to the size of PRG data to embed larger ZIP files.

With all that said, don't be surprised if I give you an NES cartridge with a secret ZIP file hidden in NES ROM data.


The source code for this project is uploaded to GitHub (or you can get it by unpacking the NES ROM file) and has a BSD 2-Clause License.

Also popular now: