Skip to content

Commit

Permalink
feat(scanallclasses): create a scan all classes boolean
Browse files Browse the repository at this point in the history
Not perf tested, shouldn't be too slow though.
By default only allows classes globally allowed in the config.
Not functional under modlauncher, couldn't see a way to get the transformer to indiscriminately apply to every class loaded.

Wasn't sure if I should've added filtering to not process java.* classes, but theoretically these are exploitable so I decided to leave them filtered, might be a bad choice.
  • Loading branch information
ThatGamerBlue committed Jul 29, 2023
1 parent 08048f8 commit 8d5d567
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.dogboy.serializationisbad.core.Patches;
import io.dogboy.serializationisbad.core.SerializationIsBad;
import io.dogboy.serializationisbad.core.config.PatchModule;
import org.objectweb.asm.tree.ClassNode;

import java.lang.instrument.ClassFileTransformer;
Expand All @@ -13,12 +14,17 @@ public class SIBTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
String classNameDots = className.replace('/', '.');

if (Patches.getPatchModuleForClass(classNameDots) == null) return classfileBuffer;
boolean isClassUnknown = Patches.getPatchModuleForClass(classNameDots) == PatchModule.EMPTY;
if (!SerializationIsBad.getInstance().getConfig().isScanAllClasses() && isClassUnknown) {
return classfileBuffer;
}

SerializationIsBad.logger.info("Applying patches to " + classNameDots);
if (!isClassUnknown) {
SerializationIsBad.logger.info("Applying patches to " + classNameDots);
}

ClassNode classNode = Patches.readClassNode(classfileBuffer);
Patches.applyPatches(classNameDots, classNode);
Patches.applyPatches(classNameDots, classNode, isClassUnknown);
return Patches.writeClassNode(classNode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static PatchModule getPatchModuleForClass(String className) {
}
}

return null;
return PatchModule.EMPTY;
}

public static ClassNode readClassNode(byte[] classBytecode) {
Expand All @@ -37,7 +37,8 @@ public static byte[] writeClassNode(ClassNode classNode) {
return writer.toByteArray();
}

public static void applyPatches(String className, ClassNode classNode) {
public static void applyPatches(String className, ClassNode classNode, boolean isClassUnknown) {
boolean patched = false;
for (MethodNode methodNode : classNode.methods) {
InsnList instructions = methodNode.instructions;
for (int i = 0; i < instructions.size(); i++) {
Expand All @@ -61,9 +62,13 @@ public static void applyPatches(String className, ClassNode classNode) {
instructions.insertBefore(instruction, additionalInstructions);

SerializationIsBad.logger.info(" (2/2) Redirecting ObjectInputStream to ClassFilteringObjectInputStream in method " + methodNode.name);
patched = true;
}
}
}
if (patched && isClassUnknown) {
SerializationIsBad.logger.warn("Applied ObjectInputStream patches in unknown class " + className + ", please report this to the developers of SerializationIsBad responsibly.");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.Set;

public class PatchModule {
public final static PatchModule EMPTY = new PatchModule();

private Set<String> classesToPatch;
private Set<String> classAllowlist;
private Set<String> packageAllowlist;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,28 @@
import java.util.Set;

public class SIBConfig {
private boolean scanAllClasses;
private boolean executeBlocking;
private List<PatchModule> patchModules;
private Set<String> classAllowlist;
private Set<String> packageAllowlist;

public SIBConfig() {
this.scanAllClasses = true;
this.executeBlocking = true;
this.patchModules = new ArrayList<>();
this.classAllowlist = new HashSet<>();
this.packageAllowlist = new HashSet<>();
}

public boolean isScanAllClasses() {
return this.scanAllClasses;
}

public void setScanAllClasses(boolean scanAllClasses) {
this.scanAllClasses = scanAllClasses;
}

public boolean isExecuteBlocking() {
return this.executeBlocking;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@

import io.dogboy.serializationisbad.core.Patches;
import io.dogboy.serializationisbad.core.SerializationIsBad;
import io.dogboy.serializationisbad.core.config.PatchModule;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.tree.ClassNode;

public class SIBTransformer implements IClassTransformer {
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
if (Patches.getPatchModuleForClass(transformedName) == null) return basicClass;
boolean isClassUnknown = Patches.getPatchModuleForClass(transformedName) == PatchModule.EMPTY;
if (!SerializationIsBad.getInstance().getConfig().isScanAllClasses() && isClassUnknown) {
return basicClass;
}

SerializationIsBad.logger.info("Applying patches to " + transformedName);
if (!isClassUnknown) {
SerializationIsBad.logger.info("Applying patches to " + transformedName);
}

ClassNode classNode = Patches.readClassNode(basicClass);
Patches.applyPatches(transformedName, classNode);
Patches.applyPatches(transformedName, classNode, isClassUnknown);
return Patches.writeClassNode(classNode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ public SIBTransformer(PatchModule patchModule) {

@Override
public ClassNode transform(ClassNode input, ITransformerVotingContext context) {
Patches.applyPatches(input.name, input);
// todo: change `false` here to something applicable if we figure out a way to get this to run on every class
Patches.applyPatches(input.name, input, false);
return input;
}

Expand Down
1 change: 1 addition & 0 deletions serializationisbad.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"scanAllClasses": true,
"executeBlocking": true,
"patchModules": [
{
Expand Down

0 comments on commit 8d5d567

Please sign in to comment.