diff --git a/pom.xml b/pom.xml
index dd910da92e..295625ff7f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
4.0.0
net.runelite
deob
- 0.0.1-SNAPSHOT
+ 1.0-SNAPSHOT
org.apache.commons
diff --git a/src/main/java/net/runelite/deob/Deob.java b/src/main/java/net/runelite/deob/Deob.java
index 5a967aec2c..c5e17f20b5 100644
--- a/src/main/java/net/runelite/deob/Deob.java
+++ b/src/main/java/net/runelite/deob/Deob.java
@@ -31,67 +31,67 @@ public class Deob
ClassGroup group = JarUtil.loadJar(new File(args[0]));
-// run(group, new RenameUnique());
-//
-// // remove except RuntimeException
-// run(group, new RuntimeExceptions());
-//
-// // remove unused methods
-// run(group, new UnreachedCode());
-// run(group, new UnusedMethods());
-//
-// // remove illegal state exceptions, frees up some parameters
-// run(group, new IllegalStateExceptions());
-//
-// // remove constant logically dead parameters
-// run(group, new ConstantParameter());
-//
-// // remove unhit blocks
-// run(group, new UnreachedCode());
-// run(group, new UnusedMethods());
-//
-// // remove unused parameters
-// run(group, new UnusedParameters());
-//
-// // remove unused fields
-// run(group, new UnusedFields());
-//
-// // remove unused methods, again?
-// run(group, new UnusedMethods());
-//
-//// run(group, new MethodInliner());
-//// run(group, new UnusedMethods()); // inliner might leave unused methods
-//
-//// // broken because rename was removed
-//// //run(group, new MethodMover());
-//
-// run(group, new FieldInliner());
-//
-//// // XXX this is broken because when moving clinit around, some fields can depend on other fields
-//// // (like multianewarray)
-//// //new FieldMover().run(group);
-//
-// run(group, new UnusedClass());
+ run(group, new RenameUnique());
+
+ // remove except RuntimeException
+ run(group, new RuntimeExceptions());
+
+ // remove unused methods
+ run(group, new UnreachedCode());
+ run(group, new UnusedMethods());
+
+ // remove illegal state exceptions, frees up some parameters
+ run(group, new IllegalStateExceptions());
+
+ // remove constant logically dead parameters
+ run(group, new ConstantParameter());
+
+ // remove unhit blocks
+ run(group, new UnreachedCode());
+ run(group, new UnusedMethods());
+
+ // remove unused parameters
+ run(group, new UnusedParameters());
+
+ // remove unused fields
+ run(group, new UnusedFields());
+
+ // remove unused methods, again?
+ run(group, new UnusedMethods());
+
+// run(group, new MethodInliner());
+// run(group, new UnusedMethods()); // inliner might leave unused methods
+
+// // broken because rename was removed
+// //run(group, new MethodMover());
+
+ run(group, new FieldInliner());
+
+// // XXX this is broken because when moving clinit around, some fields can depend on other fields
+// // (like multianewarray)
+// //new FieldMover().run(group);
+
+ run(group, new UnusedClass());
-// ModArith mod = new ModArith();
-// mod.run(group);
-//
-// int last = -1, cur;
-// while ((cur = mod.runOnce()) > 0)
-// {
-// new MultiplicationDeobfuscator().run(group);
-//
-// new MultiplyOneDeobfuscator().run(group);
-//
-// new MultiplyZeroDeobfuscator().run(group);
-//
-// if (last == cur)
-// break;
-//
-// last = cur;
-// }
-//
-// mod.annotateEncryption();
+ ModArith mod = new ModArith();
+ mod.run(group);
+
+ int last = -1, cur;
+ while ((cur = mod.runOnce()) > 0)
+ {
+ new MultiplicationDeobfuscator().run(group);
+
+ new MultiplyOneDeobfuscator().run(group);
+
+ new MultiplyZeroDeobfuscator().run(group);
+
+ if (last == cur)
+ break;
+
+ last = cur;
+ }
+
+ mod.annotateEncryption();
// eval constant fields (only set once to a constant in ctor) maybe just inline them
@@ -105,8 +105,8 @@ public class Deob
private static void merge() throws IOException
{
- ClassGroup group1 = JarUtil.loadJar(new File("/Users/adam/w/rs/07/adamin1.jar")),
- group2 = JarUtil.loadJar(new File("/Users/adam/w/rs/07/adamin2.jar"));
+ ClassGroup group1 = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar")),
+ group2 = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));
Rename2 rename = new Rename2();
rename.run(group1, group2);
diff --git a/src/main/java/net/runelite/deob/Field.java b/src/main/java/net/runelite/deob/Field.java
index 910d10aeb7..4d0fdfef72 100644
--- a/src/main/java/net/runelite/deob/Field.java
+++ b/src/main/java/net/runelite/deob/Field.java
@@ -54,7 +54,7 @@ public class Field
out.writeShort(accessFlags);
out.writeShort(pool.makeUTF8(name));
- out.writeShort(pool.makeUTF8(type.toString()));
+ out.writeShort(pool.makeUTF8(type.getFullType()));
attributes.write(out);
}
diff --git a/src/main/java/net/runelite/deob/attributes/annotation/Annotation.java b/src/main/java/net/runelite/deob/attributes/annotation/Annotation.java
index bf44f27d01..dcd6b51859 100644
--- a/src/main/java/net/runelite/deob/attributes/annotation/Annotation.java
+++ b/src/main/java/net/runelite/deob/attributes/annotation/Annotation.java
@@ -65,7 +65,7 @@ public class Annotation
{
ConstantPool pool = annotations.getAttributes().getClassFile().getPool();
- out.writeShort(pool.makeUTF8(type.toString()));
+ out.writeShort(pool.makeUTF8(type.getFullType()));
out.writeShort(elements.size());
for (Element e : elements)
{
diff --git a/src/main/java/net/runelite/deob/attributes/annotation/Element.java b/src/main/java/net/runelite/deob/attributes/annotation/Element.java
index 94da9891a2..c644994534 100644
--- a/src/main/java/net/runelite/deob/attributes/annotation/Element.java
+++ b/src/main/java/net/runelite/deob/attributes/annotation/Element.java
@@ -64,7 +64,7 @@ public class Element
{
ConstantPool pool = annotation.getAnnotations().getAttributes().getClassFile().getPool();
- out.writeShort(pool.makeUTF8(type.toString()));
+ out.writeShort(pool.makeUTF8(type.getFullType()));
byte type;
switch (value.getType())
{
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java
index 629e737e7d..84346341da 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java
@@ -95,7 +95,16 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
// add possible method call to execution
Execution execution = frame.getExecution();
- execution.invoke(ins, method);
+ Frame f = execution.invoke(ins, method);
+
+ if (f != null)
+ {
+ assert f.getMethod() == method;
+ //assert f.lastField == frame.lastField;
+ //assert f.staticReturn == frame;
+
+ //frame.stop();
+ }
}
frame.addInstructionContext(ins);
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 9c1790c2f5..2dd5822ca3 100644
--- a/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java
+++ b/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java
@@ -42,7 +42,7 @@ public class ModArith implements Deobfuscator
private List pairs = new ArrayList<>();
private Encryption encryption = new Encryption();
- private List getInsInExpr(InstructionContext ctx, Set set)
+ private static List getInsInExpr(InstructionContext ctx, Set set)
{
List l = new ArrayList<>();
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 c4bc56131e..b561a2ee1c 100644
--- a/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java
+++ b/src/main/java/net/runelite/deob/deobfuscators/rename/Rename2.java
@@ -25,6 +25,8 @@ import net.runelite.deob.attributes.annotation.Annotation;
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.Vertex;
import net.runelite.deob.deobfuscators.rename.graph.VertexType;
@@ -193,6 +195,47 @@ public class Rename2
return fields;
}
+ private void mapOneFrame(ClassGroup group, Execution e)
+ {
+ for (ClassFile cf : group.getClasses())
+ {
+ for (Method m : cf.getMethods().getMethods())
+ {
+ if (m.isStatic())
+ continue;
+
+ List frames = e.processedFrames.stream().filter(f -> f.getMethod() == m).collect(Collectors.toList());
+
+ if (frames.size() != 1)
+ continue;
+
+ int count = 0;
+ for (InstructionContext i : frames.get(0).getInstructions())
+ {
+ if (i.getInstruction() instanceof SetFieldInstruction)
+ {
+ SetFieldInstruction sfi = (SetFieldInstruction) i.getInstruction();
+
+ Field f = sfi.getMyField();
+ if (f == null)
+ continue;
+
+ Vertex methodVertex = e.getGraph().getVertexFor(m),
+ fieldVertex = e.getGraph().getVertexFor(f);
+
+ Edge edge = new FieldEdge(i.getInstruction(), methodVertex, fieldVertex, EdgeType.SETFIELD, count);
+ e.getGraph().addEdge(edge);
+
+ edge = new FieldEdge(i.getInstruction(), fieldVertex, methodVertex, EdgeType.SETFIELD_FROM, count);
+ e.getGraph().addEdge(edge);
+
+ ++count;
+ }
+ }
+ }
+ }
+ }
+
private void solve()
{
List solved = g1.getVerticies().stream().filter(v -> v.getOther() != null).collect(Collectors.toList());
@@ -231,14 +274,14 @@ public class Rename2
if (e2.getTo().getOther() != null)
continue; // skip solved edges
- if (b2)
- {
- Method m = (Method) e2.getTo().getObject();
- if (m.getName().equals("method2489"))
- {
- b2 = true;
- }
- }
+// if (b2)
+// {
+// Method m = (Method) e2.getTo().getObject();
+// if (m.getName().equals("method2489"))
+// {
+// b2 = true;
+// }
+// }
if (!e.getTo().couldBeEqual(e2.getTo()))
{
@@ -320,6 +363,9 @@ public class Rename2
System.out.println(fname(f1) + " is " + fname(f2));
}
+// mapOneFrame(one, eone);
+// mapOneFrame(two, etwo);
+
System.out.println("g1 verticies " + g1.getVerticies().size() + " reachable " + g1.reachableVerticiesFromSolvedVerticies().size());
Set reachable = g1.reachableVerticiesFromSolvedVerticies();
for (Vertex v : g1.getVerticies())
@@ -384,7 +430,7 @@ public class Rename2
try
{
- JarUtil.saveJar(two, new File("/Users/adam/w/rs/07/adamout.jar"));
+ JarUtil.saveJar(two, new File("d:/rs/07/adamout.jar"));
}
catch (IOException ex)
{
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 611e5cf8f3..9644b96302 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
@@ -1,15 +1,18 @@
package net.runelite.deob.deobfuscators.rename.graph;
import java.util.Objects;
+import net.runelite.deob.attributes.code.Instruction;
public class Edge
{
+ private final Instruction ins; // craetor
private final Vertex from, to;
private final EdgeType type;
private int weight;
- public Edge(Vertex from, Vertex to, EdgeType type)
+ public Edge(Instruction ins, Vertex from, Vertex to, EdgeType type)
{
+ this.ins = ins;
this.from = from;
this.to = to;
this.type = type;
@@ -17,6 +20,11 @@ public class Edge
assert from.getGraph() == to.getGraph();
}
+ public Instruction getIns()
+ {
+ return ins;
+ }
+
public Vertex getFrom()
{
return from;
@@ -94,8 +102,8 @@ public class Edge
if (this.type != other.type)
return false;
- //if (this.weight != other.weight)
- // return false;
+// if (this.weight != other.weight)
+// return false;
return true;
}
diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/EdgeType.java b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/EdgeType.java
index 9651842c6c..fc4180da2b 100644
--- a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/EdgeType.java
+++ b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/EdgeType.java
@@ -8,5 +8,17 @@ public enum EdgeType
INVOKED_FROM,
GETFIELD_FROM,
- SETFIELD_FROM;
+ SETFIELD_FROM,
+
+ FIELD_ASSOCIATION,
+ FIELD_ASSOCIATION_FROM,
+
+ METHOD_ASSOCIATION,
+ METHOD_ASSOCIATION_FROM,
+
+ PREV_FIELD,
+ PREV_FIELD_FROM,
+
+ FIELD_ASSIGNMENT_FIELD,
+ FIELD_ASSIGNMENT_FIELD_FROM;
}
diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/FieldEdge.java b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/FieldEdge.java
new file mode 100644
index 0000000000..33f0ffeff8
--- /dev/null
+++ b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/FieldEdge.java
@@ -0,0 +1,39 @@
+package net.runelite.deob.deobfuscators.rename.graph;
+
+import net.runelite.deob.attributes.code.Instruction;
+
+public class FieldEdge extends Edge
+{
+ private int id;
+
+ public FieldEdge(Instruction ins, Vertex from, Vertex to, EdgeType type, int id)
+ {
+ super(ins, from, to, type);
+ this.id = id;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (!super.equals(obj))
+ {
+ return false;
+ }
+ final FieldEdge other = (FieldEdge) obj;
+ if (this.id != other.id)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 5;
+ hash = 89 * hash + this.id;
+ return hash ^ super.hashCode();
+ }
+
+
+}
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 872eb8839c..74311df267 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
@@ -46,15 +46,9 @@ public class Graph
return v;
}
- public void addEdge(Object from, Object to, EdgeType type)
+ public void addEdge(Edge e)
{
- assert from != null;
- assert to != null;
-
- Vertex v1 = getVertexFor(from), v2 = getVertexFor(to);
-
- Edge e = new Edge(v1, v2, type);
- v1.addEdge(e);
+ e.getFrom().addEdge(e);
}
public List getVerticies()
diff --git a/src/main/java/net/runelite/deob/deobfuscators/rename/graph/MethodEdge.java b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/MethodEdge.java
new file mode 100644
index 0000000000..036ec421c8
--- /dev/null
+++ b/src/main/java/net/runelite/deob/deobfuscators/rename/graph/MethodEdge.java
@@ -0,0 +1,53 @@
+package net.runelite.deob.deobfuscators.rename.graph;
+
+import java.util.Objects;
+import net.runelite.deob.Method;
+import net.runelite.deob.attributes.code.Instruction;
+
+public class MethodEdge extends Edge
+{
+ private final Method method;
+
+ public MethodEdge(Instruction i, Vertex from, Vertex to, EdgeType type, Method method)
+ {
+ super(i, from, to, type);
+ this.method = method;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int hash = 7;
+ hash = 61 * hash + Objects.hashCode(this.method);
+ return hash ^ super.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (!super.equals(obj))
+ {
+ return false;
+ }
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj == null)
+ {
+ return false;
+ }
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+ final MethodEdge other = (MethodEdge) obj;
+ if (!Objects.equals(this.method, other.method))
+ {
+ return false;
+ }
+ return true;
+ }
+
+
+}
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 4169978271..14807d9330 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
@@ -16,6 +16,7 @@ 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.InvokeInstruction;
+import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction;
import net.runelite.deob.attributes.code.instructions.InvokeStatic;
import net.runelite.deob.deobfuscators.rename.InstructionList;
import net.runelite.deob.deobfuscators.rename.Rename2;
@@ -34,6 +35,8 @@ public class Vertex
private Collection mightBe;
private Vertex is;
+
+ private Set edgeFrom = new HashSet<>();
public Vertex(Graph graph, Object object)
{
@@ -107,7 +110,11 @@ public class Vertex
Edge c = edges.get(edge);
if (c != null)
{
- c.increase();
+ if (edge.getIns() instanceof SetFieldInstruction && !edgeFrom.contains(edge.getIns()))
+ {
+ edgeFrom.add(edge.getIns());
+ c.increase();
+ }
return;
}
diff --git a/src/main/java/net/runelite/deob/execution/Execution.java b/src/main/java/net/runelite/deob/execution/Execution.java
index 35eff6776d..d0d6571642 100644
--- a/src/main/java/net/runelite/deob/execution/Execution.java
+++ b/src/main/java/net/runelite/deob/execution/Execution.java
@@ -18,9 +18,13 @@ import net.runelite.deob.Field;
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.instruction.types.SetFieldInstruction;
import net.runelite.deob.attributes.code.instructions.InvokeStatic;
+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.MethodEdge;
import net.runelite.deob.deobfuscators.rename.graph.VertexType;
import org.apache.commons.collections4.map.MultiValueMap;
@@ -100,14 +104,15 @@ public class Execution
frames.add(frame);
}
- public void invoke(InstructionContext from, Method to)
+ public Frame invoke(InstructionContext from, Method to)
{
if (hasInvoked(from, to))
- return;
+ return null;
Frame f = new Frame(this, to);
f.initialize(from);
this.addFrame(f);
+ return f;
}
public void addMethod(Method to)
@@ -132,7 +137,9 @@ public class Execution
frame.execute();
assert frames.get(0) == frame;
- frames.remove(0);
+ assert !frame.isExecuting();
+
+ frames.remove(frame);
processedFrames.add(frame);
}
@@ -189,12 +196,13 @@ public class Execution
}
}
- protected void buildGraph(Frame frame, Instruction i)
+ protected void buildGraph(Frame frame, Instruction i, InstructionContext ctx)
{
if (!isBuildGraph())
return;
assert frame.getMethod() == frame.nonStatic || frame.nonStatic.isStatic() == false;
+ assert ctx.getInstruction() == i;
if (i instanceof InvokeInstruction)
{
@@ -209,8 +217,8 @@ public class Execution
for (Method m : methods)
{
- graph.addEdge(frame.nonStatic, m, EdgeType.INVOKE);
- graph.addEdge(m, frame.nonStatic, EdgeType.INVOKED_FROM);
+ graph.addEdge(new Edge(i, graph.getVertexFor(frame.nonStatic), graph.getVertexFor(m), EdgeType.INVOKE));
+ graph.addEdge(new Edge(i, graph.getVertexFor(m), graph.getVertexFor(frame.nonStatic), EdgeType.INVOKED_FROM));
}
}
else if (i instanceof FieldInstruction)
@@ -220,13 +228,87 @@ public class Execution
if (fi.getMyField() == null)
return;
+ //int id = frame.getMethodCtx().fcount++;
EdgeType type = fi instanceof GetFieldInstruction ? EdgeType.GETFIELD : EdgeType.SETFIELD;
- graph.addEdge(frame.nonStatic, fi.getMyField(), type);
+ graph.addEdge(new Edge(i, graph.getVertexFor(frame.nonStatic), graph.getVertexFor(fi.getMyField()), type));
EdgeType typeRev = fi instanceof GetFieldInstruction ? EdgeType.GETFIELD_FROM : EdgeType.SETFIELD_FROM;
- graph.addEdge(fi.getMyField(), frame.nonStatic, typeRev);
+ graph.addEdge(new Edge(i, graph.getVertexFor(fi.getMyField()), graph.getVertexFor(frame.nonStatic), typeRev));
+
+ if (fi instanceof SetFieldInstruction && frame.lastField != null)
+ {
+ graph.addEdge(new MethodEdge(i, graph.getVertexFor(fi.getMyField()), graph.getVertexFor(frame.lastField), EdgeType.PREV_FIELD, frame.nonStatic));
+ graph.addEdge(new MethodEdge(i, graph.getVertexFor(frame.lastField), graph.getVertexFor(fi.getMyField()), EdgeType.PREV_FIELD_FROM, frame.nonStatic));
+ }
+
+// if (fi instanceof SetFieldInstruction)
+// {
+// StackContext sctx = ctx.getPops().get(0);
+// if (sctx.getPushed().getInstruction() instanceof GetFieldInstruction)
+// {
+// GetFieldInstruction gfi = (GetFieldInstruction) sctx.getPushed().getInstruction();
+//
+// if (gfi.getMyField() != null)
+// {
+// // XXX dup edges
+// graph.addEdge(new MethodEdge(i, graph.getVertexFor(fi.getMyField()), graph.getVertexFor(gfi.getMyField()), EdgeType.FIELD_ASSIGNMENT_FIELD, frame.nonStatic));
+// graph.addEdge(new MethodEdge(i, graph.getVertexFor(gfi.getMyField()), graph.getVertexFor(fi.getMyField()), EdgeType.FIELD_ASSIGNMENT_FIELD_FROM, frame.nonStatic));
+// }
+// }
+// }
+
+ // associated fields
+ for (InstructionContext ic : getInsInExpr(ctx, new HashSet<>()))
+ {
+ Instruction i2 = (Instruction) ic.getInstruction();
+
+ if (i2 instanceof FieldInstruction)
+ {
+ FieldInstruction fi2 = (FieldInstruction) i2;
+
+ if (fi2.getMyField() == null)
+ continue;
+
+ // these are within the context of a method
+ graph.addEdge(new MethodEdge(i2, graph.getVertexFor(fi.getMyField()), graph.getVertexFor(fi2.getMyField()), EdgeType.FIELD_ASSOCIATION, frame.nonStatic));
+ graph.addEdge(new MethodEdge(i2, graph.getVertexFor(fi2.getMyField()), graph.getVertexFor(fi.getMyField()), EdgeType.FIELD_ASSOCIATION_FROM, frame.nonStatic));
+ }
+ else if (i2 instanceof InvokeInstruction)
+ {
+ InvokeInstruction ii2 = (InvokeInstruction) i2;
+
+ if (ii2 instanceof InvokeStatic)
+ continue;
+
+ for (Method m : ii2.getMethods())
+ {
+ graph.addEdge(new MethodEdge(i2, graph.getVertexFor(fi.getMyField()), graph.getVertexFor(m), EdgeType.METHOD_ASSOCIATION, frame.nonStatic));
+ graph.addEdge(new MethodEdge(i2, graph.getVertexFor(m), graph.getVertexFor(fi.getMyField()), EdgeType.METHOD_ASSOCIATION_FROM, frame.nonStatic));
+ }
+ }
+ }
}
}
+ private static List getInsInExpr(InstructionContext ctx, Set set)
+ {
+ List l = new ArrayList<>();
+
+ if (ctx == null || set.contains(ctx.getInstruction()))
+ return l;
+
+ set.add(ctx.getInstruction());
+
+ l.add(ctx);
+
+ for (StackContext s : ctx.getPops())
+ l.addAll(getInsInExpr(s.getPushed(), set));
+ for (StackContext s : ctx.getPushes())
+ for (InstructionContext i : s.getPopped())
+ l.addAll(getInsInExpr(i, set));
+
+ return l;
+ }
+
public Graph getGraph()
{
return graph;
diff --git a/src/main/java/net/runelite/deob/execution/Frame.java b/src/main/java/net/runelite/deob/execution/Frame.java
index d00a01e391..9e20bc0b8d 100644
--- a/src/main/java/net/runelite/deob/execution/Frame.java
+++ b/src/main/java/net/runelite/deob/execution/Frame.java
@@ -3,6 +3,7 @@ package net.runelite.deob.execution;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
+import net.runelite.deob.Field;
import net.runelite.deob.Method;
import net.runelite.deob.attributes.Code;
import net.runelite.deob.attributes.code.Exception;
@@ -11,6 +12,9 @@ import net.runelite.deob.attributes.code.Instructions;
import net.runelite.deob.pool.NameAndType;
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
import net.runelite.deob.attributes.code.instruction.types.ReturnInstruction;
+import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction;
+import net.runelite.deob.attributes.code.instructions.AThrow;
+import net.runelite.deob.attributes.code.instructions.InvokeStatic;
public class Frame
{
@@ -23,6 +27,8 @@ public class Frame
private List instructions = new ArrayList<>(); // instructions executed in this frame
private MethodContext ctx;
protected Method nonStatic; // next non static method up the stack
+ public Field lastField;
+ public Frame staticReturn;
public Frame(Execution execution, Method method)
{
@@ -63,6 +69,9 @@ public class Frame
if (this.getMethod().isStatic())
{
this.nonStatic = ctx.getFrame().nonStatic;
+// this.lastField = ctx.getFrame().lastField;
+// this.staticReturn = ctx.getFrame();
+ //this.ctx = ctx.getFrame().ctx;
}
// initialize LVT. the last argument is popped first, and is at arguments[0]
@@ -99,6 +108,8 @@ public class Frame
this.variables = new Variables(other.variables);
this.ctx = other.ctx;
this.nonStatic = other.nonStatic;
+ this.lastField = other.lastField;
+ this.staticReturn = other.staticReturn;
}
public Frame dup()
@@ -167,6 +178,21 @@ public class Frame
{
Instruction oldCur = cur;
+ if ((cur instanceof ReturnInstruction || cur instanceof AThrow) && this.staticReturn != null)
+ {
+ Frame newFrame = this.staticReturn.dup();
+ newFrame.lastField = this.lastField;
+ newFrame.executing = true;
+
+ assert newFrame.cur instanceof InvokeStatic;
+ int i = newFrame.method.getCode().getInstructions().getInstructions().indexOf(newFrame.cur);
+ assert i != -1;
+ newFrame.cur = newFrame.method.getCode().getInstructions().getInstructions().get(i + 1);
+
+ assert execution.frames.contains(newFrame);
+ //this.execution.frames.add(newFrame);
+ }
+
try
{
cur.execute(this);
@@ -199,7 +225,13 @@ public class Frame
if (!executing)
break;
- execution.buildGraph(this, oldCur);
+ execution.buildGraph(this, oldCur, ictx);
+ if (oldCur instanceof SetFieldInstruction)
+ {
+ SetFieldInstruction sfi = (SetFieldInstruction) oldCur;
+ if (sfi.getMyField() != null)
+ this.lastField = sfi.getMyField();
+ }
if (oldCur == cur)
{
diff --git a/src/main/java/net/runelite/deob/execution/MethodContext.java b/src/main/java/net/runelite/deob/execution/MethodContext.java
index 99dbe328fe..fa97ec80d3 100644
--- a/src/main/java/net/runelite/deob/execution/MethodContext.java
+++ b/src/main/java/net/runelite/deob/execution/MethodContext.java
@@ -1,6 +1,7 @@
package net.runelite.deob.execution;
import java.util.Collection;
+import net.runelite.deob.Field;
import net.runelite.deob.attributes.code.Instruction;
import org.apache.commons.collections4.map.MultiValueMap;
diff --git a/src/main/java/net/runelite/deob/execution/Type.java b/src/main/java/net/runelite/deob/execution/Type.java
index e21cfb5e63..29e376c23e 100644
--- a/src/main/java/net/runelite/deob/execution/Type.java
+++ b/src/main/java/net/runelite/deob/execution/Type.java
@@ -28,7 +28,7 @@ public class Type
private static String asmTypeToClass(String type)
{
- switch (type.toString())
+ switch (type)
{
case "B":
return byte.class.getCanonicalName();
diff --git a/src/main/java/net/runelite/deob/pool/NameAndType.java b/src/main/java/net/runelite/deob/pool/NameAndType.java
index 58a7b12d3f..75a7ed6661 100644
--- a/src/main/java/net/runelite/deob/pool/NameAndType.java
+++ b/src/main/java/net/runelite/deob/pool/NameAndType.java
@@ -61,7 +61,7 @@ public class NameAndType extends PoolEntry
if (signature != null)
descriptorIndex = pool.makeUTF8(signature.toString());
else
- descriptorIndex = pool.makeUTF8(type.toString());
+ descriptorIndex = pool.makeUTF8(type.getFullType());
}
@Override
@@ -97,7 +97,7 @@ public class NameAndType extends PoolEntry
public Object getStackObject()
{
- switch (type.toString())
+ switch (type.getFullType())
{
case "B":
return (byte) 0;
diff --git a/src/main/java/net/runelite/deob/signature/Signature.java b/src/main/java/net/runelite/deob/signature/Signature.java
index a04943fac6..8b9ce7fec5 100644
--- a/src/main/java/net/runelite/deob/signature/Signature.java
+++ b/src/main/java/net/runelite/deob/signature/Signature.java
@@ -64,9 +64,9 @@ public class Signature
StringBuffer sb = new StringBuffer();
sb.append('(');
for (Type a : arguments)
- sb.append(a.toString());
+ sb.append(a.getFullType());
sb.append(')');
- sb.append(rv.toString());
+ sb.append(rv.getFullType());
return sb.toString();
}
diff --git a/src/test/java/net/runelite/deob/deobfuscators/rename/Rename.java b/src/test/java/net/runelite/deob/deobfuscators/rename/Rename.java
new file mode 100644
index 0000000000..05af1da2cf
--- /dev/null
+++ b/src/test/java/net/runelite/deob/deobfuscators/rename/Rename.java
@@ -0,0 +1,95 @@
+package net.runelite.deob.deobfuscators.rename;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+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.InvokeInstruction;
+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.util.JarUtil;
+import org.junit.Test;
+
+public class Rename
+{
+ private List getInstructionsInMethodInclStatic(Method method, Set visited)
+ {
+ List ilist = new ArrayList<>();
+
+ if (visited.contains(method))
+ return ilist;
+ visited.add(method);
+
+ Code code = method.getCode();
+ if (code == null)
+ return ilist;
+
+ for (Instruction i : code.getInstructions().getInstructions())
+ {
+ if (i instanceof InvokeStatic)
+ {
+ InvokeInstruction ii = (InvokeInstruction) i;
+ List methods = ii.getMethods();
+
+ if (methods.isEmpty())
+ continue;
+
+ Method m = methods.get(0);
+ ilist.addAll(this.getInstructionsInMethodInclStatic(m, visited));
+ }
+ else
+ {
+ ilist.add(i);
+ }
+ }
+
+ return ilist;
+ }
+
+ @Test
+ public void test() throws IOException
+ {
+ ClassGroup one = JarUtil.loadJar(new File("d:/rs/07/adamin1.jar")), two = JarUtil.loadJar(new File("d:/rs/07/adamin2.jar"));
+
+ Execution eone = new Execution(one);
+ eone.setBuildGraph(true);
+ eone.populateInitialMethods();
+ eone.run();
+
+ Execution etwo = new Execution(two);
+ etwo.setBuildGraph(true);
+ etwo.populateInitialMethods();
+ etwo.run();
+
+// Method m1 = one.findClass("client").findMethod("vmethod3096"), m2 = two.findClass("client").findMethod("vmethod2975");
+//
+// List l1 = (List) getInstructionsInMethodInclStatic(m1, new HashSet()).stream().filter(i -> i instanceof SetFieldInstruction).collect(Collectors.toList()),
+// l2 = (List) getInstructionsInMethodInclStatic(m2, new HashSet()).stream().filter(i -> i instanceof SetFieldInstruction).collect(Collectors.toList());
+//
+//
+// List lf1 =(List) l1.stream().filter(i -> i.getMyField() != null).map(i -> i.getMyField()).distinct().collect(Collectors.toList()),
+// lf2 = l2.stream().filter(i -> i.getMyField() != null).map(i -> i.getMyField()).distinct().collect(Collectors.toList());
+//
+// for (int i = 0; i< 100; ++i)
+// {
+// Field f1 = lf1.get(i), f2 = lf2.get(i);
+//
+// System.out.println(f1 + " <-> " + f2);
+// }
+ // number of setfields
+ //List f1 = eone.processedFrames.stream().filter(f -> f.getMethod() == m1).collect(Collectors.toList()),
+ // f2 = etwo.processedFrames.stream().filter(f -> f.getMethod() == m2).collect(Collectors.toList());
+
+ //System.out.println(ll1);
+ }
+}