Skip to content

Commit

Permalink
fix(fabric-agent): allow SiB classes to be loaded from the parent cla…
Browse files Browse the repository at this point in the history
…ssloader
  • Loading branch information
dogboy21 committed Aug 19, 2023
1 parent 2d0e3ee commit 2c1c8cb
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
try {
if (className == null) return classfileBuffer;
if ("net/minecraft/launchwrapper/ITweaker".equals(className)) SerializationIsBadAgent.insertLaunchWrapperExclusion();
if ("net/fabricmc/loader/ModContainer".equals(className)) SerializationIsBadAgent.insertFabricValidParentUrl(loader);

String classNameDots = className.replace('/', '.');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import java.lang.instrument.Instrumentation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Set;

public class SerializationIsBadAgent {

Expand Down Expand Up @@ -35,4 +38,39 @@ static void insertLaunchWrapperExclusion() {
}
}

/**
* Another hacky workaround for newer Fabric versions that enforce
* classpath isolation. This adds the path to the SiB jar to the
* list of jar paths that are allowed to be loaded by the parent
* classloader
*
* @param fabricClassLoader The classloader that was used to load the Fabric classes
*/
static void insertFabricValidParentUrl(ClassLoader fabricClassLoader) {
try {
Path sibPath = new File(SerializationIsBadAgent.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toPath();

// basically accessing the following:
// ((KnotClassDelegate) ((Knot) FabricLauncherBase.getLauncher()).classLoader).validParentCodeSources

Class<?> fabricLauncherBaseClass = Class.forName("net.fabricmc.loader.impl.launch.FabricLauncherBase", true, fabricClassLoader);
Method getLauncherMethod = fabricLauncherBaseClass.getDeclaredMethod("getLauncher");
Object fabricLauncher = getLauncherMethod.invoke(null);
Field classLoaderField = fabricLauncher.getClass().getDeclaredField("classLoader");
classLoaderField.setAccessible(true);
Object classLoader = classLoaderField.get(fabricLauncher);
Field validParentCodeSourcesField = classLoader.getClass().getDeclaredField("validParentCodeSources");
validParentCodeSourcesField.setAccessible(true);
@SuppressWarnings("unchecked")
Set<Path> validParentCodeSources = (Set<Path>) validParentCodeSourcesField.get(classLoader);

Set<Path> newValidParentCodeSources = new HashSet<>(validParentCodeSources);
newValidParentCodeSources.add(sibPath);

validParentCodeSourcesField.set(classLoader, newValidParentCodeSources);
} catch (Throwable e) {
SerializationIsBad.logger.error("Failed to insert Fabric valid parent URL", e);
}
}

}

0 comments on commit 2c1c8cb

Please sign in to comment.