diff --git a/tools/aegis4j/README.md b/tools/aegis4j/README.md index a3e085b1c9..7a9bff9db8 100644 --- a/tools/aegis4j/README.md +++ b/tools/aegis4j/README.md @@ -1,4 +1,17 @@ -# aegis4j +# Fork of aegis4j + +This module is a fork of [aegis4j](https://github.com/gredler/aegis4j). Many thanks to the oiginal author(s). +The main changes in this fork are: + +- Additional patches for more unused methods and classes tagged as vulnerable in our dependencies. +- Patches now patch the beginning of a method or constructor body, and don't replace the whole body. This maintains behaviour + where an exception is thrown, but allows fixes where appropriate code can be inserted at the start of a method. +- Compatibility with JDK8 +- Support for specifying different source files or resources for the patches +- Support for a system property to provide addition in-the-field patches for emergency use +- Reduced output, except in error conditions. + +# Original aegis4j README Avoid the NEXT Log4Shell vulnerability! diff --git a/tools/aegis4j/build.gradle b/tools/aegis4j/build.gradle index e3242d73ca..63cccc87f7 100644 --- a/tools/aegis4j/build.gradle +++ b/tools/aegis4j/build.gradle @@ -55,6 +55,7 @@ test { useJUnitPlatform() systemProperty 'jdk.attach.allowAttachSelf', 'true' // tests attach agent to local VM systemProperty 'aegis4j.projectDir', "${project.projectDir.toString()}" + systemProperty 'aegis4j.log', "true" forkEvery 1 // tests cannot undo class modifications to clean up after themselves testLogging { events 'passed', 'skipped', 'failed' diff --git a/tools/aegis4j/src/main/java/net/gredler/aegis4j/AegisAgent.java b/tools/aegis4j/src/main/java/net/gredler/aegis4j/AegisAgent.java index 2d7e0fae2b..c046243034 100644 --- a/tools/aegis4j/src/main/java/net/gredler/aegis4j/AegisAgent.java +++ b/tools/aegis4j/src/main/java/net/gredler/aegis4j/AegisAgent.java @@ -26,6 +26,16 @@ import java.util.stream.Collectors; */ public final class AegisAgent { + public static boolean log = Boolean.getBoolean("aegis4j.log"); + + public static void logPrint(String line) { + if (log) System.out.print(line); + } + + public static void logPrintln(String line) { + if (log) System.out.println(line); + } + private static Instrumentation instrumentation; /** @@ -66,13 +76,13 @@ public final class AegisAgent { } InputStream in = path.toUri().toURL().openStream(); props = readPropertiesFromStream(in); - System.out.println("Aegis4j patching from " + path + " mods file"); + logPrintln("Aegis4j patching from " + path + " mods file"); } else if (normalisedaArg.startsWith("resource=")) { String pathString = arg.trim().substring(9); InputStream in = ClassLoader.getSystemResourceAsStream(pathString); if (in == null) throw new IOException("Unable to load mods resource " + pathString); props = readPropertiesFromStream(in); - System.out.println("Aegis4j patching from " + pathString + " mods resource"); + logPrintln("Aegis4j patching from " + pathString + " mods resource"); } else { throw new IllegalArgumentException("Aegis4j ERROR: unrecognised parameters " + arg); } diff --git a/tools/aegis4j/src/main/java/net/gredler/aegis4j/Patcher.java b/tools/aegis4j/src/main/java/net/gredler/aegis4j/Patcher.java index a7fff21698..1c0d51f042 100644 --- a/tools/aegis4j/src/main/java/net/gredler/aegis4j/Patcher.java +++ b/tools/aegis4j/src/main/java/net/gredler/aegis4j/Patcher.java @@ -50,7 +50,7 @@ public final class Patcher implements ClassFileTransformer { * @param block the features to block */ public static void start(Instrumentation instr, Set block, Properties props) throws IOException { - System.out.print("Aegis4j patching starting..."); + AegisAgent.logPrint("Aegis4j patching starting..."); if (patcher != null) instr.removeTransformer(patcher); patcher = new Patcher(block, props); instr.addTransformer(patcher, true); @@ -58,14 +58,14 @@ public final class Patcher implements ClassFileTransformer { int count = 0; for (String className : patcher.modifications.keySet()) { try { - if (count > 0) System.out.print(", "); - System.out.print(className); + if (count > 0) AegisAgent.logPrint(", "); + AegisAgent.logPrint(className); Class clazz = Class.forName(className); instr.retransformClasses(clazz); } catch (ClassNotFoundException e) { - System.out.print("... not present"); + AegisAgent.logPrint("... not present"); } catch (NoClassDefFoundError e) { - System.out.print("... not present"); + AegisAgent.logPrint("... not present"); } catch (UnmodifiableClassException e) { throw new IOException("Problems transforming class", e); } @@ -73,7 +73,7 @@ public final class Patcher implements ClassFileTransformer { } System.setProperty("aegis4j.blocked.features", String.join(",", block)); - System.out.println(" finished."); + AegisAgent.logPrintln(" finished."); } @Override @@ -103,7 +103,7 @@ public final class Patcher implements ClassFileTransformer { } else { CtMethod[] methods = mod.isAll() ? clazz.getDeclaredMethods() : clazz.getDeclaredMethods(mod.methodName); if (methods.length == 0) { - System.err.println("ERROR: Method not found: " + className + "." + mod.methodName); + System.err.println("Aegis4j ERROR: Method not found: " + className + "." + mod.methodName); } for (CtMethod method : methods) { if (mod.newBody.startsWith("throw ")) {