[ apatch ]
simple patching engine
Copyright 1999-2012 Jørgen Ibsen
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.
apatch is licensed under the Apache License, Version 2.0 (the "License"); you may not use this software except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
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.
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 under section 5.
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.
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
ifyes
?yesno ifno goto choice_no goto choice_yes choice_no:
onerror goto done ; when the search fails, goto done more: search 0xff 0xff 0xff write 0x00 0x00 0x00 goto more done:
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 ...
.. go out to the following people:
If you have any questions, suggestions or bug-reports about apatch, please feel free to contact me by e-mail at:
You can get the latest version of apatch and my other software at:
apatch is now open source, licensed under the Apache License, Version 2.0. Most of this project was written over ten years ago, and since I feel it is unlikely I will do anymore work on it, I wanted to release the source in case it is of interest and/or use to anyone.
Added import
command, which allows importing
fc /b
output and registry files in REGEDIT4 format.
Added support for simple registry patching, thx to TheDutchJewel and X-Lock!
Environment-variable strings in the attrib
,
open
and backup
commands are now expanded.
Added support for automatic backup creation on first change, thx to
Mouser! The write
, test
and search
commands now accept strings. Added a simple GUI wrapper for the apatch
compiler (for those with command-line-phobic), thx to X-Lock!
Added offset checking to the offset
, test
and write
commands. The backup filename is now generated if
not specified.
Added the colors
and dlgsize
commands.
Added the possibility to read filenames from the command-line. Open file dialog now starts in the current directory.
Added the attrib
and compare
commands.
Switched to FASM v1.48.
Switched to FASM v1.47. Fixed a bug when opening multiple files, thx to Frodo!
Switched to GCC 3.2.3. Compiled with optimization turned on.
Silent update: Fixed a html problem, thx to Skymmer!
This is a total rewrite of aPATCH v0.34, which was a DOS byte-patch generator that produced 16-bit patch executables.
The patch generator is now a Win32 console application, and the patch stub is a Win32 GUI application.
replace
command.