This document describes a preliminary version of a text-based file format designed for small patches to binary files. The format is derived from JSON. Readers are invited to comment and help shape its direction.
Having the ability to make small patches to binary files can be valuable in situations where a user needs to make changes to a program, particularly to hard-coded strings or "magic numbers," but does not have access to the source code.
Traditionally, binary patch formats have been fairly rigid. The Verbose Interactive Patch (VIP) format attempts to expand on existing formats in a few ways. The format is designed to be:
-
Verbose.
-
Instead of binary files, use text, so patches are easy to read, write, and understand.
-
Patches are self-documenting; they include human-readable information explaining what they do.
-
-
Interactive.
-
Patches may have many variants, or "options."
-
Patches may instruct the patcher to collect data from the user during the patching process.
-
-
Manageable.
-
Patches must provide the original data at all patched locations, so the patch can be reverted by the user.
-
Patchers may detect the current patched state of the target file by comparing each patch option to the target data.
-
Patches are stored in a plain-text, JSON compatible format.
The root object is structured as follows:
-
title :
string
The title of this patch.
-
version :
string | number
Version of this patch.
-
author :
string
Author of this patch.
-
contributors :
Array.<string>
If you make significant changes to a patch, list yourself as the author and move the previous author to the end of this list.
-
publisher :
string
Patch publisher. If you convert a patch from another format without making significant changes, list yourself as the publisher.
-
target :
string
Absolute path to the file to be patched. Implementations may treat this as a suggestion, and prompt the user for an alternate path if the file is not present.
-
initial :
Object
Stores the unpatched state of the target file. Implementations must allow the user to revert the patch to this state.
- ***(offset)* : `Array.<string>` ...** Array of bytes originally stored at each location in the file that can be modified by this patch.
-
options :
Object
Each variation of the patch is stored as an option.
- ***(option name)* : `Object` ...** Each option is composed of *fragments*. - ***(offset)* : `Array | Object` ...** Each fragment can be a literal array of bytes, like `initial`, or it can "interactive." See "Interactive fragments."
{
"title": "More cowbell",
"version": 0.9,
"author": "J. Doe",
"target": "/foo/bar/baz.so",
"initial": {
"9b1ec": ["d0", "f8", "50", "0a"]
},
"options": {
"5 cowbells" : {
"9b1ec": [6, "20", "00", "bf"]
},
"6 cowbells" : {
"9b1ec": [7, "20", "00", "bf"]
},
"7 cowbells" : {
"9b1ec": [8, "20", "00", "bf"]
}
}
}