From 13d81e05db8008c5d0776bc4cac5f1b293b2ba3b Mon Sep 17 00:00:00 2001 From: cpw Date: Sat, 16 Aug 2014 10:32:22 -0400 Subject: [PATCH] More cleanup of exit handling, also add a couple more noise classes to the list of things ignored. --- .../mods/fml/common/asm/FMLSanityChecker.java | 9 +++-- .../asm/transformers/TerminalTransformer.java | 38 ++++++++++++++++--- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/fml/src/main/java/cpw/mods/fml/common/asm/FMLSanityChecker.java b/fml/src/main/java/cpw/mods/fml/common/asm/FMLSanityChecker.java index da230a00e..63d13205a 100644 --- a/fml/src/main/java/cpw/mods/fml/common/asm/FMLSanityChecker.java +++ b/fml/src/main/java/cpw/mods/fml/common/asm/FMLSanityChecker.java @@ -28,6 +28,7 @@ import com.google.common.base.Charsets; import com.google.common.io.ByteStreams; import cpw.mods.fml.common.CertificateHelper; +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; import cpw.mods.fml.common.patcher.ClassPatchManager; import cpw.mods.fml.relauncher.FMLLaunchHandler; @@ -41,6 +42,7 @@ public class FMLSanityChecker implements IFMLCallHook private static final String FORGEFINGERPRINT = "E3:C3:D5:0C:7C:98:6D:F7:4C:64:5C:0A:C5:46:39:74:1C:90:A5:57".toLowerCase().replace(":", ""); private static final String MCFINGERPRINT = "CD:99:95:96:56:F7:53:DC:28:D8:63:B4:67:69:F7:F8:FB:AE:FC:FC".toLowerCase().replace(":", ""); private LaunchClassLoader cl; + private Boolean liveEnv; public static File fmlLocation; @Override @@ -80,8 +82,8 @@ public class FMLSanityChecker implements IFMLCallHook { goodFML = true; } - - boolean goodMC = FMLLaunchHandler.side() == Side.SERVER; //Server is not signed, so assume it's good. + // Server is not signed, so assume it's good - a deobf env is dev time so it's good too + boolean goodMC = FMLLaunchHandler.side() == Side.SERVER || !liveEnv; int certCount = 0; try { @@ -154,7 +156,7 @@ public class FMLSanityChecker implements IFMLCallHook "and should have returned us a valid, intact minecraft jar location. This did not work. Either you have modified the minecraft jar file (if so " + "run the forge installer again), or you are using a base editing jar that is changing this class (and likely others too). If you REALLY " + "want to run minecraft in this configuration, add the flag -Dfml.ignoreInvalidMinecraftCertificates=true to the 'JVM settings' in your launcher profile."); - System.exit(1); + FMLCommonHandler.instance().exitJava(1, false); } else { @@ -172,6 +174,7 @@ public class FMLSanityChecker implements IFMLCallHook @Override public void injectData(Map data) { + liveEnv = (Boolean)data.get("runtimeDeobfuscationEnabled"); cl = (LaunchClassLoader) data.get("classLoader"); File mcDir = (File)data.get("mcLocation"); fmlLocation = (File)data.get("coremodLocation"); diff --git a/fml/src/main/java/cpw/mods/fml/common/asm/transformers/TerminalTransformer.java b/fml/src/main/java/cpw/mods/fml/common/asm/transformers/TerminalTransformer.java index c38d865ea..d5056c3cc 100644 --- a/fml/src/main/java/cpw/mods/fml/common/asm/transformers/TerminalTransformer.java +++ b/fml/src/main/java/cpw/mods/fml/common/asm/transformers/TerminalTransformer.java @@ -42,12 +42,16 @@ public class TerminalTransformer implements IClassTransformer @Override public MethodVisitor visitMethod(int mAccess, final String mName, final String mDesc, String mSignature, String[] mExceptions) { - final boolean warn = !clsName.equals("net/minecraft/client/Minecraft") && - !clsName.equals("net/minecraft/server/dedicated/DedicatedServer") && - !clsName.equals("cpw/mods/fml/common/FMLCommonHandler"); + final boolean warn = !(clsName.equals("net/minecraft/client/Minecraft") || + clsName.equals("net/minecraft/server/dedicated/DedicatedServer") || + clsName.equals("cpw/mods/fml/common/FMLCommonHandler") || + clsName.startsWith("com/jcraft/jogg/") || + clsName.startsWith("scala/sys/") + ); return new MethodVisitor(Opcodes.ASM4, super.visitMethod(mAccess, mName, mDesc, mSignature, mExceptions)) { + @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { if (opcode == Opcodes.INVOKESTATIC && owner.equals("java/lang/System") && name.equals("exit") && desc.equals("(I)V")) @@ -55,8 +59,9 @@ public class TerminalTransformer implements IClassTransformer if (warn) { FMLRelaunchLog.warning("============================================================="); - FMLRelaunchLog.warning("MOD HAS DIRECT REFERENCE System.exit() THIS IS NOT ALLOWED REROUTING TO FMLCommonHandler!"); + FMLRelaunchLog.warning("MOD HAS DIRECT REFERENCE System.exit() THIS IS NOT ALLOWED REROUTING TO FML!"); FMLRelaunchLog.warning("Offendor: %s.%s%s", ExitVisitor.this.clsName, mName, mDesc); + FMLRelaunchLog.warning("Use FMLCommonHandler.exitJava instead"); FMLRelaunchLog.warning("============================================================="); } owner = ExitVisitor.callbackOwner; @@ -67,8 +72,9 @@ public class TerminalTransformer implements IClassTransformer if (warn) { FMLRelaunchLog.warning("============================================================="); - FMLRelaunchLog.warning("MOD HAS DIRECT REFERENCE Runtime.exit() THIS IS NOT ALLOWED REROUTING TO FMLCommonHandler!"); + FMLRelaunchLog.warning("MOD HAS DIRECT REFERENCE Runtime.exit() THIS IS NOT ALLOWED REROUTING TO FML!"); FMLRelaunchLog.warning("Offendor: %s.%s%s", ExitVisitor.this.clsName, mName, mDesc); + FMLRelaunchLog.warning("Use FMLCommonHandler.exitJava instead"); FMLRelaunchLog.warning("============================================================="); } opcode = Opcodes.INVOKESTATIC; @@ -76,6 +82,21 @@ public class TerminalTransformer implements IClassTransformer name = "runtimeExitCalled"; desc = "(Ljava/lang/Runtime;I)V"; } + else if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/Runtime") && name.equals("halt") && desc.equals("(I)V")) + { + if (warn) + { + FMLRelaunchLog.warning("============================================================="); + FMLRelaunchLog.warning("MOD HAS DIRECT REFERENCE Runtime.halt() THIS IS NOT ALLOWED REROUTING TO FML!"); + FMLRelaunchLog.warning("Offendor: %s.%s%s", ExitVisitor.this.clsName, mName, mDesc); + FMLRelaunchLog.warning("Use FMLCommonHandler.exitJava instead"); + FMLRelaunchLog.warning("============================================================="); + } + opcode = Opcodes.INVOKESTATIC; + owner = ExitVisitor.callbackOwner; + name = "runtimeHaltCalled"; + desc = "(Ljava/lang/Runtime;I)V"; + } super.visitMethodInsn(opcode, owner, name, desc); } @@ -95,6 +116,13 @@ public class TerminalTransformer implements IClassTransformer runtime.exit(status); } + // Intercept Runtime.getRuntime().halt, and check if the caller is allowed to use it, if not wrap it in a ExitTrappedException + public static void runtimeHaltCalled(Runtime runtime, int status) + { + ExitVisitor.checkAccess(); + runtime.halt(status); + } + private static void checkAccess() { StackTraceElement[] cause = Thread.currentThread().getStackTrace();