diff --git a/src/main/java/net/runelite/deob/attributes/code/instruction/types/ArrayStore.java b/src/main/java/net/runelite/deob/attributes/code/instruction/types/ArrayStoreInstruction.java similarity index 50% rename from src/main/java/net/runelite/deob/attributes/code/instruction/types/ArrayStore.java rename to src/main/java/net/runelite/deob/attributes/code/instruction/types/ArrayStoreInstruction.java index d6d6e9725c..be720de008 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instruction/types/ArrayStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instruction/types/ArrayStoreInstruction.java @@ -1,6 +1,6 @@ package net.runelite.deob.attributes.code.instruction.types; -public interface ArrayStore +public interface ArrayStoreInstruction extends MappableInstruction { } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/AAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/AAStore.java index 1f2775c1f4..9375ec6562 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/AAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/AAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class AAStore extends Instruction implements ArrayStore +public class AAStore extends ArrayStore { public AAStore(Instructions instructions, InstructionType type, int pc) { @@ -32,4 +30,5 @@ public class AAStore extends Instruction implements ArrayStore frame.addInstructionContext(ins); } + } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/BAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/BAStore.java index 32a50d44d9..f572308d44 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/BAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/BAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class BAStore extends Instruction implements ArrayStore +public class BAStore extends ArrayStore { public BAStore(Instructions instructions, InstructionType type, int pc) { diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/CAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/CAStore.java index 1af78ad6b3..ddc869ae95 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/CAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/CAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class CAStore extends Instruction implements ArrayStore +public class CAStore extends ArrayStore { public CAStore(Instructions instructions, InstructionType type, int pc) { diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/DAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/DAStore.java index 1e0f2c333e..3687f8f294 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/DAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/DAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class DAStore extends Instruction implements ArrayStore +public class DAStore extends ArrayStore { public DAStore(Instructions instructions, InstructionType type, int pc) { diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/Dup2.java b/src/main/java/net/runelite/deob/attributes/code/instructions/Dup2.java index f47ff14968..8a5240ccc6 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/Dup2.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/Dup2.java @@ -69,9 +69,32 @@ public class Dup2 extends Instruction implements DupInstruction } @Override - public StackContext getOriginal(StackContext ctx) + public StackContext getOriginal(StackContext sctx) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + // 2 1 -> 2 1 2 1 OR 1 -> 1 1 + InstructionContext ctx = sctx.getPushed(); + assert ctx.getPops().size() == 2 || ctx.getPops().size() == 1; + + assert ctx.getInstruction() == this; + assert ctx.getPushes().contains(sctx); + int idx = ctx.getPushes().indexOf(sctx); + + if (ctx.getPops().size() == 1) + { + return ctx.getPops().get(0); + } + + switch (idx) + { + case 0: + case 2: + return ctx.getPops().get(1); + case 1: + case 4: + return ctx.getPops().get(0); + default: + throw new IllegalStateException(); + } } @Override diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/FAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/FAStore.java index b7507e7d13..cdaf83283d 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/FAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/FAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class FAStore extends Instruction implements ArrayStore +public class FAStore extends ArrayStore { public FAStore(Instructions instructions, InstructionType type, int pc) { diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IAStore.java index 044e182dfb..5abea63b68 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class IAStore extends Instruction implements ArrayStore +public class IAStore extends ArrayStore { public IAStore(Instructions instructions, InstructionType type, int pc) { diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/LAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/LAStore.java index cf58357ee7..511b7457d6 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/LAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/LAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class LAStore extends Instruction implements ArrayStore +public class LAStore extends ArrayStore { public LAStore(Instructions instructions, InstructionType type, int pc) { diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/SAStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/SAStore.java index 458d03f6e1..8d0057d4fb 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/SAStore.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/SAStore.java @@ -1,15 +1,13 @@ package net.runelite.deob.attributes.code.instructions; -import net.runelite.deob.attributes.code.Instruction; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; -import net.runelite.deob.attributes.code.instruction.types.ArrayStore; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.Stack; import net.runelite.deob.execution.StackContext; -public class SAStore extends Instruction implements ArrayStore +public class SAStore extends ArrayStore { public SAStore(Instructions instructions, InstructionType type, int pc) { diff --git a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java index 2dd5822ca3..dd1e10b1d6 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -15,7 +15,6 @@ import net.runelite.deob.Method; 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.instruction.types.ArrayStore; import net.runelite.deob.attributes.code.instruction.types.FieldInstruction; import net.runelite.deob.attributes.code.instruction.types.GetFieldInstruction; import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction; @@ -32,6 +31,7 @@ import net.runelite.deob.execution.StackContext; import net.runelite.deob.pool.PoolEntry; import net.runelite.deob.signature.Type; import org.apache.commons.collections4.map.MultiValueMap; +import net.runelite.deob.attributes.code.instruction.types.ArrayStoreInstruction; public class ModArith implements Deobfuscator { @@ -51,7 +51,7 @@ public class ModArith implements Deobfuscator // invoke and array store pops are unrelated to each other if (ctx.getInstruction() instanceof InvokeInstruction || - ctx.getInstruction() instanceof ArrayStore) + ctx.getInstruction() instanceof ArrayStoreInstruction) return l; set.add(ctx.getInstruction()); diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java b/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java index 361c860eca..0d68b375b3 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/MappingExecutorUtil.java @@ -7,13 +7,20 @@ import java.util.stream.Collectors; import net.runelite.deob.ClassGroup; import net.runelite.deob.Method; import net.runelite.deob.attributes.code.Instruction; +import net.runelite.deob.attributes.code.instruction.types.DupInstruction; import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction; +import net.runelite.deob.attributes.code.instruction.types.LVTInstruction; import net.runelite.deob.attributes.code.instruction.types.MappableInstruction; +import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction; import net.runelite.deob.attributes.code.instructions.InvokeStatic; import net.runelite.deob.execution.Execution; import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.execution.ParallellMappingExecutor; +import net.runelite.deob.execution.StackContext; +import net.runelite.deob.execution.VariableContext; +import net.runelite.deob.execution.Variables; +import net.runelite.deob.signature.Signature; public class MappingExecutorUtil { @@ -144,4 +151,73 @@ public class MappingExecutorUtil { return i instanceof InvokeStatic && isMappable((InvokeStatic) i); } + + public static InstructionContext resolve( + InstructionContext ctx, + StackContext from // pushed from ctx + ) + { + if (ctx.getInstruction() instanceof SetFieldInstruction) + { + StackContext s = ctx.getPops().get(0); + return resolve(s.getPushed(), s); + } + + if (ctx.getInstruction() instanceof DupInstruction) + { + DupInstruction d = (DupInstruction) ctx.getInstruction(); + StackContext s = d.getOriginal(from); + return resolve(s.getPushed(), s); + } + + if (ctx.getInstruction() instanceof LVTInstruction) + { + LVTInstruction lvt = (LVTInstruction) ctx.getInstruction(); + Variables variables = ctx.getVariables(); + + if (lvt.store()) + { + StackContext s = ctx.getPops().get(0); // is this right? + return resolve(s.getPushed(), s); + } + else + { + VariableContext vctx = variables.get(lvt.getVariableIndex()); // variable being loaded + assert vctx != null; + + InstructionContext storedCtx = vctx.getInstructionWhichStored(); + if (storedCtx == null) + return ctx; // initial parameter + + if (vctx.isIsParameter()) + { + // Normally storedCtx being an InvokeInstruction means that this resolves to the + // return value of an invoke instruction, but if the variable is a parameter, it means + // this storedCtx is the invoke instruction which called this method. + assert storedCtx.getInstruction() instanceof InvokeInstruction; + // In PME non static functions are never stepped into/aren't inline obfuscated + assert storedCtx.getInstruction() instanceof InvokeStatic; + + // Figure out parameter index from variable index. + Signature sig = ctx.getFrame().getMethod().getDescriptor(); // signature of current method + int paramIndex = 0; + for (int lvtIndex = 0 /* static */; + paramIndex < sig.size(); + lvtIndex += sig.getTypeOfArg(paramIndex++).getSlots()) + if (lvtIndex == lvt.getVariableIndex()) + break; + assert paramIndex < sig.size(); + + // Get stack context that was popped by the invoke + // pops[0] is the first thing popped, which is the last parameter. + StackContext sctx = storedCtx.getPops().get(sig.size() - 1 - paramIndex); + return resolve(sctx.getPushed(), sctx); + } + + return resolve(storedCtx, null); + } + } + + return ctx; + } } diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java b/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java index a04a8f1931..66627ca7bf 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java @@ -26,7 +26,6 @@ import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction; import net.runelite.deob.deobfuscators.Renamer; import net.runelite.deob.deobfuscators.rename.graph.Edge; import net.runelite.deob.deobfuscators.rename.graph.EdgeType; -import net.runelite.deob.deobfuscators.rename.graph.FieldEdge; import net.runelite.deob.deobfuscators.rename.graph.Graph; import net.runelite.deob.deobfuscators.rename.graph.GraphBuilder; import net.runelite.deob.deobfuscators.rename.graph.Vertex; @@ -350,7 +349,15 @@ public class Rename2 if (m1.getName().equals("") || m1.getName().equals("")) return; - ParallelExecutorMapping mapping = MappingExecutorUtil.map(m1, m2); + ParallelExecutorMapping mapping = null; + try + { + mapping = MappingExecutorUtil.map(m1, m2); + } + catch (MappingException ex) + { + throw new RuntimeException(ex); + } System.out.println("EXEC " + count++ + " " + mname(m1) + " " + mname(m2) + " " + mapping); for (Entry e : mapping.getMap().entrySet()) diff --git a/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java b/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java index c352594728..9340ee5231 100644 --- a/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java +++ b/src/main/java/net/runelite/deob/execution/ParallellMappingExecutor.java @@ -20,13 +20,13 @@ public class ParallellMappingExecutor } boolean step1 = true, step2 = true; - int count; + static int count; public boolean step() { ++count; - if (count == 34403) + if (count == 65925) { int i = 5; } diff --git a/src/test/java/net/runelite/deob/deobfuscators/rename/MapTest.java b/src/test/java/net/runelite/deob/deobfuscators/rename/MapTest.java index 737296ce6e..c799155119 100644 --- a/src/test/java/net/runelite/deob/deobfuscators/rename/MapTest.java +++ b/src/test/java/net/runelite/deob/deobfuscators/rename/MapTest.java @@ -23,7 +23,7 @@ public class MapTest } @Test - public void test() throws IOException + public void test() throws IOException, MappingException { ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar")); ClassGroup group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));