Skip to content

Instantly share code, notes, and snippets.

@dfrommi
Last active October 18, 2020 12:15
Show Gist options
  • Select an option

  • Save dfrommi/f7f95a4ed5fb213cdb970c18deeda4a4 to your computer and use it in GitHub Desktop.

Select an option

Save dfrommi/f7f95a4ed5fb213cdb970c18deeda4a4 to your computer and use it in GitHub Desktop.
Patch binary files with Java #java #util

Patch binary files with Java

Recently, I wanted to create an "intelligent" binary patcher, which not only replaces some chunk of binary data at a file's predefined offset, but instead performs search and replace. BinaryPatcher.java is the result.

The usage is pretty straight forward. Let's have a look at an basic example:

class Tester {
    public static void main(String[] args) {
        try {
            String filename = "patchme";
            BinaryPatcher p = new BinaryPatcher(filename, "AB00FF14", "AB11FF14");

            if (p.isPatchable()) {
                p.createBackup(filename + ".org");
                p.patch();
            }
        } catch(IOException e) {
            System.out.println("ERROR: " + e.getMessage());
        }
    }
}

We try to patch the file patchme. The search and replace binary data is given by hex sequences, in this example AB00FF14 is replaced by AB11FF14. If the file is patchable, i.e. it contains the search pattern, a backup named patchme.org is created an finally, the original file is modified.

That's all. Pretty simple but useful.

import java.io.*;
import java.math.BigInteger;
public class BinaryPatcher {
private String content;
private final String filename;
private final String searchPattern;
private final String replacePattern;
public BinaryPatcher(String filename, String searchPattern,
String replacePattern) throws IOException {
this.filename = filename;
this.searchPattern = convertHexStringToBinaryString(searchPattern);
this.replacePattern = convertHexStringToBinaryString(replacePattern);
initializeContent();
}
public boolean isPatchable() {
return getContent().contains(searchPattern);
}
public void patch() throws IOException {
if (!isPatchable()) {
throw new IOException("Search pattern not found");
}
String originalContent = getContent();
String patchedContent = originalContent.replace(searchPattern,
replacePattern);
saveStringToFile(patchedContent, filename);
}
public void createBackup(String filename) throws IOException {
saveStringToFile(getContent(), filename);
}
private static String convertHexStringToBinaryString(String theHexString) {
byte[] byteSequence = new BigInteger(theHexString, 16).toByteArray();
return new String(byteSequence);
}
private void initializeContent() throws IOException {
byte[] buffer = new byte[(int) new File(filename).length()];
FileInputStream in = new FileInputStream(filename);
in.read(buffer);
in.close();
content = new String(buffer);
}
private void saveStringToFile(String content, String filename)
throws IOException {
FileOutputStream out = new FileOutputStream(filename);
out.write(content.getBytes());
out.close();
}
private String getContent() {
return content;
}
}
class Tester {
public static void main(String[] args) {
try {
String filename = "patchme";
BinaryPatcher p = new BinaryPatcher(filename, "AB00FF14", "AB11FF14");
if (p.isPatchable()) {
p.createBackup(filename + ".org");
p.patch();
}
} catch(IOException e) {
System.out.println("ERROR: " + e.getMessage());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment