total crap

This commit is contained in:
Adam
2015-11-28 23:27:34 -05:00
parent 1f778cfd67
commit a2581e62c1
21 changed files with 482 additions and 104 deletions

View File

@@ -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>

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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)
{

View File

@@ -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())
{

View File

@@ -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);

View File

@@ -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<>();

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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();
}
}

View File

@@ -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()

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -28,7 +28,7 @@ public class Type
private static String asmTypeToClass(String type)
{
switch (type.toString())
switch (type)
{
case "B":
return byte.class.getCanonicalName();

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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);
}
}