Save before I rip this up

This commit is contained in:
Adam
2015-11-19 12:28:01 -05:00
parent 87d4bc1ee5
commit bda6242dcb
3 changed files with 123 additions and 45 deletions

View File

@@ -1,10 +1,9 @@
package net.runelite.deob.deobfuscators.rename; package net.runelite.deob.deobfuscators.rename;
import edu.ucla.sspace.graph.Edge;
import edu.ucla.sspace.graph.Graph; import edu.ucla.sspace.graph.Graph;
import edu.ucla.sspace.graph.isomorphism.IsomorphismTester; import edu.ucla.sspace.graph.isomorphism.IsomorphismTester;
import edu.ucla.sspace.graph.isomorphism.TypedVF2IsomorphismTester;
import edu.ucla.sspace.graph.isomorphism.VF2IsomorphismTester; import edu.ucla.sspace.graph.isomorphism.VF2IsomorphismTester;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@@ -15,10 +14,9 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.runelite.deob.ClassGroup; import net.runelite.deob.ClassGroup;
import net.runelite.deob.Method; import net.runelite.deob.Method;
import net.runelite.deob.attributes.code.Instruction;
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
import net.runelite.deob.execution.Execution; import net.runelite.deob.execution.Execution;
import net.runelite.deob.execution.Frame; import net.runelite.deob.execution.Frame;
import net.runelite.deob.execution.MethodContext;
public class Rename public class Rename
{ {
@@ -33,13 +31,54 @@ public class Rename
// methods which have been processed in the original // methods which have been processed in the original
private Set<Method> processed = new HashSet<>(); private Set<Method> processed = new HashSet<>();
private static String cname(Method m) { return m.getMethods().getClassFile().getName(); }
private static String mname(Method m) { return cname(m) + "." + m.getName(); }
private void compare(MethodContext m1, Graph g1, MethodContext m2, Graph g2)
{
Set<Edge> edges = new HashSet<>(g1.edges()); // edges in g1 not in g2
for (Edge e : (Set<Edge>) g2.edges())
{
edges.remove(e);
}
for (Edge e : edges)
{
Method me1 = m1.getIdMap().get(e.from()).get(0);
Method me2 = m1.getIdMap().get(e.to()).get(0);
System.out.println("EDGE IN 1 NOT IN 2: " + mname(me1) + " -> " + mname(me2));
Method om1 = m2.getIdMap().get(e.from()).get(0);
Method om2 = m2.getIdMap().get(e.to()).get(0);
System.out.println(" OTHER SIDE: " + mname(om1) + " -> " + mname(om2));
}
//System.out.println(edges);
if (g2.order() == g1.order())
{
int[] v1 = g1.vertices().toPrimitiveArray(),
v2 = g2.vertices().toPrimitiveArray();
for (int i = 0; i < g1.order(); ++i)
{
Method me1 = m1.getIdMap().get(v1[i]).get(0);
Method me2 = m2.getIdMap().get(v2[i]).get(0);
System.out.println("VMATCH " + mname(me1) + " -> " + mname(me2));
}
}
}
private boolean compare(Frame f1, Frame f2) private boolean compare(Frame f1, Frame f2)
{ {
Graph g1 = f1.getMethodCtx().getGraph(), g2 = f2.getMethodCtx().getGraph(); Graph g1 = f1.getMethodCtx().getGraph(), g2 = f2.getMethodCtx().getGraph();
IsomorphismTester isoTest = new /*Typed*/VF2IsomorphismTester(); IsomorphismTester isoTest = new /*Typed*/VF2IsomorphismTester();
if (!isoTest.areIsomorphic(g1, g2)) if (g1.size() != g2.size() || g1.order() != g2.order() || !isoTest.areIsomorphic(g1, g2))
{ {
System.out.println("IN " + mname(f1.getMethod()) + " -> " + mname(f2.getMethod()));
compare(f1.getMethodCtx(), g1, f2.getMethodCtx(), g2);
System.out.println("Not isomorphic " + g1.size() + " " + g2.size()); System.out.println("Not isomorphic " + g1.size() + " " + g2.size());
return false; return false;
} }
@@ -129,6 +168,7 @@ public class Rename
if (!b) if (!b)
{ {
System.out.println("Mismatch " + p1.getMethod().getMethods().getClassFile().getName() + "." + p1.getMethod().getName() + " <-> " + p2.getMethod().getMethods().getClassFile().getName() + "." + p2.getMethod().getName()); System.out.println("Mismatch " + p1.getMethod().getMethods().getClassFile().getName() + "." + p1.getMethod().getName() + " <-> " + p2.getMethod().getMethods().getClassFile().getName() + "." + p2.getMethod().getName());
System.out.println(one.getMethods().getClassFile().getName() + "." + one.getName() + " and " + two.getMethods().getClassFile().getName() + "." + two.getName());
int i =7; int i =7;
} }
break outer2; break outer2;
@@ -141,35 +181,35 @@ public class Rename
groupOne = one; groupOne = one;
groupTwo = two; groupTwo = two;
Execution eone = new Execution(one); // Execution eone = new Execution(one);
eone.setBuildGraph(true); // eone.setBuildGraph(true);
eone.setFollowInvokes(false); // eone.setFollowInvokes(false);
eone.populateInitialMethods(); // eone.populateInitialMethods();
List<Method> initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList()); // List<Method> initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
eone.run(); // eone.run();
//
// Execution etwo = new Execution(two);
// etwo.setBuildGraph(true);
// etwo.setFollowInvokes(false);
// etwo.populateInitialMethods();
// List<Method> 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 etwo = new Execution(two); process(
etwo.setBuildGraph(true); one.findClass("client").findMethod("vmethod2999"),
etwo.setFollowInvokes(false); two.findClass("client").findMethod("vmethod2978")
etwo.populateInitialMethods(); );
List<Method> 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(
// one.findClass("class143").findMethod("method3014"),
// two.findClass("class143").findMethod("method2966")
// );
for (;;) for (;;)
{ {

View File

@@ -118,6 +118,8 @@ public class Execution
public void invoke(InstructionContext from, Method to) public void invoke(InstructionContext from, Method to)
{ {
Frame frame = from.getFrame();
if (!this.isFollowInvokes() && !to.isStatic()) if (!this.isFollowInvokes() && !to.isStatic())
return; return;
@@ -127,6 +129,9 @@ public class Execution
Frame f = new Frame(this, to); Frame f = new Frame(this, to);
f.initialize(from); f.initialize(from);
this.addFrame(f); this.addFrame(f);
// if (!this.followInvokes && to.isStatic())
// frame.stop(); // frames continue from the method
} }
public void addMethod(Method to) public void addMethod(Method to)
@@ -145,13 +150,21 @@ public class Execution
methods.add(frame.getMethod()); methods.add(frame.getMethod());
if (!frame.isExecuting())
{
frames.remove(0);
processedFrames.add(frame);
continue;
}
++fcount; ++fcount;
assert frame.isExecuting();
frame.execute(); frame.execute();
if (!frame.isExecuting()) if (!frame.isExecuting())
{ {
assert frames.get(0) == frame; //assert frames.get(0) == frame;
frames.remove(0); frames.remove(frame);
processedFrames.add(frame); processedFrames.add(frame);
} }
else else

View File

@@ -1,15 +1,8 @@
package net.runelite.deob.execution; package net.runelite.deob.execution;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import edu.ucla.sspace.graph.DirectedEdge;
import edu.ucla.sspace.graph.Graph;
import edu.ucla.sspace.graph.SimpleDirectedEdge;
import edu.ucla.sspace.graph.SparseDirectedGraph;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import net.runelite.deob.Method; import net.runelite.deob.Method;
import net.runelite.deob.attributes.Code; import net.runelite.deob.attributes.Code;
import net.runelite.deob.attributes.code.Exception; import net.runelite.deob.attributes.code.Exception;
@@ -17,8 +10,7 @@ import net.runelite.deob.attributes.code.Instruction;
import net.runelite.deob.attributes.code.Instructions; import net.runelite.deob.attributes.code.Instructions;
import net.runelite.deob.pool.NameAndType; import net.runelite.deob.pool.NameAndType;
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction; import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
import net.runelite.deob.util.IdGen; import net.runelite.deob.attributes.code.instruction.types.ReturnInstruction;
import org.apache.commons.collections4.map.MultiValueMap;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
public class Frame public class Frame
@@ -34,6 +26,7 @@ public class Frame
protected MutableInt prevVertex = new MutableInt(-1); protected MutableInt prevVertex = new MutableInt(-1);
//protected int prevVertex = -1; //protected int prevVertex = -1;
//private List<Method> prevInvokes; //private List<Method> prevInvokes;
private Frame from;
public Frame(Execution execution, Method method) public Frame(Execution execution, Method method)
{ {
@@ -70,8 +63,10 @@ public class Frame
// initialize frame from invoking context // initialize frame from invoking context
assert ctx.getInstruction() instanceof InvokeInstruction; assert ctx.getInstruction() instanceof InvokeInstruction;
if (this.getMethod().isStatic()) if (!this.getExecution().isFollowInvokes() && this.getMethod().isStatic())
{ {
assert from == null;
from = ctx.getFrame();
this.ctx = ctx.getFrame().ctx; // share ctx if this method is static this.ctx = ctx.getFrame().ctx; // share ctx if this method is static
this.prevVertex = ctx.getFrame().prevVertex; this.prevVertex = ctx.getFrame().prevVertex;
} }
@@ -111,6 +106,7 @@ public class Frame
this.ctx = other.ctx; this.ctx = other.ctx;
this.prevVertex = new MutableInt(other.prevVertex); this.prevVertex = new MutableInt(other.prevVertex);
//this.prevInvokes = other.prevInvokes; //this.prevInvokes = other.prevInvokes;
from = other.from;
} }
public Frame dup() public Frame dup()
@@ -179,6 +175,10 @@ public class Frame
{ {
Instruction oldCur = cur; Instruction oldCur = cur;
if (cur instanceof ReturnInstruction)
if (processReturn())
break;
try try
{ {
cur.execute(this); cur.execute(this);
@@ -225,7 +225,11 @@ public class Frame
} }
if (!execution.frames.isEmpty() && execution.frames.get(0) != this) if (!execution.frames.isEmpty() && execution.frames.get(0) != this)
{
stop(); // the prev frame must be an invokestatic?
assert execution.frames.get(0).getMethod().isStatic();
break; break;
}
} }
} }
@@ -271,4 +275,25 @@ public class Frame
cur = to; cur = to;
} }
private boolean processReturn()
{
if (this.getExecution().isFollowInvokes() || !this.getMethod().isStatic())
return false;
if (from == null)
return false;
assert !from.isExecuting();
// update method, cur, stack, variables, from outermost method
this.method = from.method;
//this.executing = from.executing;
this.cur = from.cur;
this.stack = new Stack(from.stack);
this.variables = new Variables(from.variables);
//stop(); // now that weve switched this should still be running
return true; // this stops frame execution
}
} }