Skip to content
DSG (Destitute Streetdwelling Guttersnipe) edited this page Aug 23, 2023 · 3 revisions

IPS File Format

converted from HTML at IPS File Format

IPS specifications.

IPS format was created a lot of time ago and so the specs for many people are too restrictive for the modern needs. Well, let see these specs.

  • IPS files can patch every file not larger than 2^24-1 bits (2047 Mb)
  • Every patch should not be larger than 2^16-1 bits (7.99 Mb)
  • An IPS file can hold as many patches he can, assumed that the specified offset and the size of every single patch doesn't overflow the specified bounds.

As you should realize it isn't so restrictive... 8 )

IPS file format

The IPS file structure is made just like that:

Section Size (Bytes) Description
Header 5 The header show ever the same string: PATCH note that the string is not NULL terminated.
Record 3+2+Variable It's the record of a single patch, see below
.... The numbers of record may vary
End Of file marker 3 A string (not NULL terminated) saying EOF

IPS Record structure:

Section Size (Bytes) Description
Offset 3 The offset where the patch will be placed in the file to patch
Size 2 The size of the data to put from the specified offset in the patching file
Data Size Contains a number of Size bytes of data to be copied in the file to patch

And that's the info you can find around. Now the technical stuff and RLE infos.

IPS RLE encoding

The next big step in the comprehension of the IPS format is that some patches can be RLE encoded to save space. The encoding is very simple but can easily be overlooked if someone is not aware of that. If when you read the size value of a record this field contains 0 you have a RLE encoded patch. You should read again a 16 bit value to obtain the size of the RLE patch and then you should read a single byte. This byte must be repeated as many times as the value of the second 16 bit read. An IPS RLE Record should look like that:

IPS RLE Record structure:

Section Size(Bytes) Description
Offset 3 Any Value
Size 2 0
RLE_Size 2 Any nonzero value
Value 1 This is the value to write RLE_Size times starting from Offset

Encoding Of Offset and Size

For peoples using low level languages a little bytes-swapping is needed to make read right the values of Offset and Size. These values are written linearly, just like Pascal and Basic does when handling numerical variables. The problem is that low level languages like ASM and C/C++ use the same endianess format of the machine, so every couple of two bytes are swapped. A 16 bit value is written like this in the IPS: 0x6712, a 24 bit value in this way: 0x671234. If read with a low level language they'll throw up: 0x1267 and 0x341267 respectively. Here two C macros that does the conversion after you read them. bp should be a char array:

#define BYTE3_TO_UINT(bp) \
     (((unsigned int)(bp)[0] << 16) & 0x00FF0000) | \
     (((unsigned int)(bp)[1] << 8) & 0x0000FF00) | \
     ((unsigned int)(bp)[2] & 0x000000FF)  
  
#define BYTE2_TO_UINT(bp) \
    (((unsigned int)(bp)[0] << 8) & 0xFF00) | \
    ((unsigned int) (bp)[1] & 0x00FF)

16 bit compiler users may find useful to substitute unsigned int to unsigned long in  the BYTE3_TO_UINT macro...

Real simple once someone has hacked the format for you, isn't it?

Z.e.r.o

IPS (International Patching System)

converted from HTML at IPS (binary patch format) - Just Solve the File Format Problem

IPS (binary patch format)

Name IPS (binary patch format)
Ontology Electronic File Formats
Archiving
IPS (binary patch format)
Extension(s) .ips
Released ≤ 1993

IPS is a simple format for binary file patches, popular in the ROM hacking community. "IPS" allegedly stands for "International Patching System". The original author of the format is unknown.

Structure

An IPS file starts with the magic number "PATCH" (50 41 54 43 48), followed by a series of hunks and an end-of-file marker "EOF" (45 4f 46). All numerical values are unsigned and stored big-endian.

Regular hunks consist of a three-byte offset followed by a two-byte length of the payload and the payload itself. Applying the hunk is done by writing the payload at the specified offset.

RLE hunks have their length field set to zero; in place of a payload there is a two-byte length of the run followed by a single byte indicating the value to be written. Applying the RLE hunk is done by writing this byte the specified number of times at the specified offset.

As an extension, the end-of-file marker may be followed by a three-byte length to which the resulting file should be truncated. Not every patching program will implement this extension, however.

Limitations and pitfalls

Due to its simplicity, the IPS format suffers from a number of problems:

  • Programs generating IPS files should avoid generating hunks with offset 0x454f46, as the byte encoding of this offset may be misinterpreted as the end-of-file marker. (One way to do it is to generate them with offset 0x454f45 and include the preceding byte.)
  • IPS patches are not reversible, unlike e.g. unified diffs: one cannot recover an unpatched binary from a patch file and a patched binary.
  • There are no integrity checks built into the IPS format. The responsibility to ensure that the patch is not corrupted, that the correct file is patched, and that the result of patching is valid falls upon the user.
  • The IPS format is next to impossible to extend in a backwards-compatible way; extending the format risks introducing misinterpretations which are often not even detectable by the patching software (given the above).
  • IPS patches cannot affect bytes beyond offset 16842750 (0x100fffe = 0xffffff + 0xffff); the IPS patch format may be therefore inadequate for files larger than 16 MiB.

External links