Skip to content

Instantly share code, notes, and snippets.

@gitbuh
Created June 16, 2012 18:02
Show Gist options
  • Save gitbuh/2942105 to your computer and use it in GitHub Desktop.
Save gitbuh/2942105 to your computer and use it in GitHub Desktop.
VIP - Verbose Interactive Patch

VIP - Verbose Interactive Patch Format

Introduction

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.

Purpose

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.

File format

Patches are stored in a plain-text, JSON compatible format.

Overview

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."  
    

Simple example

{ 
  "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"]
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment