Skip to content

Commit

Permalink
replace SandboxClassLoader with working SSVM SandBox
Browse files Browse the repository at this point in the history
  • Loading branch information
EpicPlayerA10 committed Sep 10, 2024
1 parent d32c291 commit f066c6e
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 187 deletions.
1 change: 0 additions & 1 deletion .run/Bootstrap.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<configuration default="false" name="Bootstrap" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="Bootstrap" />
<module name="deobfuscator-impl" />
<option name="VM_PARAMETERS" value="-Djava.security.manager -Djava.security.policy=./security-policy.txt" />
<method v="2">
<option name="Make" enabled="true" />
</method>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public String canonicalName() {
*/
public byte[] compileToBytes(Context context) {
try {
ClassWriter classWriter = new LibraryClassWriter(this.classWriterFlags, context.getLoader());
ClassWriter classWriter = new LibraryClassWriter(this.classWriterFlags, context.getLibraryLoader());
this.classNode.accept(classWriter);

return classWriter.toByteArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,58 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import dev.xdark.ssvm.VirtualMachine;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import uwu.narumi.deobfuscator.api.asm.ClassWrapper;
import uwu.narumi.deobfuscator.api.execution.SandBox;
import uwu.narumi.deobfuscator.api.library.LibraryClassLoader;

public class Context {

private static final Logger LOGGER = LogManager.getLogger(Context.class);

private final Map<String, ClassWrapper> classes = new ConcurrentHashMap<>();
private final Map<String, byte[]> originalClasses = new ConcurrentHashMap<>();
private final Map<String, byte[]> files = new ConcurrentHashMap<>();

private final DeobfuscatorOptions options;
private final LibraryClassLoader loader;
private final SandBox sandBox;
private final LibraryClassLoader libraryLoader;

private SandBox sandBox = null;

public Context(DeobfuscatorOptions options, LibraryClassLoader loader, SandBox sandBox) {
public Context(DeobfuscatorOptions options, LibraryClassLoader libraryLoader) {
this.options = options;
this.loader = loader;
this.sandBox = sandBox;
this.libraryLoader = libraryLoader;
}

public DeobfuscatorOptions getOptions() {
return options;
/**
* Gets sandbox or creates if it does not exist.
*/
public SandBox getSandBox() {
if (this.sandBox == null) {
// Lazily load sandbox
try {
this.sandBox = new SandBox(
this.libraryLoader,
options.virtualMachine() == null ? new VirtualMachine() : options.virtualMachine()
);
} catch (Throwable t) {
LOGGER.error("SSVM bootstrap failed");
LOGGER.debug("Error", t);
if (options.consoleDebug()) t.printStackTrace();
}
}
return this.sandBox;
}

public LibraryClassLoader getLoader() {
return loader;
public DeobfuscatorOptions getOptions() {
return options;
}

public SandBox getSandBox() {
return sandBox;
public LibraryClassLoader getLibraryLoader() {
return libraryLoader;
}

public Collection<ClassWrapper> classes() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import dev.xdark.ssvm.api.VMInterface;
import dev.xdark.ssvm.classloading.SupplyingClassLoaderInstaller;
import dev.xdark.ssvm.execution.ExecutionEngine;
import dev.xdark.ssvm.execution.VMException;
import dev.xdark.ssvm.filesystem.FileManager;
import dev.xdark.ssvm.invoke.InvocationUtil;
import dev.xdark.ssvm.memory.management.MemoryManager;
Expand All @@ -18,16 +19,22 @@
import dev.xdark.ssvm.util.Reflection;
import java.io.PrintWriter;
import java.io.StringWriter;

import dev.xdark.ssvm.value.InstanceValue;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import uwu.narumi.deobfuscator.api.library.LibraryClassLoader;

public class SandBox {

private static final Logger LOGGER = LogManager.getLogger(SandBox.class);

private final LibraryClassLoader loader;

private VirtualMachine virtualMachine;
private MemoryManager memoryManager;
private SupplyingClassLoaderInstaller.Helper helper;
private InvocationUtil invocationUtil;
private final VirtualMachine virtualMachine;
private final MemoryManager memoryManager;
private final SupplyingClassLoaderInstaller.Helper helper;
private final InvocationUtil invocationUtil;

public SandBox(LibraryClassLoader loader) {
this(loader, new VirtualMachine());
Expand All @@ -41,11 +48,8 @@ public SandBox(LibraryClassLoader loader, VirtualMachine virtualMachine) {
this.virtualMachine.initialize();
this.virtualMachine.bootstrap();
this.memoryManager = virtualMachine.getMemoryManager();
this.helper =
SupplyingClassLoaderInstaller.install(
virtualMachine,
new ClassLoaderDataSupplier(loader)
.append(SupplyingClassLoaderInstaller.supplyFromRuntime()));
// Install all classes from deobfuscator context
this.helper = SupplyingClassLoaderInstaller.install(virtualMachine, new ClassLoaderDataSupplier(loader));
this.invocationUtil = InvocationUtil.create(virtualMachine);
patchVm();
} catch (Exception e) {
Expand Down Expand Up @@ -81,6 +85,21 @@ public static String toString(Throwable t) {
return stringWriter.toString();
}

/**
* Converts {@link VMException} into readable java exception
*/
public void handleVMException(VMException ex) {
InstanceValue oop = ex.getOop();
if (oop.getJavaClass() == virtualMachine.getSymbols().java_lang_ExceptionInInitializerError()) {
oop = (InstanceValue) virtualMachine.getOperations().getReference(oop, "exception", "Ljava/lang/Throwable;");
}

// Print pretty exception
LOGGER.error(oop);
LOGGER.error(virtualMachine.getOperations().toJavaException(oop));
throw ex;
}

public VirtualMachine getVirtualMachine() {
return virtualMachine;
}
Expand Down

This file was deleted.

This file was deleted.

2 changes: 0 additions & 2 deletions deobfuscator-impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
<configuration>
<junitArtifactName>org.junit.jupiter:junit-jupiter</junitArtifactName>
<trimStackTrace>false</trimStackTrace>
<!-- Enable security manager for SandboxClassLoader to work -->
<argLine>-Djava.security.manager -Djava.security.policy=../security-policy.txt</argLine>
</configuration>
</plugin>
</plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.Policy;
import java.util.*;
import java.util.function.Supplier;
import java.util.zip.ZipEntry;
Expand All @@ -18,7 +17,6 @@
import uwu.narumi.deobfuscator.api.context.Context;
import uwu.narumi.deobfuscator.api.context.DeobfuscatorOptions;
import uwu.narumi.deobfuscator.api.execution.SandBox;
import uwu.narumi.deobfuscator.api.execution.SandboxPolicy;
import uwu.narumi.deobfuscator.api.helper.ClassHelper;
import uwu.narumi.deobfuscator.api.helper.FileHelper;
import uwu.narumi.deobfuscator.api.library.Library;
Expand Down Expand Up @@ -50,9 +48,6 @@ private Deobfuscator(DeobfuscatorOptions options) {

this.options = options;

// Setup policy for SandboxClassLoader
Policy.setPolicy(new SandboxPolicy());

List<Library> libraries = new ArrayList<>();
// Add libraries
libraries.addAll(options.libraries().stream().map(path -> new Library(path, options.classWriterFlags())).toList());
Expand All @@ -70,20 +65,7 @@ private Deobfuscator(DeobfuscatorOptions options) {
libraries
);

// Temporary disabled until the sandbox is fixed
SandBox sandBox = null;
/*try {
sandBox = new SandBox(
libraryClassLoader,
options.virtualMachine() == null ? new VirtualMachine() : options.virtualMachine()
);
} catch (Throwable t) {
LOGGER.error("SSVM bootstrap failed");
LOGGER.debug("Error", t);
if (options.consoleDebug()) t.printStackTrace();
}*/

this.context = new Context(options, libraryClassLoader, sandBox);
this.context = new Context(options, libraryClassLoader);
}

public void start() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ protected void registerAll() {
register("Inline static fields with modification", InputType.JAVA_CODE, List.of(InlineStaticFieldTransformer::new), Source.of("TestInlineStaticFieldsWithModification"));

// Sandbox security. Should throw
registerThrows("Sandbox security", InputType.JAVA_CODE, List.of(TestSandboxSecurityTransformer::new), Source.of("TestSandboxSecurity"));
registerThrows("Sandbox security", InputType.JAVA_CODE, List.of(TestSandboxSecurityTransformer::new), Source.of("sandbox/TestSandboxSecurity"));

// Samples
register("Some flow obf sample", InputType.CUSTOM_CLASS, List.of(ComposedGeneralFlowTransformer::new), Source.of("FlowObfSample"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package uwu.narumi.deobfuscator.transformer;

import dev.xdark.ssvm.mirror.type.InstanceClass;
import uwu.narumi.deobfuscator.api.asm.ClassWrapper;
import uwu.narumi.deobfuscator.api.context.Context;
import uwu.narumi.deobfuscator.api.execution.SandboxClassLoader;
import uwu.narumi.deobfuscator.api.execution.SandBox;
import uwu.narumi.deobfuscator.api.transformer.Transformer;

import java.lang.reflect.Method;

public class TestSandboxSecurityTransformer extends Transformer {
@Override
protected void transform(ClassWrapper scope, Context context) throws Exception {
SandboxClassLoader sandboxClassLoader = new SandboxClassLoader(context);
Class<?> clazz = Class.forName("TestSandboxSecurity", true, sandboxClassLoader);
Method method = clazz.getDeclaredMethod("test");
// Invoke test method
method.invoke(null);
SandBox sandBox = context.getSandBox();
InstanceClass clazz = sandBox.getHelper().loadClass("sandbox.TestSandboxSecurity");

sandBox.getInvocationUtil().invokeInt(
clazz.getMethod("test", "()I")
);
}
}
Loading

0 comments on commit f066c6e

Please sign in to comment.