forked from MirrorHub/authlib-injector
support retransform
This commit is contained in:
parent
bfa2629ff7
commit
83dcd8380f
3 changed files with 81 additions and 7 deletions
|
@ -27,7 +27,10 @@ jar {
|
||||||
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||||
'Git-Commit': gitInfo.gitHashFull,
|
'Git-Commit': gitInfo.gitHashFull,
|
||||||
'Git-IsClean': gitInfo.isCleanTag,
|
'Git-IsClean': gitInfo.isCleanTag,
|
||||||
'Premain-Class': 'org.to2mbn.authlibinjector.javaagent.AuthlibInjectorPremain'
|
'Premain-Class': 'org.to2mbn.authlibinjector.javaagent.AuthlibInjectorPremain',
|
||||||
|
'Agent-Class': 'org.to2mbn.authlibinjector.javaagent.AuthlibInjectorPremain',
|
||||||
|
'Can-Retransform-Classes': true,
|
||||||
|
'Can-Redefine-Classes': true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import org.to2mbn.authlibinjector.transform.YggdrasilKeyTransformUnit;
|
||||||
|
|
||||||
public final class AuthlibInjector {
|
public final class AuthlibInjector {
|
||||||
|
|
||||||
private static final String[] nonTransformablePackages = new String[] { "java.", "javax.", "com.sun.",
|
public static final String[] nonTransformablePackages = new String[] { "java.", "javax.", "com.sun.",
|
||||||
"com.oracle.", "jdk.", "sun.", "org.apache.", "com.google.", "oracle.", "com.oracle.", "com.paulscode.",
|
"com.oracle.", "jdk.", "sun.", "org.apache.", "com.google.", "oracle.", "com.oracle.", "com.paulscode.",
|
||||||
"io.netty.", "org.lwjgl.", "net.java.", "org.w3c.", "javassist.", "org.xml.", "org.jcp.", "paulscode.",
|
"io.netty.", "org.lwjgl.", "net.java.", "org.w3c.", "javassist.", "org.xml.", "org.jcp.", "paulscode.",
|
||||||
"com.ibm.", "joptsimple.", "org.to2mbn.authlibinjector." };
|
"com.ibm.", "joptsimple.", "org.to2mbn.authlibinjector." };
|
||||||
|
|
|
@ -1,21 +1,92 @@
|
||||||
package org.to2mbn.authlibinjector.javaagent;
|
package org.to2mbn.authlibinjector.javaagent;
|
||||||
|
|
||||||
import static org.to2mbn.authlibinjector.AuthlibInjector.bootstrap;
|
import static org.to2mbn.authlibinjector.AuthlibInjector.bootstrap;
|
||||||
|
import static org.to2mbn.authlibinjector.AuthlibInjector.debug;
|
||||||
import static org.to2mbn.authlibinjector.AuthlibInjector.info;
|
import static org.to2mbn.authlibinjector.AuthlibInjector.info;
|
||||||
|
import static org.to2mbn.authlibinjector.AuthlibInjector.nonTransformablePackages;
|
||||||
import java.lang.instrument.Instrumentation;
|
import java.lang.instrument.Instrumentation;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class AuthlibInjectorPremain {
|
public class AuthlibInjectorPremain {
|
||||||
|
|
||||||
public static void premain(String arg, Instrumentation instrumentation) {
|
public static void premain(String arg, Instrumentation instrumentation) {
|
||||||
try {
|
try {
|
||||||
info("launched from javaagent");
|
info("launched from premain");
|
||||||
if (arg != null && !arg.isEmpty()) {
|
initInjector(arg, instrumentation, false);
|
||||||
System.setProperty("org.to2mbn.authlibinjector.config", arg);
|
|
||||||
}
|
|
||||||
bootstrap(instrumentation::addTransformer);
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// prevent the exception being thrown to VM
|
// prevent the exception being thrown to VM
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void agentmain(String arg, Instrumentation instrumentation) {
|
||||||
|
try {
|
||||||
|
info("launched from agentmain");
|
||||||
|
initInjector(arg, instrumentation, true);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
// prevent the exception being thrown to VM
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void initInjector(String arg, Instrumentation instrumentation, boolean needsRetransform) {
|
||||||
|
setupConfig(arg);
|
||||||
|
|
||||||
|
boolean retransformSupported = instrumentation.isRetransformClassesSupported();
|
||||||
|
boolean retransformEnabled = retransformSupported && needsRetransform;
|
||||||
|
bootstrap(x -> instrumentation.addTransformer(x, retransformEnabled));
|
||||||
|
|
||||||
|
if (needsRetransform) {
|
||||||
|
if (retransformSupported) {
|
||||||
|
info("start retransforming");
|
||||||
|
doRetransform(instrumentation);
|
||||||
|
} else {
|
||||||
|
info("retransforming is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setupConfig(String arg) {
|
||||||
|
if (arg != null && !arg.isEmpty()) {
|
||||||
|
System.setProperty("org.to2mbn.authlibinjector.config", arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void doRetransform(Instrumentation instrumentation) {
|
||||||
|
try {
|
||||||
|
long t0 = System.currentTimeMillis();
|
||||||
|
Class<?>[] classToRetransform = getClassesToRetransform(instrumentation);
|
||||||
|
if (classToRetransform.length > 0) {
|
||||||
|
instrumentation.retransformClasses(classToRetransform);
|
||||||
|
}
|
||||||
|
long t1 = System.currentTimeMillis();
|
||||||
|
info("retransforming finished in {0}ms", t1 - t0);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
info("unable to retransform");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?>[] getClassesToRetransform(Instrumentation instrumentation) {
|
||||||
|
Class<?>[] loadedClasses = instrumentation.getAllLoadedClasses();
|
||||||
|
Class<?>[] dest = new Class[loadedClasses.length];
|
||||||
|
int idx = 0;
|
||||||
|
for (Class<?> clazz : loadedClasses) {
|
||||||
|
if (instrumentation.isModifiableClass(clazz)) {
|
||||||
|
boolean toRetransform = true;
|
||||||
|
for (String nonTransformablePackage : nonTransformablePackages) {
|
||||||
|
if (clazz.getName().startsWith(nonTransformablePackage)) {
|
||||||
|
toRetransform = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toRetransform) {
|
||||||
|
dest[idx++] = clazz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug("loaded {0} classes, {1} to retransform", loadedClasses.length, idx);
|
||||||
|
return Arrays.copyOf(dest, idx);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue