1. Jørgen Ibsen
  2. apatch

Overview

HTTPS SSH

apatch simple patching engine

Copyright 1999-2014 Joergen Ibsen

http://www.ibsensoftware.com/

About

apatch is a byte-patch generator. It is a tool which compiles a simple script into a patch executable.

apatch can create multi-file patches with search/replace, backup creation, and crc checking. It also supports registry patching.

The patch executables created are Win32 GUI programs. They display a dialog with a status window which is used to show information to the user.

A very light encryption is applied to the patch executable.

Syntax

These are the command-line arguments for apatch:

Syntax:  apatch [options] <script file> [output file]

Options:
  -d  debug script
  -v  show version information

'apatch -c <file>' can be used to calculate the CRC of the given file.

So basically you have to write a simple script file, which contains the information about what files should be patched and how. The next sections describe the format of the script file and what commands can be used -- also check the examples.

The switches can be given anywhere in the argument-list, in any case and in any order you like. Input- and output file should be pretty self-explanatory. The switches work like this:

-d : Makes apatch output what it has read from the script. This is
     nice for debugging.

-v : Displays version information.

The command switch -c can be used to calculate the crc of a given file. This can then be used together with the crc command.

If command-line tools make you nervous, you can try apatchUI, which is a simple GUI wrapper.

Script Commands

title "string"

Set the caption of the patch dialog to the given string.

dlgsize width height

Set the width and height of the status window (the default is 60 characters wide and 24 characters high).

colors red green blue red green blue

Set the text and background color of the status window. The first three components are the text color, the last three are the background. Each component is a byte value (0-255).

print "string" ["string"]

Print a string (double-quote delimited) to the status window. Multiple strings after each other are concatenated. The strings can contain escape codes, which are described in the section about script format.

start

Marks the start of the actual patch code. At this point the user will be able to choose between 'Patch' and 'Quit'. Only the title, dlgsize, color and print commands are allowed before the start command. Must be present.

cls

Clear the status window.

quit

Quit patch.

goto labelname

Continue patch execution at label labelname.

onerror goto labelname

If an error occurs, execution should continue at label labelname.

onerror quit

If an error occurs, the patch should quit. This is the default.

labelname:

Declare a label named labelname for use with goto and onerror.

attrib <+|->char [<+|->char ...] "filename"

Changes the file attributes of the file with the given name. The attribute characters supported are:

a - archive
h - hidden
r - read-only
s - system

Environment-variable strings in the filename are expanded.

open [ro] "filename"

Open a file with the given name. The optional argument ro opens the file in read-only mode. Environment-variable strings in the filename are expanded.

open [ro] dialog ["string"]

Display an open file dialog, and let the user choose a file to open. The optional argument ro opens the file in read-only mode. The optional string sets the title of the open file dialog.

open [ro] argv

Reads the next argument given on the command-line, and opens a file with that name. The optional argument ro opens the file in read-only mode.

backup <on|off>

Turns automatic backup creation on or off. Automatic backup creation will make a backup of any opened file before it is changed the first time (if a file is not changed, no backup will be made). The backup filename is the open filename with .bak appended.

backup ["filename"]

Create a backup of the current file (including any changes made up to the backup command). The optional argument specifies the filename to use for the backup file. If not present, the current open filename with .bak appended will be used. Environment-variable strings in the filename are expanded.

offset [+|-] value

Set the current offset within the current file to value. The optional argument + adds value to the current offset. The optional argument - subtracts value from the current offset. If the resulting offset is outside the current file, an error occurs and the offset is not changed.

size value

Check if the size of the current file is equal to value. If not, an error occurs.

size "filename"

Check if the size of the current file is equal to the size of the file with the given name (evaluated at patch generation time). If not, an error occurs.

crc value

Check if the crc of the current file is equal to value. If not, an error occurs.

crc "filename"

Check if the crc of the current file is equal to the crc of the file with the given name (evaluated at patch generation time). If not, an error occurs.

write byte [byte ...]

Write the byte values given at the current offset in the current file. Strings can be used for specifying multiple bytes. Moves the offset accordingly.

test byte [byte ...]

Test if the bytes present at the current offset in the current file are equal to those given. If not, an error occurs. The wildcard character ? can be used to denote a byte whose value should not be checked. Strings can be used for specifying multiple bytes. Does not move the offset.

search byte [byte ...]

Search for the given sequence of bytes from the current offset in the current file and forward. If not found, an error occurs. The wildcard character ? can be used to denote a byte whose value should not be checked. Strings can be used for specifying multiple bytes. Moves the offset if a match is found.

compare "filename1" to "filename2"

Performs a byte compare between two files and inserts the offset and write commands required to patch the source file to the destination file (evaluated at patch generation time). File open operation and any size or crc checking must be performed before this command. The files are compared up to the length of the shortest file.

regopen base "subkey"

Open an existing key with the specified base key and subkey. If the key does not exist, an error occurs.

base must be one of HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE and HKEY_USERS.

regcreate base "subkey"

Create a key with the specified base key and subkey. If the key already exists, it is opened.

base must be one of HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE and HKEY_USERS.

regset "name" [binary] data

Store data in the value with the given name in the currently open registry key.

A string will be interpreted as type REG_SZ, an integer value will be interpreted as type REG_DWORD. The optional argument binary makes the type REG_BINARY and accepts both sequences of bytes and strings.

regdel "name"

Delete the value with the given name in the currently open registry key.

import <fc|reg> "filename"

Import patch data from a file. Supports import of fc /b output and registry files in REGEDIT4 format.

fc imports fc /b style data and inserts the offset and write commands required to patch the bytes listed in the file (evaluated at patch generation time). File open operation and any size or crc checking must be performed before this command.

reg imports a registry file in REGEDIT4 format and inserts the regcreate and regset commands required to merge the registry keys and values listed in the file into the registry.

yesno ifno goto labelname

Let the user choose between 'Yes' and 'No'. If the user chooses 'No', continue execution at label labelname.

yesno ifno quit

Let the user choose between 'Yes' and 'No'. If the user chooses 'No', quit patch.

end

Marks the end of the patch. Must be present.

Script Format

The first part of a script, up to the start command, may only contain the title, dlgsize, color and print commands. They should be used to give the dialog an appropriate name and display some informative text in the status window (possibly even a nice little ascii logo :-).

When execution reaches the start command, the user is given the choice between 'Patch' and 'Quit'. This is to ensure that the patch is not applied unwillingly. If the user chooses 'Patch', execution continues.

Between the start and end commands, the actual patch code is placed.

Anything after the end command is ignored.

Comments start with ; and continue to the end of the line.

Numbers are read using strtoul(), so the format should be either decimal or hex with a leading 0x.

Strings must be double-quote delimited, and may contain the following escape codes:

\"    - insert a double-quote
\n    - insert a newline
\r    - insert a return
\t    - insert a tab
\xNN  - insert a byte with value NN (hex)
\\    - insert a single backslash

Tips and Tricks

Why is there no ifyes?

    yesno  ifno goto choice_no
    goto   choice_yes
choice_no:

Global Search and Replace

    onerror goto done     ; when the search fails, goto done
more:
    search 0xff 0xff 0xff
    write  0x00 0x00 0x00
    goto   more
done:

Open Default or Selected File

    print "patch default file 'somefile.dat'?"
    yesno ifno goto select_file
    open  "somefile.dat"
    goto  got_file
select_file:
    open  dialog
got_file:
    ; patch file ...