diff --git a/src/main/java/net/runelite/deob/ClassFile.java b/src/main/java/net/runelite/deob/ClassFile.java index c8713441ce..3320f250e8 100644 --- a/src/main/java/net/runelite/deob/ClassFile.java +++ b/src/main/java/net/runelite/deob/ClassFile.java @@ -61,6 +61,7 @@ public class ClassFile { this.group = group; + interfaces = new Interfaces(this); fields = new Fields(this); methods = new Methods(this); attributes = new Attributes(this); @@ -131,6 +132,16 @@ public class ClassFile this.name = new Class(name); } + public String getSuperName() + { + return super_class.getName(); + } + + public void setSuperName(String name) + { + super_class = new Class(name); + } + public Class getParentClass() { return this.super_class; diff --git a/src/main/java/net/runelite/deob/Interfaces.java b/src/main/java/net/runelite/deob/Interfaces.java index 4bee37f2df..f8a877721e 100644 --- a/src/main/java/net/runelite/deob/Interfaces.java +++ b/src/main/java/net/runelite/deob/Interfaces.java @@ -24,6 +24,11 @@ public class Interfaces interfaces.add(c.getPool().getClass(is.readUnsignedShort())); } + Interfaces(ClassFile c) + { + classFile = c; + } + public List getInterfaces() { return interfaces; diff --git a/src/main/java/net/runelite/deob/Method.java b/src/main/java/net/runelite/deob/Method.java index a915c47c5a..e32c63d51b 100644 --- a/src/main/java/net/runelite/deob/Method.java +++ b/src/main/java/net/runelite/deob/Method.java @@ -75,6 +75,11 @@ public class Method return attributes; } + public void setAttributes(Attributes a) + { + this.attributes = a; + } + public String getName() { return name; @@ -100,6 +105,11 @@ public class Method return (accessFlags & ACC_STATIC) != 0; } + public void setStatic() + { + accessFlags |= ACC_STATIC; + } + public boolean isSynchronized() { return (accessFlags & ACC_SYNCHRONIZED) != 0; diff --git a/src/main/java/net/runelite/deob/Methods.java b/src/main/java/net/runelite/deob/Methods.java index 63460f825b..dac43dc9f5 100644 --- a/src/main/java/net/runelite/deob/Methods.java +++ b/src/main/java/net/runelite/deob/Methods.java @@ -37,6 +37,11 @@ public class Methods m.write(out); } + public void addMethod(Method m) + { + methods.add(m); + } + public void removeMethod(Method m) { methods.remove(m); diff --git a/src/main/java/net/runelite/deob/attributes/Code.java b/src/main/java/net/runelite/deob/attributes/Code.java index 6dee991646..4ac3ccdc2e 100644 --- a/src/main/java/net/runelite/deob/attributes/Code.java +++ b/src/main/java/net/runelite/deob/attributes/Code.java @@ -23,6 +23,7 @@ public class Code extends Attribute exceptions = new Exceptions(this); this.attributes = new Attributes(this); + instructions = new Instructions(this); } @Override diff --git a/src/main/java/net/runelite/deob/attributes/code/Instructions.java b/src/main/java/net/runelite/deob/attributes/code/Instructions.java index 20170e8b36..2125c9c1a3 100644 --- a/src/main/java/net/runelite/deob/attributes/code/Instructions.java +++ b/src/main/java/net/runelite/deob/attributes/code/Instructions.java @@ -71,6 +71,11 @@ public class Instructions return instructions; } + public void addInstruction(Instruction i) + { + instructions.add(i); + } + public List getBlocks() { return blocks; diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/Dup_X1.java b/src/main/java/net/runelite/deob/attributes/code/instructions/Dup_X1.java index 7c26c66d76..41a82e5ac3 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/Dup_X1.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/Dup_X1.java @@ -12,10 +12,15 @@ import net.runelite.deob.attributes.code.instruction.types.DupInstruction; public class Dup_X1 extends Instruction implements DupInstruction { - public Dup_X1(Instructions instructions, InstructionType type, int pc) throws IOException + public Dup_X1(Instructions instructions, InstructionType type, int pc) { super(instructions, type, pc); } + + public Dup_X1(Instructions instructions) + { + super(instructions, InstructionType.DUP_X1, -1); + } @Override public void execute(Frame frame) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java index 02af0586c6..80f4e35955 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IConst_3.java @@ -21,7 +21,7 @@ public class IConst_3 extends Instruction implements PushConstantInstruction public IConst_3(Instructions instructions) { - super(instructions, InstructionType.ICONST_3, 0); + super(instructions, InstructionType.ICONST_3, -1); } @Override diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/ILoad.java b/src/main/java/net/runelite/deob/attributes/code/instructions/ILoad.java index b9b7403b07..88dd26a874 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/ILoad.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/ILoad.java @@ -24,7 +24,7 @@ public class ILoad extends Instruction implements LVTInstruction, WideInstructio public ILoad(Instructions instructions, int index) { - super(instructions, InstructionType.ILOAD, 0); + super(instructions, InstructionType.ILOAD, -1); this.index = index; ++length; } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java index 7b006d99a8..7bb7db6de1 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java @@ -16,10 +16,15 @@ import java.io.IOException; public class IStore_0 extends Instruction implements LVTInstruction { - public IStore_0(Instructions instructions, InstructionType type, int pc) throws IOException + public IStore_0(Instructions instructions, InstructionType type, int pc) { super(instructions, type, pc); } + + public IStore_0(Instructions instructions) + { + super(instructions, InstructionType.ISTORE_0, -1); + } @Override public void execute(Frame frame) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/LDC_W.java b/src/main/java/net/runelite/deob/attributes/code/instructions/LDC_W.java index 303d944248..8064b069f5 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/LDC_W.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/LDC_W.java @@ -33,6 +33,11 @@ public class LDC_W extends Instruction implements PushConstantInstruction length += 2; } + public LDC_W(Instructions instructions, int value) + { + this(instructions, new net.runelite.deob.pool.Integer(value)); + } + @Override public void load(DataInputStream is) throws IOException { @@ -148,4 +153,9 @@ public class LDC_W extends Instruction implements PushConstantInstruction return super.makeSpecific(); } + + public int getConstantAsInt() + { + return (int) value.getObject(); + } } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/Pop.java b/src/main/java/net/runelite/deob/attributes/code/instructions/Pop.java index 03ede0dc36..44420a5bcf 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/Pop.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/Pop.java @@ -7,14 +7,18 @@ import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.StackContext; -import java.io.IOException; public class Pop extends Instruction { - public Pop(Instructions instructions, InstructionType type, int pc) throws IOException + public Pop(Instructions instructions, InstructionType type, int pc) { super(instructions, type, pc); } + + public Pop(Instructions instructions) + { + super(instructions, InstructionType.POP, -1); + } @Override public void execute(Frame frame) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/VReturn.java b/src/main/java/net/runelite/deob/attributes/code/instructions/VReturn.java index 0e16aee782..952f3504e1 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/VReturn.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/VReturn.java @@ -14,6 +14,11 @@ public class VReturn extends Instruction implements ReturnInstruction { super(instructions, type, pc); } + + public VReturn(Instructions instructions) + { + super(instructions, InstructionType.RETURN, -1); + } @Override public void execute(Frame frame) diff --git a/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscatorTest.java b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscatorTest.java new file mode 100644 index 0000000000..1e1024152d --- /dev/null +++ b/src/test/java/net/runelite/deob/deobfuscators/arithmetic/MultiplicationDeobfuscatorTest.java @@ -0,0 +1,119 @@ +package net.runelite.deob.deobfuscators.arithmetic; + +import net.runelite.deob.ClassFile; +import net.runelite.deob.ClassGroup; +import net.runelite.deob.Deobfuscator; +import net.runelite.deob.Method; +import net.runelite.deob.Methods; +import net.runelite.deob.attributes.Attributes; +import net.runelite.deob.attributes.Code; +import net.runelite.deob.attributes.code.Instruction; +import net.runelite.deob.attributes.code.Instructions; +import net.runelite.deob.attributes.code.instructions.Dup_X1; +import net.runelite.deob.attributes.code.instructions.IConst_0; +import net.runelite.deob.attributes.code.instructions.IConst_3; +import net.runelite.deob.attributes.code.instructions.ILoad; +import net.runelite.deob.attributes.code.instructions.IMul; +import net.runelite.deob.attributes.code.instructions.IStore_0; +import net.runelite.deob.attributes.code.instructions.LDC_W; +import net.runelite.deob.attributes.code.instructions.Pop; +import net.runelite.deob.attributes.code.instructions.VReturn; +import net.runelite.deob.execution.Execution; +import net.runelite.deob.signature.Signature; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class MultiplicationDeobfuscatorTest +{ + private ClassGroup group; + private Code code; + private Instructions ins; + + @Before + public void init() + { + group = new ClassGroup(); + + ClassFile cf = new ClassFile(group); + cf.setName("test"); + cf.setSuperName("java/lang/Object"); + group.addClass(cf); + + Methods methods = cf.getMethods(); + Method method = new Method(methods, "func", new Signature("()V")); + method.setStatic(); + methods.addMethod(method); + + Attributes methodAttributes = method.getAttributes(); + + code = new Code(methodAttributes); + methodAttributes.addAttribute(code); + + ins = code.getInstructions(); + } + + // aload 2 + // ldc_w 1587543155 + // iload 4 + // imul + // dup_x1 + // ldc_w -2130376517 + // imul + // putfield class2/field279 I + // ldc_w -67313687 + // imul + // putstatic class29/field949 I + @Test + public void testDupX1() + { + code.setMaxStack(5); + + // vars[0] = 3 + Instruction[] prepareVariables = { + new IConst_3(ins), + new IStore_0(ins) + }; + + for (Instruction i : prepareVariables) + ins.addInstruction(i); + + LDC_W constant1 = new LDC_W(ins, 1587543155), + constant2 = new LDC_W(ins, -2130376517), + constant3 = new LDC_W(ins, -67313687); + + Instruction body[] = { + new IConst_0(ins), // for dup_x1 to place before this + constant1, + new ILoad(ins, 0), + new IMul(ins), + new Dup_X1(ins), + constant2, + new IMul(ins), + new Pop(ins), + new Pop(ins), + constant3, + new IMul(ins), + new Pop(ins), + new VReturn(ins) + }; + + for (Instruction i : body) + ins.addInstruction(i); + + // check execution runs ok + Execution e = new Execution(group); + e.populateInitialMethods(); + e.run(); + + assert constant1.getConstantAsInt() * constant2.getConstantAsInt() == 1; + assert constant1.getConstantAsInt() * constant3.getConstantAsInt() == -1_095_175_765; + + Deobfuscator d = new MultiplicationDeobfuscator(); + d.run(group); + + Assert.assertEquals(1, constant1.getConstantAsInt()); + Assert.assertEquals(1, constant2.getConstantAsInt()); + Assert.assertEquals(-1_095_175_765, constant3.getConstantAsInt()); + } +}