More cleanup of exit handling, also add a couple more noise classes to the list of things ignored.

This commit is contained in:
cpw 2014-08-16 10:32:22 -04:00
parent 7c5eb19645
commit 13d81e05db
2 changed files with 39 additions and 8 deletions

View file

@ -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<String, Object> data)
{
liveEnv = (Boolean)data.get("runtimeDeobfuscationEnabled");
cl = (LaunchClassLoader) data.get("classLoader");
File mcDir = (File)data.get("mcLocation");
fmlLocation = (File)data.get("coremodLocation");

View file

@ -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();