total crap
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -2,7 +2,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>deob</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class ModArith implements Deobfuscator
|
||||
private List<Pair> pairs = new ArrayList<>();
|
||||
private Encryption encryption = new Encryption();
|
||||
|
||||
private List<InstructionContext> getInsInExpr(InstructionContext ctx, Set<Instruction> set)
|
||||
private static List<InstructionContext> getInsInExpr(InstructionContext ctx, Set<Instruction> set)
|
||||
{
|
||||
List<InstructionContext> l = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -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<Frame> 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<Vertex> 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<Vertex> 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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<Vertex> getVerticies()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<Vertex> mightBe;
|
||||
private Vertex is;
|
||||
|
||||
private Set<Instruction> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<InstructionContext> getInsInExpr(InstructionContext ctx, Set<Instruction> set)
|
||||
{
|
||||
List<InstructionContext> 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;
|
||||
|
||||
@@ -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<InstructionContext> 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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public class Type
|
||||
|
||||
private static String asmTypeToClass(String type)
|
||||
{
|
||||
switch (type.toString())
|
||||
switch (type)
|
||||
{
|
||||
case "B":
|
||||
return byte.class.getCanonicalName();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Instruction> getInstructionsInMethodInclStatic(Method method, Set<Method> visited)
|
||||
{
|
||||
List<Instruction> 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<Method> 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<SetFieldInstruction> l1 = (List<SetFieldInstruction>) getInstructionsInMethodInclStatic(m1, new HashSet()).stream().filter(i -> i instanceof SetFieldInstruction).collect(Collectors.toList()),
|
||||
// l2 = (List<SetFieldInstruction>) getInstructionsInMethodInclStatic(m2, new HashSet()).stream().filter(i -> i instanceof SetFieldInstruction).collect(Collectors.toList());
|
||||
//
|
||||
//
|
||||
// List<Field> 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<Frame> 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user