diff --git a/src/main/java/net/runelite/deob/attributes/ConstantValue.java b/src/main/java/net/runelite/deob/attributes/ConstantValue.java index 44f8d92af3..c64e739049 100644 --- a/src/main/java/net/runelite/deob/attributes/ConstantValue.java +++ b/src/main/java/net/runelite/deob/attributes/ConstantValue.java @@ -5,6 +5,7 @@ import net.runelite.deob.pool.PoolEntry; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Objects; public class ConstantValue extends Attribute { @@ -38,4 +39,35 @@ public class ConstantValue extends Attribute { out.writeShort(this.getAttributes().getClassFile().getPool().make(value)); } + + @Override + public int hashCode() + { + int hash = 3; + hash = 79 * hash + Objects.hashCode(this.value); + return hash; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + final ConstantValue other = (ConstantValue) obj; + if (!Objects.equals(this.value, other.value)) + { + return false; + } + return true; + } } 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 413ca59407..364fb388dd 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java @@ -1,5 +1,6 @@ package net.runelite.deob.deobfuscators.rename; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -11,10 +12,13 @@ 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.instruction.types.SetFieldInstruction; import net.runelite.deob.deobfuscators.rename.graph.Graph; import net.runelite.deob.deobfuscators.rename.graph.Vertex; import net.runelite.deob.deobfuscators.rename.graph.VertexType; import net.runelite.deob.execution.Execution; +import net.runelite.deob.execution.Frame; +import net.runelite.deob.execution.InstructionContext; import net.runelite.deob.signature.Signature; import net.runelite.deob.util.NameMappings; @@ -23,7 +27,7 @@ public class Rename2 private Graph g1, g2; private static String cname(Method m) { return m.getMethods().getClassFile().getName(); } - private static String mname(Method m) { return cname(m) + "." + m.getName(); } + public static String mname(Method m) { return cname(m) + "." + m.getName(); } private static String fname(Field f) { return f.getFields().getClassFile().getName() + "." + f.getName(); } public static void collide(Object o0, Object o1, Object o2) @@ -92,6 +96,27 @@ public class Rename2 } } + private List getClientFields(ClassGroup group, Execution e) + { + Method clinit = group.findClass("client").findMethod(""); + Frame frame = e.processedFrames.stream().filter(f -> f.getMethod() == clinit).findFirst().get(); + + List fields = new ArrayList<>(); + for (InstructionContext i : frame.getInstructions()) + { + if (i.getInstruction() instanceof SetFieldInstruction) + { + SetFieldInstruction sfi = (SetFieldInstruction) i.getInstruction(); + Field f = sfi.getMyField(); + + if (f != null) + fields.add(f); + } + } + + return fields; + } + private void solve() { List solved = g1.getVerticies().stream().filter(v -> v.getOther() != null).collect(Collectors.toList()); @@ -101,14 +126,13 @@ public class Rename2 Vertex other = s.getOther(); s.getEdges().stream() - //.map(e -> e.getTo()) // e.from is always s .filter(e -> e.getTo().getOther() == null) // only get vertexes that aren't solved yet .forEach(e -> e.getTo().merge( other.getEdges().stream() .filter(e2 -> e2.getTo().getOther() == null) .filter(e2 -> e.getTo().couldBeEqual(e2.getTo())) - .filter(e2 -> e.getType() == e2.getType()) + .filter(e2 -> e.couldBeEqual(e2)) .map(e2 -> e2.getTo()) .collect(Collectors.toList()) ) @@ -144,6 +168,22 @@ public class Rename2 mapClassMethods(m1, m2); } + List fl1 = getClientFields(one, eone); + List fl2 = getClientFields(two, etwo); + + for (int i = 0; i < Math.min(fl1.size(), fl2.size()); ++i) + { + Field f1 = fl1.get(i), f2 = fl2.get(i); + + Vertex v1 = g1.getVertexFor(f1); + Vertex v2 = g2.getVertexFor(f2); + + v1.is(v2); + v2.is(v1); + + System.out.println(fname(f1) + " is " + fname(f2)); + } + for (;;) { int before = g1.solved(null); diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Edge.java b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Edge.java index 3fab87f591..0bd768ca3f 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Edge.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Edge.java @@ -6,6 +6,7 @@ public class Edge { private final Vertex from, to; private final EdgeType type; + private int weight; public Edge(Vertex from, Vertex to, EdgeType type) { @@ -29,7 +30,17 @@ public class Edge public EdgeType getType() { return type; - } + } + + public void increase() + { + ++weight; + } + + public int getWeight() + { + return weight; + } @Override public int hashCode() @@ -71,4 +82,15 @@ public class Edge } return true; } + + public boolean couldBeEqual(Edge other) + { + if (this.type != other.type) + return false; + +// if (this.weight != other.weight) +// return false; + + return true; + } } diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Graph.java b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Graph.java index a26341e6ac..72cde7b536 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Graph.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Graph.java @@ -10,7 +10,6 @@ public class Graph private List verticies = new ArrayList<>(); private Map o2v = new HashMap<>(); - private int edgeCount; public Vertex getVertexFor(Object o) { @@ -32,8 +31,7 @@ public class Graph Vertex v1 = getVertexFor(from), v2 = getVertexFor(to); Edge e = new Edge(v1, v2, type); - if (v1.addEdge(e)) - ++edgeCount; + v1.addEdge(e); } public List getVerticies() @@ -45,16 +43,11 @@ public class Graph { return verticies.size(); } - - public int edgeCount() - { - return edgeCount; - } @Override public String toString() { - return "Graph{" + "verticies=" + verticies.size() + ", edgeCount=" + edgeCount + '}'; + return "Graph{" + "verticies=" + verticies.size() + "}"; } public void check() diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Vertex.java b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Vertex.java index 5b43cd631f..9680f35e76 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Vertex.java +++ b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/Vertex.java @@ -1,12 +1,21 @@ package net.runelite.deob.deobfuscators.rename.graph; +import com.google.common.base.Objects; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import net.runelite.deob.ClassFile; import net.runelite.deob.Field; import net.runelite.deob.Method; +import net.runelite.deob.attributes.AttributeType; +import net.runelite.deob.attributes.Code; +import net.runelite.deob.attributes.ConstantValue; +import net.runelite.deob.attributes.code.Instruction; +import net.runelite.deob.attributes.code.instruction.types.PushConstantInstruction; import net.runelite.deob.deobfuscators.rename.Rename2; +import net.runelite.deob.pool.PoolEntry; import org.apache.commons.collections4.CollectionUtils; public class Vertex @@ -15,7 +24,7 @@ public class Vertex private Object object; private VertexType type; - private Set edges = new HashSet<>(); + private final Map edges = new HashMap<>(); private Collection mightBe; private Vertex is; @@ -52,14 +61,21 @@ public class Vertex this.type = type; } - public boolean addEdge(Edge edge) + public void addEdge(Edge edge) { - return edges.add(edge); + Edge c = edges.get(edge); + if (c != null) + { + c.increase(); + return; + } + + edges.put(edge, edge); } public Set getEdges() { - return edges; + return edges.keySet(); } public void merge(Collection maybe) @@ -115,6 +131,37 @@ public class Vertex return true; } + private boolean couldBeEqual(Method m1, Method m2) + { + Set h1 = new HashSet<>(), + h2 = new HashSet<>(); + + if (m1.getCode() == null) + return true; + + for (Instruction i : m1.getCode().getInstructions().getInstructions()) + { + if (i instanceof PushConstantInstruction) + { + PushConstantInstruction pci = (PushConstantInstruction) i; + h1.add(pci.getConstant()); + } + } + + for (Instruction i : m2.getCode().getInstructions().getInstructions()) + { + if (i instanceof PushConstantInstruction) + { + PushConstantInstruction pci = (PushConstantInstruction) i; + h2.add(pci.getConstant()); + } + } + + boolean b = h1.equals(h2); + return b; + //return true; + } + public boolean couldBeEqual(Vertex other) { assert this != other; @@ -142,10 +189,16 @@ public class Vertex if (m1.getAccessFlags() != m2.getAccessFlags()) return false; + if ((m1.getCode() == null) != (m2.getCode() == null)) + return false; + ClassFile cf1 = m1.getMethods().getClassFile(), cf2 = m2.getMethods().getClassFile(); if (!couldBeEqual(cf1, cf2)) return false; + +// if (!couldBeEqual(m1, m2)) +// return false; } else if (type == VertexType.FIELD) { @@ -165,6 +218,12 @@ public class Vertex if (!couldBeEqual(cf1, cf2)) return false; } + + ConstantValue cf1 = (ConstantValue) f1.getAttributes().findType(AttributeType.CONSTANT_VALUE); + ConstantValue cf2 = (ConstantValue) f2.getAttributes().findType(AttributeType.CONSTANT_VALUE); + + if (!Objects.equal(cf1, cf2)) + return false; } else assert false; diff --git a/src/main/java/net/runelite/deob/execution/Execution.java b/src/main/java/net/runelite/deob/execution/Execution.java index aca80f659e..7baae880b7 100644 --- a/src/main/java/net/runelite/deob/execution/Execution.java +++ b/src/main/java/net/runelite/deob/execution/Execution.java @@ -20,6 +20,7 @@ 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; import net.runelite.deob.deobfuscators.arithmetic.Encryption; +import net.runelite.deob.deobfuscators.rename.Rename2; import net.runelite.deob.deobfuscators.rename.graph.EdgeType; import net.runelite.deob.deobfuscators.rename.graph.Graph; import org.apache.commons.collections4.map.MultiValueMap; @@ -203,6 +204,8 @@ public class Execution if (!isBuildGraph()) return; + assert frame.getMethod() == frame.nonStatic || frame.nonStatic.isStatic() == false; + if (i instanceof InvokeInstruction) { if (i instanceof InvokeStatic)