diff --git a/pom.xml b/pom.xml index f0f8bb8be5..4b58e1d18a 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,11 @@ gson 2.4 + + org.apache.commons + commons-lang3 + 3.1 + org.slf4j diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/Rename.java b/src/main/java/net/runelite/deob/deobfuscators/rename/Rename.java index 4e890bb320..5e7c8c6372 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/Rename.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/Rename.java @@ -129,41 +129,35 @@ public class Rename groupOne = one; groupTwo = two; - Execution eone = new Execution(one); - eone.setBuildGraph(true); - eone.setFollowInvokes(false); - eone.populateInitialMethods(); - List initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList()); - eone.run(); - - Execution etwo = new Execution(two); - etwo.setBuildGraph(true); - etwo.setFollowInvokes(false); - etwo.populateInitialMethods(); - List initial2 = etwo.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList()); - etwo.run(); - - assert initial1.size() == initial2.size(); - - for (int i = 0; i < initial1.size(); ++i) - { - Method m1 = initial1.get(i), m2 = initial2.get(i); - - assert m1.getName().equals(m2.getName()); - - objMap.put(m1, m2); - } +// Execution eone = new Execution(one); +// eone.setBuildGraph(true); +// eone.setFollowInvokes(false); +// eone.populateInitialMethods(); +// List initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList()); +// eone.run(); +// +// Execution etwo = new Execution(two); +// etwo.setBuildGraph(true); +// etwo.setFollowInvokes(false); +// etwo.populateInitialMethods(); +// List initial2 = etwo.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList()); +// etwo.run(); +// +// assert initial1.size() == initial2.size(); +// +// for (int i = 0; i < initial1.size(); ++i) +// { +// Method m1 = initial1.get(i), m2 = initial2.get(i); +// +// assert m1.getName().equals(m2.getName()); +// +// objMap.put(m1, m2); +// } -// process( -// initial1.get(0).getMethod(), -// initial2.get(0).getMethod() -// ); -// processed.add(initial1.get(0).getMethod()); -// process( -// one.findClass("class143").findMethod("run"), -// two.findClass("class143").findMethod("run") -// ); -// processed.add(one.findClass("client").findMethod("init")); + process( + one.findClass("class143").findMethod("method3014"), + two.findClass("class143").findMethod("method2966") + ); for (;;) { diff --git a/src/main/java/net/runelite/deob/execution/Execution.java b/src/main/java/net/runelite/deob/execution/Execution.java index 32b3fa753e..7a85773b06 100644 --- a/src/main/java/net/runelite/deob/execution/Execution.java +++ b/src/main/java/net/runelite/deob/execution/Execution.java @@ -115,15 +115,16 @@ public class Execution public void invoke(InstructionContext from, Method to) { - if (!this.isFollowInvokes()) + if (!this.isFollowInvokes() && !to.isStatic()) return; - if (hasInvoked(from, to)) - return; +// if (hasInvoked(from, to)) +// return; Frame f = new Frame(this, to); f.initialize(from); - this.addFrame(f); + frames.add(0, f); + //this.addFrame(f); } public void addMethod(Method to) diff --git a/src/main/java/net/runelite/deob/execution/Frame.java b/src/main/java/net/runelite/deob/execution/Frame.java index 21b231d3fa..37e3751334 100644 --- a/src/main/java/net/runelite/deob/execution/Frame.java +++ b/src/main/java/net/runelite/deob/execution/Frame.java @@ -19,6 +19,7 @@ import net.runelite.deob.pool.NameAndType; import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction; import net.runelite.deob.util.IdGen; import org.apache.commons.collections4.map.MultiValueMap; +import org.apache.commons.lang3.mutable.MutableInt; public class Frame { @@ -30,8 +31,9 @@ public class Frame private Variables variables; private List instructions = new ArrayList<>(); // instructions executed in this frame private MethodContext ctx; - protected int prevVertex = -1; - private List prevInvokes; + protected MutableInt prevVertex = new MutableInt(-1); + //protected int prevVertex = -1; + //private List prevInvokes; public Frame(Execution execution, Method method) { @@ -68,6 +70,12 @@ public class Frame // initialize frame from invoking context assert ctx.getInstruction() instanceof InvokeInstruction; + if (this.getMethod().isStatic()) + { + this.ctx = ctx.getFrame().ctx; // share ctx if this method is static + this.prevVertex = ctx.getFrame().prevVertex; + } + // initialize LVT. the last argument is popped first, and is at arguments[0] List pops = ctx.getPops(); pops = Lists.reverse(new ArrayList<>(pops)); // reverse the list so first argument is at index 0 @@ -101,8 +109,8 @@ public class Frame this.stack = new Stack(other.stack); this.variables = new Variables(other.variables); this.ctx = other.ctx; - this.prevVertex = other.prevVertex; - this.prevInvokes = other.prevInvokes; + this.prevVertex = new MutableInt(other.prevVertex); + //this.prevInvokes = other.prevInvokes; } public Frame dup() @@ -193,12 +201,15 @@ public class Frame execution.executed.add(oldCur); + if (!execution.frames.isEmpty() && execution.frames.get(0) != this) + break; + processExceptions(oldCur); if (oldCur instanceof InvokeInstruction) { InvokeInstruction ii = (InvokeInstruction) oldCur; - this.prevInvokes = ii.getMethods(); + // this.prevInvokes = ii.getMethods(); } if (!executing) @@ -253,7 +264,7 @@ public class Frame assert to.getInstructions() == method.getCode().getInstructions(); assert method.getCode().getInstructions().getInstructions().contains(to); - if (ctx.hasJumped(this.prevInvokes, from, to)) + if (ctx.hasJumped(prevVertex, from, to)) { executing = false; return; diff --git a/src/main/java/net/runelite/deob/execution/MethodContext.java b/src/main/java/net/runelite/deob/execution/MethodContext.java index d91cbdeccc..5a644748f0 100644 --- a/src/main/java/net/runelite/deob/execution/MethodContext.java +++ b/src/main/java/net/runelite/deob/execution/MethodContext.java @@ -15,24 +15,25 @@ import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction; import net.runelite.deob.attributes.code.instructions.InvokeStatic; import net.runelite.deob.util.IdGen; import org.apache.commons.collections4.map.MultiValueMap; +import org.apache.commons.lang3.mutable.MutableInt; class MIKey { - private List method; + private int prevVertex; private InstructionContext ictx; - public MIKey(List method, InstructionContext ictx) + public MIKey(int prevVertex, InstructionContext ictx) { - this.method = method; + this.prevVertex = prevVertex; this.ictx = ictx; } @Override public int hashCode() { - int hash = 5; - hash = 61 * hash + Objects.hashCode(this.method); - hash = 61 * hash + Objects.hashCode(this.ictx); + int hash = 7; + hash = 97 * hash + this.prevVertex; + hash = 97 * hash + Objects.hashCode(this.ictx); return hash; } @@ -52,7 +53,7 @@ class MIKey return false; } final MIKey other = (MIKey) obj; - if (!Objects.equals(this.method, other.method)) + if (this.prevVertex != other.prevVertex) { return false; } @@ -62,8 +63,6 @@ class MIKey } return true; } - - } public class MethodContext @@ -90,10 +89,10 @@ public class MethodContext return graph; } - protected boolean hasJumped(List fromm, InstructionContext from, Instruction to) + protected boolean hasJumped(MutableInt prevVertex, InstructionContext from, Instruction to) { // with this true, there are so many frames I can't run a full execution without oom. - MIKey key = execution.isBuildGraph() ? new MIKey(fromm, from) : new MIKey(null, from); + MIKey key = execution.isBuildGraph() ? new MIKey(prevVertex.intValue(), from) : new MIKey(-1, from); Collection i = visited.getCollection(key); if (i != null && i.contains(to)) return true; @@ -124,8 +123,8 @@ public class MethodContext if (i instanceof InvokeInstruction) { -// if (i instanceof InvokeStatic) -// return; + if (i instanceof InvokeStatic) + return; InvokeInstruction ii = (InvokeInstruction) i; @@ -145,12 +144,12 @@ public class MethodContext return; } - if (frame.prevVertex == -1) + if (frame.prevVertex.intValue() == -1) { int id = getIdFor(i); //int id = ids.get(); //graph.add(id); - frame.prevVertex = id; + frame.prevVertex.setValue(id); //this.idMap.put(id, i); return; } @@ -160,12 +159,16 @@ public class MethodContext //graph.add(id); //idMap.put(id, i); - if (id == frame.prevVertex) + if (frame.prevVertex.intValue() == id) return; - DirectedEdge edge = new SimpleDirectedEdge(frame.prevVertex, id); + InvokeInstruction from = (InvokeInstruction) this.idMap.get(frame.prevVertex.intValue()), to = (InvokeInstruction) this.idMap.get(id); + System.out.println("Added edge " + from.getMethods().get(0).getMethods().getClassFile().getName() + "." + from.getMethods().get(0).getName() + + " to " + to.getMethods().get(0).getMethods().getClassFile().getName() + "." + to.getMethods().get(0).getName()); + + DirectedEdge edge = new SimpleDirectedEdge(frame.prevVertex.intValue(), id); graph.add(edge); - frame.prevVertex = id; + frame.prevVertex.setValue(id); } }