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 com.google.common.io.ByteStreams;
import cpw.mods.fml.common.CertificateHelper; 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.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.common.patcher.ClassPatchManager; import cpw.mods.fml.common.patcher.ClassPatchManager;
import cpw.mods.fml.relauncher.FMLLaunchHandler; 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 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 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 LaunchClassLoader cl;
private Boolean liveEnv;
public static File fmlLocation; public static File fmlLocation;
@Override @Override
@ -80,8 +82,8 @@ public class FMLSanityChecker implements IFMLCallHook
{ {
goodFML = true; goodFML = true;
} }
// 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; //Server is not signed, so assume it's good. boolean goodMC = FMLLaunchHandler.side() == Side.SERVER || !liveEnv;
int certCount = 0; int certCount = 0;
try 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 " + "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 " + "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."); "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 else
{ {
@ -172,6 +174,7 @@ public class FMLSanityChecker implements IFMLCallHook
@Override @Override
public void injectData(Map<String, Object> data) public void injectData(Map<String, Object> data)
{ {
liveEnv = (Boolean)data.get("runtimeDeobfuscationEnabled");
cl = (LaunchClassLoader) data.get("classLoader"); cl = (LaunchClassLoader) data.get("classLoader");
File mcDir = (File)data.get("mcLocation"); File mcDir = (File)data.get("mcLocation");
fmlLocation = (File)data.get("coremodLocation"); fmlLocation = (File)data.get("coremodLocation");

View file

@ -42,12 +42,16 @@ public class TerminalTransformer implements IClassTransformer
@Override @Override
public MethodVisitor visitMethod(int mAccess, final String mName, final String mDesc, String mSignature, String[] mExceptions) public MethodVisitor visitMethod(int mAccess, final String mName, final String mDesc, String mSignature, String[] mExceptions)
{ {
final boolean warn = !clsName.equals("net/minecraft/client/Minecraft") && final boolean warn = !(clsName.equals("net/minecraft/client/Minecraft") ||
!clsName.equals("net/minecraft/server/dedicated/DedicatedServer") && clsName.equals("net/minecraft/server/dedicated/DedicatedServer") ||
!clsName.equals("cpw/mods/fml/common/FMLCommonHandler"); 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)) return new MethodVisitor(Opcodes.ASM4, super.visitMethod(mAccess, mName, mDesc, mSignature, mExceptions))
{ {
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) 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")) 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) if (warn)
{ {
FMLRelaunchLog.warning("============================================================="); 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("Offendor: %s.%s%s", ExitVisitor.this.clsName, mName, mDesc);
FMLRelaunchLog.warning("Use FMLCommonHandler.exitJava instead");
FMLRelaunchLog.warning("============================================================="); FMLRelaunchLog.warning("=============================================================");
} }
owner = ExitVisitor.callbackOwner; owner = ExitVisitor.callbackOwner;
@ -67,8 +72,9 @@ public class TerminalTransformer implements IClassTransformer
if (warn) if (warn)
{ {
FMLRelaunchLog.warning("============================================================="); 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("Offendor: %s.%s%s", ExitVisitor.this.clsName, mName, mDesc);
FMLRelaunchLog.warning("Use FMLCommonHandler.exitJava instead");
FMLRelaunchLog.warning("============================================================="); FMLRelaunchLog.warning("=============================================================");
} }
opcode = Opcodes.INVOKESTATIC; opcode = Opcodes.INVOKESTATIC;
@ -76,6 +82,21 @@ public class TerminalTransformer implements IClassTransformer
name = "runtimeExitCalled"; name = "runtimeExitCalled";
desc = "(Ljava/lang/Runtime;I)V"; 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); super.visitMethodInsn(opcode, owner, name, desc);
} }
@ -95,6 +116,13 @@ public class TerminalTransformer implements IClassTransformer
runtime.exit(status); 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() private static void checkAccess()
{ {
StackTraceElement[] cause = Thread.currentThread().getStackTrace(); StackTraceElement[] cause = Thread.currentThread().getStackTrace();