Add graphbuilder to statically build graph
This commit is contained in:
@@ -46,6 +46,17 @@ public class Graph
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeVertex(Object o)
|
||||||
|
{
|
||||||
|
Vertex v = this.getVertexFor(o);
|
||||||
|
|
||||||
|
assert v.getEdges().isEmpty();
|
||||||
|
assert v.getEdgesFrom().isEmpty();
|
||||||
|
|
||||||
|
verticies.remove(v);
|
||||||
|
o2v.remove(o);
|
||||||
|
}
|
||||||
|
|
||||||
public void addEdge(Edge e)
|
public void addEdge(Edge e)
|
||||||
{
|
{
|
||||||
e.getFrom().addEdge(e);
|
e.getFrom().addEdge(e);
|
||||||
|
|||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package net.runelite.deob.deobfuscators.rename.graph;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import net.runelite.deob.ClassFile;
|
||||||
|
import net.runelite.deob.ClassGroup;
|
||||||
|
import net.runelite.deob.Field;
|
||||||
|
import net.runelite.deob.Method;
|
||||||
|
import net.runelite.deob.attributes.Code;
|
||||||
|
import net.runelite.deob.attributes.code.Instruction;
|
||||||
|
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;
|
||||||
|
import net.runelite.deob.attributes.code.instructions.InvokeStatic;
|
||||||
|
|
||||||
|
public class GraphBuilder
|
||||||
|
{
|
||||||
|
public static Graph build(ClassGroup group)
|
||||||
|
{
|
||||||
|
// statically build
|
||||||
|
Graph g = new Graph();
|
||||||
|
|
||||||
|
// add verticies
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
//g.addVertex(cf, VertexType.CLASS);
|
||||||
|
|
||||||
|
for (Field f : cf.getFields().getFields())
|
||||||
|
{
|
||||||
|
g.addVertex(f, VertexType.FIELD);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Method m : cf.getMethods().getMethods())
|
||||||
|
{
|
||||||
|
g.addVertex(m, VertexType.METHOD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : cf.getMethods().getMethods())
|
||||||
|
{
|
||||||
|
processMethod(g, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove static methods
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : cf.getMethods().getMethods())
|
||||||
|
{
|
||||||
|
if (m.isStatic() && !m.getName().equals("<clinit>"))
|
||||||
|
{
|
||||||
|
removeMethod(g, m);
|
||||||
|
|
||||||
|
Vertex v = g.getVertexFor(m);
|
||||||
|
|
||||||
|
assert v.getEdges().isEmpty();
|
||||||
|
assert v.getEdgesFrom().isEmpty();
|
||||||
|
|
||||||
|
g.removeVertex(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processMethod(Graph graph, Method method)
|
||||||
|
{
|
||||||
|
Code code = method.getCode();
|
||||||
|
if (code == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (Instruction i : code.getInstructions().getInstructions())
|
||||||
|
{
|
||||||
|
if (i instanceof InvokeInstruction)
|
||||||
|
{
|
||||||
|
if (i instanceof InvokeStatic)
|
||||||
|
return;
|
||||||
|
|
||||||
|
InvokeInstruction ii = (InvokeInstruction) i;
|
||||||
|
|
||||||
|
List<Method> methods = ii.getMethods();
|
||||||
|
if (methods.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vertex methodVertex = graph.getVertexFor(method);
|
||||||
|
|
||||||
|
for (Method m : methods)
|
||||||
|
{
|
||||||
|
Vertex otherMethodVertex = graph.getVertexFor(m);
|
||||||
|
|
||||||
|
graph.addEdge(new Edge(null, methodVertex, otherMethodVertex, EdgeType.INVOKE));
|
||||||
|
graph.addEdge(new Edge(null, otherMethodVertex, methodVertex, EdgeType.INVOKED_FROM));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (i instanceof FieldInstruction)
|
||||||
|
{
|
||||||
|
FieldInstruction fi = (FieldInstruction) i;
|
||||||
|
|
||||||
|
if (fi.getMyField() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vertex methodVertex = graph.getVertexFor(method),
|
||||||
|
fieldVertex = graph.getVertexFor(fi.getMyField());
|
||||||
|
|
||||||
|
EdgeType type = fi instanceof GetFieldInstruction ? EdgeType.GETFIELD : EdgeType.SETFIELD;
|
||||||
|
graph.addEdge(new Edge(null, methodVertex, fieldVertex, type));
|
||||||
|
EdgeType typeRev = fi instanceof GetFieldInstruction ? EdgeType.GETFIELD_FROM : EdgeType.SETFIELD_FROM;
|
||||||
|
graph.addEdge(new Edge(null, fieldVertex, methodVertex, typeRev));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void removeMethod(Graph g, Method m)
|
||||||
|
{
|
||||||
|
Vertex v = g.getVertexFor(m);
|
||||||
|
|
||||||
|
// for every object that points to m, make it point to
|
||||||
|
// everything that m points to, with edge type of the edge from m.
|
||||||
|
|
||||||
|
for (Edge e : new HashSet<>(v.getEdgesFrom()))
|
||||||
|
{
|
||||||
|
// edge is TO v
|
||||||
|
assert e.getTo() == v;
|
||||||
|
|
||||||
|
Vertex from = e.getFrom();
|
||||||
|
|
||||||
|
// add an edge from -> everything v is to
|
||||||
|
|
||||||
|
for (Edge e2 : new HashSet<>(v.getEdges()))
|
||||||
|
{
|
||||||
|
assert e2.getFrom() == v;
|
||||||
|
|
||||||
|
Vertex to = e2.getTo();
|
||||||
|
EdgeType type = e2.getType();
|
||||||
|
|
||||||
|
// add edge
|
||||||
|
from.addEdge(new Edge(null, from, to, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// remove
|
||||||
|
from.removeEdge(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for every object m points to, everything that points to m should point to it.
|
||||||
|
for (Edge e : new HashSet<>(v.getEdges()))
|
||||||
|
{
|
||||||
|
assert e.getFrom() == v;
|
||||||
|
|
||||||
|
Vertex to = e.getTo();
|
||||||
|
EdgeType type = e.getType();
|
||||||
|
|
||||||
|
for (Edge e2 : new HashSet<>(v.getEdgesFrom()))
|
||||||
|
{
|
||||||
|
assert e2.getTo() == v;
|
||||||
|
|
||||||
|
// add edge from -> to
|
||||||
|
Vertex from = e2.getFrom();
|
||||||
|
|
||||||
|
from.addEdge(new Edge(null, from, to, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
v.removeEdge(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,8 @@ public class Vertex
|
|||||||
private final Object object;
|
private final Object object;
|
||||||
private VertexType type;
|
private VertexType type;
|
||||||
|
|
||||||
private final Set<Edge> edges = new HashSet<>();
|
private final Set<Edge> edges = new HashSet<>(),
|
||||||
|
from = new HashSet<>();
|
||||||
|
|
||||||
private Collection<Vertex> mightBe;
|
private Collection<Vertex> mightBe;
|
||||||
private Vertex is;
|
private Vertex is;
|
||||||
@@ -107,6 +108,9 @@ public class Vertex
|
|||||||
|
|
||||||
public void addEdge(Edge edge)
|
public void addEdge(Edge edge)
|
||||||
{
|
{
|
||||||
|
assert edge.getFrom() == this;
|
||||||
|
//assert edge.getTo() != this;
|
||||||
|
|
||||||
if (edges.contains(edge))
|
if (edges.contains(edge))
|
||||||
//if (c != null)
|
//if (c != null)
|
||||||
{
|
{
|
||||||
@@ -118,15 +122,38 @@ public class Vertex
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vertex to = edge.getTo();
|
||||||
|
assert to.from.contains(edge) == false;
|
||||||
|
|
||||||
edges.add(edge);
|
edges.add(edge);
|
||||||
|
to.from.add(edge);
|
||||||
|
|
||||||
//edges.put(edge, edge);
|
//edges.put(edge, edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeEdge(Edge edge)
|
||||||
|
{
|
||||||
|
assert edge.getFrom() == this;
|
||||||
|
|
||||||
|
assert edges.contains(edge);
|
||||||
|
|
||||||
|
Vertex to = edge.getTo();
|
||||||
|
assert to.from.contains(edge);
|
||||||
|
|
||||||
|
edges.remove(edge);
|
||||||
|
to.from.remove(edge);
|
||||||
|
}
|
||||||
|
|
||||||
public Set<Edge> getEdges()
|
public Set<Edge> getEdges()
|
||||||
{
|
{
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Edge> getEdgesFrom()
|
||||||
|
{
|
||||||
|
return from;
|
||||||
|
}
|
||||||
|
|
||||||
public void merge(Collection<Vertex> maybe)
|
public void merge(Collection<Vertex> maybe)
|
||||||
{
|
{
|
||||||
boolean b = false;
|
boolean b = false;
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package net.runelite.deob.deobfuscators.rename.graph;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import net.runelite.deob.ClassGroup;
|
||||||
|
import net.runelite.deob.util.JarUtil;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class GraphBuilderTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void test() throws IOException
|
||||||
|
{
|
||||||
|
ClassGroup group = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));
|
||||||
|
GraphBuilder.build(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user