Skip to content

Commit

Permalink
remove static fields that were inlined
Browse files Browse the repository at this point in the history
  • Loading branch information
EpicPlayerA10 committed Oct 12, 2024
1 parent 79375c6 commit e22d8f2
Show file tree
Hide file tree
Showing 15 changed files with 81 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import uwu.narumi.deobfuscator.api.helper.ClassHelper;
import uwu.narumi.deobfuscator.api.classpath.InheritanceClassWriter;
import uwu.narumi.deobfuscator.api.inheritance.InheritanceGraph;

public class ClassWrapper implements Cloneable {
public class ClassWrapper {

protected static final Logger LOGGER = LogManager.getLogger(ClassWrapper.class);

Expand All @@ -23,25 +22,16 @@ public class ClassWrapper implements Cloneable {
*/
private final String pathInJar;
private final ClassNode classNode;
private final FieldCache fieldCache;
private final ConstantPool constantPool;

public ClassWrapper(String pathInJar, ClassReader classReader, int classReaderFlags) {
this.pathInJar = pathInJar;
this.classNode = new ClassNode();
this.constantPool = new ConstantPool(classReader);
this.fieldCache = new FieldCache();

classReader.accept(this.classNode, classReaderFlags);
}

private ClassWrapper(String pathInJar, ClassNode classNode, FieldCache fieldCache, ConstantPool constantPool) {
this.pathInJar = pathInJar;
this.classNode = classNode;
this.fieldCache = fieldCache;
this.constantPool = constantPool;
}

public Optional<MethodNode> findMethod(String name, String desc) {
return classNode.methods.stream()
.filter(methodNode -> name == null || methodNode.name.equals(name))
Expand Down Expand Up @@ -153,16 +143,7 @@ public ClassNode classNode() {
return classNode;
}

public FieldCache getFieldCache() {
return fieldCache;
}

public ConstantPool getConstantPool() {
return constantPool;
}

@Override
public ClassWrapper clone() {
return new ClassWrapper(this.pathInJar, ClassHelper.copy(classNode), fieldCache.clone(), constantPool.clone());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.OriginalSourceValue;
import uwu.narumi.deobfuscator.api.helper.AsmHelper;

/**
* Instruction context. Holds all information relevant to the current instruction.
Expand Down Expand Up @@ -59,8 +60,7 @@ public void pop(int count) {
OriginalSourceValue sourceValue = frame().getStack(stackValueIdx);

// Pop
InsnNode popInsn = sourceValue.getSize() == 2 ? new InsnNode(Opcodes.POP2) : new InsnNode(Opcodes.POP);
this.methodNode().instructions.insertBefore(this.insn, popInsn);
this.methodNode().instructions.insertBefore(this.insn, AsmHelper.toPop(sourceValue));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.tree.analysis.Value;
import uwu.narumi.deobfuscator.api.asm.ClassWrapper;
import uwu.narumi.deobfuscator.api.asm.MethodContext;
import uwu.narumi.deobfuscator.api.asm.MethodRef;
Expand Down Expand Up @@ -129,6 +130,10 @@ public static Type getTypeFromPrimitiveCast(MethodInsnNode insn) {
throw new IllegalStateException("Unexpected value: " + insn.owner+"."+insn.name+insn.desc);
}

public static AbstractInsnNode toPop(Value value) {
return value.getSize() == 1 ? new InsnNode(POP) : new InsnNode(POP2);
}

/**
* Update method descriptor in the current class, a superclass and interfaces
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
import org.objectweb.asm.tree.analysis.Analyzer;
import org.objectweb.asm.tree.analysis.BasicInterpreter;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Value;
import uwu.narumi.deobfuscator.api.asm.NamedOpcodes;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
Expand All @@ -26,7 +30,7 @@

public class MethodHelper implements Opcodes {
/**
* Analyzes the stack frames of the method
* Analyzes the stack frames of the method using {@link OriginalSourceInterpreter}
*
* @param classNode The owner class
* @param methodNode Method
Expand All @@ -50,6 +54,31 @@ public static Map<AbstractInsnNode, Frame<OriginalSourceValue>> analyzeSource(
return Collections.unmodifiableMap(frames);
}

/**
* Analyzes the stack frames of the method using {@link BasicInterpreter}
*
* @param classNode The owner class
* @param methodNode Method
* @return A map which corresponds to: instruction -> its own stack frame
*/
@NotNull
@Unmodifiable
public static Map<AbstractInsnNode, Frame<BasicValue>> analyzeBasic(
ClassNode classNode, MethodNode methodNode
) {
Map<AbstractInsnNode, Frame<BasicValue>> frames = new HashMap<>();
Frame<BasicValue>[] framesArray;
try {
framesArray = new Analyzer<>(new BasicInterpreter()).analyze(classNode.name, methodNode);
} catch (AnalyzerException e) {
throw new RuntimeException(e);
}
for (int i = 0; i < framesArray.length; i++) {
frames.put(methodNode.instructions.get(i), framesArray[i]);
}
return Collections.unmodifiableMap(frames);
}

public static List<String> prettyInsnList(InsnList insnList) {
return prettyInsnList(Arrays.asList(insnList.toArray()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ protected void registerAll() {
register("Simple flow obfuscation", InputType.JAVA_CODE, List.of(ComposedGeneralFlowTransformer::new), Source.of("TestSimpleFlowObfuscation"));
register("Universal Number Transformer", InputType.JAVA_CODE, List.of(UniversalNumberTransformer::new), Source.of("TestUniversalNumberTransformer"));
// TODO: Uninitialized static fields should replace with 0?
register("Inline static fields", InputType.JAVA_CODE, List.of(InlineStaticFieldTransformer::new), Source.of("TestInlineStaticFields"));
register("Inline static fields with modification", InputType.JAVA_CODE, List.of(InlineStaticFieldTransformer::new), Source.of("TestInlineStaticFieldsWithModification"));
register("Inline static fields", InputType.JAVA_CODE, List.of(
InlineStaticFieldTransformer::new,
UselessPopCleanTransformer::new
), Source.of("TestInlineStaticFields"));
register("Inline static fields with modification", InputType.JAVA_CODE, List.of(
InlineStaticFieldTransformer::new,
UselessPopCleanTransformer::new
), Source.of("TestInlineStaticFieldsWithModification"));

// Test sandbox security (e.g. not allowing dangerous calls)
register("Sandbox security", InputType.JAVA_CODE, List.of(TestSandboxSecurityTransformer::new), Source.of("sandbox/TestSandboxSecurity", false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.analysis.BasicInterpreter;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.OriginalSourceValue;
import uwu.narumi.deobfuscator.api.asm.ClassWrapper;
Expand Down Expand Up @@ -89,6 +92,7 @@ protected void transform(ClassWrapper scope, Context context) throws Exception {
}));

// Replace static fields accesses with corresponding values
List<FieldRef> inlinedFields = new ArrayList<>();
context.classes(scope).forEach(classWrapper -> classWrapper.methods().forEach(methodNode -> {
Arrays.stream(methodNode.instructions.toArray())
.filter(insn -> insn.getOpcode() == GETSTATIC)
Expand All @@ -99,11 +103,42 @@ protected void transform(ClassWrapper scope, Context context) throws Exception {
if (constValue != null) {
// Replace it!
methodNode.instructions.set(insn, constValue.clone(null));

// Add to an inlined fields list
if (!inlinedFields.contains(fieldRef)) {
inlinedFields.add(fieldRef);
}

this.markChange();
}
});
}));

// Remove fields that were inlined
context.classes(scope).parallelStream().forEach(classWrapper -> {
// Remove field
classWrapper.classNode().fields.removeIf(fieldNode -> inlinedFields.contains(FieldRef.of(classWrapper.classNode(), fieldNode)));

// Replace PUTSTATIC with POP
classWrapper.findClInit().ifPresent(methodNode -> {
Map<AbstractInsnNode, Frame<BasicValue>> frames = MethodHelper.analyzeBasic(classWrapper.classNode(), methodNode);

Arrays.stream(methodNode.instructions.toArray())
.filter(insn -> insn.getOpcode() == PUTSTATIC)
.map(FieldInsnNode.class::cast)
.forEach(insn -> {
FieldRef fieldRef = FieldRef.of(insn);
if (inlinedFields.contains(fieldRef)) {
Frame<BasicValue> frame = frames.get(insn);
BasicValue value = frame.getStack(frame.getStackSize() - 1);

// Replace insn with pop
methodNode.instructions.set(insn, AsmHelper.toPop(value));
}
});
});
});

LOGGER.info("Inlined {} constant static fields", this.getChangesCount());
}
}
2 changes: 0 additions & 2 deletions testData/results/custom-classes/FlowObfSample.dec
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import org.bukkit.event.Listener;

public class IIIIIIIIlIlIIIIlIIlIIIIIIIIlIlIllllIIIlIIIlIIllIllllIIIIllIIIIllIIllllIIIIllllIIIIIIIllIllIIIlllIlIIllIlIIllIlIIIIIlIIIIIllllIlIIllIllllIIlIIIIIIlIllIlIIIIlIlIIlIIlllIIIIlIIlIIllIlIIIlIlIlIIIIllIlllll
implements Listener {
static long llllIIIIlllIlllIlIllIIlllIlIIlIIlllIlllIlllIIIllIlIIIIlIIIllIlIIlIIlIllIIlIlIIIIIIllIlIlIlIlIIllIlIllIlIIIllllllIlIIllIIllIlIlIIlIllIllIIIlIIlllIIIIIIIlIIIIIIIllIlIIIIIIlIIlIlIIlllIIIlllllIIIIlIIIlIlI;

public static int lIIIIlllIlIIllIIIlllllIlllIIllIllIIlIIllIIIllIIlIllllIIIIllIIlIIIIlIllIIlllIllIllllIIIlllIllIllIlllIlllllIIlIIIlllllIIIlIlIllllIllllIllllIIlIIllIlIIllIIllIIlIllIIllllIlllIIIIlIIllIIIIIIIIllllIlIllllIl(
int var0
) {
Expand Down
Binary file modified testData/results/custom-classes/hp888/Strings.dec
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ public final class PacketEvents implements Listener, EventManager {
private boolean terminating;
private boolean lateBind;
private static int Vulcan_k;
private static final long a = 110160429747013L;

public PacketEvents() {
int var10000 = Vulcan_Q();
Expand Down
1 change: 0 additions & 1 deletion testData/results/custom-classes/zkm/sample2/a4.dec
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public class a4 {
private static final char c;
private static final ConcurrentMap<String, List<Locale>> d;
private static final ConcurrentMap<String, List<Locale>> e;
private static final long f = 31437394211371L;
private static final String[] g;
private static final String[] h;
private static final Map i = new HashMap(13);
Expand Down
1 change: 0 additions & 1 deletion testData/results/custom-classes/zkm/sample2/a_.dec
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public class a_<T> implements Serializable {
private final T c;
private final T d;
private transient String e;
private static final long h = 104039320445854L;
private static final String[] i;
private static final String[] j;
private static final Map k = new HashMap(13);
Expand Down
1 change: 0 additions & 1 deletion testData/results/custom-classes/zkm/sample2/ba.dec
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import java.util.Comparator;

public class ba<N extends Number> extends a_<N> {
private static final long serialVersionUID = 1L;
private static final long g = 87486991067610L;

public ba(long var1, Number var3, Number var4, Comparator var5) {
var1 = 87486991067610L ^ var1;
Expand Down
1 change: 0 additions & 1 deletion testData/results/custom-classes/zkm/sample2/bc.dec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package a.a.a.a;

public final class bc extends ba<Integer> {
private static final long serialVersionUID = 1L;
private static final long f = 90497055901648L;

public static bc a(int var0, long var1, int var3) {
var1 = 90497055901648L ^ var1;
Expand Down
Loading

0 comments on commit e22d8f2

Please sign in to comment.