From e64c07a10996b5e74a8bbc1664da5019b7796020 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 8 Jul 2013 13:19:14 -0400 Subject: [PATCH] We now generate an adler32 checksum for each patched file and verify at load time that they match. Mismatch won't crash, but will emit a big warning.. --- .../cpw/mods/fml/common/patcher/ClassPatch.java | 4 +++- .../fml/common/patcher/ClassPatchManager.java | 16 +++++++++++++++- .../cpw/mods/fml/common/patcher/GenDiffSet.java | 6 ++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/fml/common/cpw/mods/fml/common/patcher/ClassPatch.java b/fml/common/cpw/mods/fml/common/patcher/ClassPatch.java index d5d6e7ff6..833a6ab78 100644 --- a/fml/common/cpw/mods/fml/common/patcher/ClassPatch.java +++ b/fml/common/cpw/mods/fml/common/patcher/ClassPatch.java @@ -6,12 +6,14 @@ public class ClassPatch { public final String targetClassName; public final boolean existsAtTarget; public final byte[] patch; - public ClassPatch(String name, String sourceClassName, String targetClassName, boolean existsAtTarget, byte[] patch) + public final int inputChecksum; + public ClassPatch(String name, String sourceClassName, String targetClassName, boolean existsAtTarget, int inputChecksum, byte[] patch) { this.name = name; this.sourceClassName = sourceClassName; this.targetClassName = targetClassName; this.existsAtTarget = existsAtTarget; + this.inputChecksum = inputChecksum; this.patch = patch; } diff --git a/fml/common/cpw/mods/fml/common/patcher/ClassPatchManager.java b/fml/common/cpw/mods/fml/common/patcher/ClassPatchManager.java index be0439f71..33b1d3ec9 100644 --- a/fml/common/cpw/mods/fml/common/patcher/ClassPatchManager.java +++ b/fml/common/cpw/mods/fml/common/patcher/ClassPatchManager.java @@ -26,6 +26,7 @@ import com.google.common.base.Strings; import com.google.common.base.Throwables; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; +import com.google.common.hash.Hashing; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import com.google.common.io.Files; @@ -80,6 +81,14 @@ public class ClassPatchManager { { FMLLog.warning("Patcher expecting empty class data file for %s, but received non-empty", patch.targetClassName); } + else + { + int inputChecksum = Hashing.adler32().hashBytes(inputData).asInt(); + if (patch.inputChecksum != inputChecksum) + { + FMLLog.severe("There is a binary discrepency between the expected input class %s (%s) and the actual class. Checksum on disk is %x, in patch %x. Things are probably about to go very wrong. Did you put something into the jar file?", mappedName, name, inputChecksum, patch.inputChecksum); + } + } synchronized (patcher) { try @@ -181,10 +190,15 @@ public class ClassPatchManager { String sourceClassName = input.readUTF(); String targetClassName = input.readUTF(); boolean exists = input.readBoolean(); + int inputChecksum = 0; + if (exists) + { + inputChecksum = input.readInt(); + } int patchLength = input.readInt(); byte[] patchBytes = new byte[patchLength]; input.readFully(patchBytes); - return new ClassPatch(name, sourceClassName, targetClassName, exists, patchBytes); + return new ClassPatch(name, sourceClassName, targetClassName, exists, inputChecksum, patchBytes); } } diff --git a/fml/common/cpw/mods/fml/common/patcher/GenDiffSet.java b/fml/common/cpw/mods/fml/common/patcher/GenDiffSet.java index 410b58768..9ba3ba512 100644 --- a/fml/common/cpw/mods/fml/common/patcher/GenDiffSet.java +++ b/fml/common/cpw/mods/fml/common/patcher/GenDiffSet.java @@ -13,6 +13,7 @@ import java.util.logging.Logger; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; +import com.google.common.hash.Hashing; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.google.common.io.Files; @@ -64,6 +65,7 @@ public class GenDiffSet { byte[] diff = delta.compute(vanillaBytes, patchedBytes); + ByteArrayDataOutput diffOut = ByteStreams.newDataOutput(diff.length + 50); // Original name diffOut.writeUTF(name); @@ -73,6 +75,10 @@ public class GenDiffSet { diffOut.writeUTF(targetClassName); // exists at original diffOut.writeBoolean(entry != null); + if (entry != null) + { + diffOut.writeInt(Hashing.adler32().hashBytes(vanillaBytes).asInt()); + } // length of patch diffOut.writeInt(diff.length); // patch