I think i need exprs

This commit is contained in:
Adam
2015-11-06 10:33:52 -05:00
parent 8df59fb261
commit 84fa11c8c8
3 changed files with 129 additions and 38 deletions

View File

@@ -1,8 +1,6 @@
package net.runelite.deob;
import net.runelite.deob.deobfuscators.FieldInliner;
import net.runelite.deob.deobfuscators.FieldMover;
import net.runelite.deob.deobfuscators.MethodMover;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
@@ -18,6 +16,7 @@ import java.util.jar.Manifest;
import net.runelite.deob.deobfuscators.ConstantParameter;
import net.runelite.deob.deobfuscators.IllegalStateExceptions;
import net.runelite.deob.deobfuscators.MethodInliner;
import net.runelite.deob.deobfuscators.Rename;
import net.runelite.deob.deobfuscators.RenameUnique;
import net.runelite.deob.deobfuscators.RuntimeExceptions;
import net.runelite.deob.deobfuscators.UnreachedCode;
@@ -35,6 +34,8 @@ public class Deob
{
public static void main(String[] args) throws IOException
{
//merge(); if(true) return;
long start = System.currentTimeMillis();
ClassGroup group = loadJar(args[0]);
@@ -70,9 +71,10 @@ public class Deob
//
// // remove unused methods, again?
// run(group, new UnusedMethods());
//
// run(group, new MethodInliner());
//
run(group, new MethodInliner());
// now remove unused methods?
// // broken because rename was removed
// //run(group, new MethodMover());
//
@@ -83,28 +85,28 @@ public class Deob
// //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)
{
System.out.println("break");
break;
}
last = cur;
//break;
}
//
// 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)
// {
// System.out.println("break");
// break;
// }
//
// last = cur;
// //break;
// }
// eval constant fields (only set once to a constant in ctor) maybe just inline them
@@ -116,6 +118,15 @@ public class Deob
System.out.println("Done in " + ((end - start) / 1000L) + "s");
}
private static void merge() throws IOException
{
ClassGroup group1 = loadJar("d:/rs/07/adamin1.jar"),
group2 = loadJar("d:/rs/07/adamin2.jar");
Rename rename = new Rename();
rename.run(group1, group2);
}
public static boolean isObfuscated(String name)
{
return name.length() <= 2 || name.startsWith("method") || name.startsWith("vmethod") || name.startsWith("field") || name.startsWith("class");

View File

@@ -30,7 +30,7 @@ import net.runelite.deob.attributes.code.Exceptions;
public class MethodInliner implements Deobfuscator
{
private Map<Method, Integer> calls = new HashMap<>();
private Set<Method> removeMethods = new HashSet<>();
//private Set<Method> removeMethods = new HashSet<>();
private void countCalls(Method m)
{
@@ -72,6 +72,7 @@ public class MethodInliner implements Deobfuscator
for (Instruction i : ins.getInstructions())
{
assert i.getInstructions() == ins;
// can only inline static method calls
if (!(i instanceof InvokeStatic))
continue;
@@ -82,14 +83,18 @@ public class MethodInliner implements Deobfuscator
Method invokedMethod = invokedMethods.get(0);
Integer count = calls.get(invokedMethod);
if (count == null || invokedMethod.getCode().getInstructions().getInstructions().size() > 30)
continue;
// if (count == null || count != 1)
// continue; // only inline methods called once
if (count == null || count != 1)
continue; // only inline methods called once
assert m != invokedMethod;
if (m == invokedMethod)
continue; // recursive method
int invokeIdx = ins.getInstructions().indexOf(i);
assert invokeIdx != -1;
assert ins.getInstructions().get(invokeIdx).getInstructions() == ins.getInstructions();
int lvtIndex = code.getMaxLocals(),
//startLvtIndex = lvtIndex,
@@ -178,6 +183,7 @@ public class MethodInliner implements Deobfuscator
invokeMethodInstructions = invokeMethodCode.getInstructions();
int idx = methodInstructions.getInstructions().indexOf(invokeIns); // index of invoke ins, before removal
assert invokeIns.getInstructions() == methodInstructions;
assert idx != -1;
Instruction nextInstruction = methodInstructions.getInstructions().get(idx + 1);
@@ -274,8 +280,8 @@ public class MethodInliner implements Deobfuscator
}
// old method goes away
invokeMethodInstructions.getInstructions().clear();
removeMethods.add(invokeMethod);
//invokeMethodInstructions.getInstructions().clear();
//removeMethods.add(invokeMethod);
}
private void moveExceptions(Method to, Method from)
@@ -312,7 +318,7 @@ public class MethodInliner implements Deobfuscator
int count = 0;
calls.clear();
removeMethods.clear();
//removeMethods.clear();
for (ClassFile cf : group.getClasses())
{
@@ -329,9 +335,9 @@ public class MethodInliner implements Deobfuscator
count += processMethod(m);
}
}
for (Method m : removeMethods)
m.getMethods().removeMethod(m);
//
// for (Method m : removeMethods)
// m.getMethods().removeMethod(m);
System.out.println("Inlined " + count + " methods");
return count;

View File

@@ -0,0 +1,74 @@
package net.runelite.deob.deobfuscators;
import java.util.List;
import java.util.stream.Collectors;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.attributes.code.Instruction;
import net.runelite.deob.attributes.code.instruction.types.ComparisonInstruction;
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
import net.runelite.deob.attributes.code.instruction.types.LVTInstruction;
import net.runelite.deob.attributes.code.instruction.types.SetFieldInstruction;
import net.runelite.deob.execution.Execution;
import net.runelite.deob.execution.Frame;
public class Rename
{
private static boolean isExpressionInstruction(Instruction in)
{
return
in instanceof SetFieldInstruction ||
(in instanceof LVTInstruction && ((LVTInstruction) in).store()) ||
in instanceof InvokeInstruction ||
in instanceof ComparisonInstruction;
}
private static List<Instruction> getExprIns(Frame frame)
{
return frame.getInstructions().stream().map(i -> i.getInstruction()).filter(i -> isExpressionInstruction(i)).collect(Collectors.toList());
}
private static boolean equalsFrames(Frame one, Frame two)
{
List<Instruction> oneIns = getExprIns(one),
twoIns = getExprIns(two);
if (oneIns.size() != twoIns.size() || oneIns.isEmpty())
return false;
for (int i = 0; i < oneIns.size(); ++i)
{
Instruction i1 = oneIns.get(i),
i2 = twoIns.get(i);
if (i1.getType() != i2.getType())
return false;
}
if (one.getMethod().getName().startsWith("method") && two.getMethod().getName().startsWith("method"))
{
int i =5;
}
return true;
}
public void run(ClassGroup one, ClassGroup two)
{
Execution ex1 = new Execution(one);
ex1.populateInitialMethods();
ex1.run();
Execution ex2 = new Execution(two);
ex2.populateInitialMethods();
ex2.run();
for (Frame f : ex1.processedFrames)
for (Frame f2 : ex2.processedFrames)
{
if (f.getMethod().getName().equals("vmethod2976") && f2.getMethod().getName().equals("vmethod2973"))
{
if (equalsFrames(f, f2))
System.out.println(f.getMethod().getName() + " " + f2.getMethod().getName());
}
}
}
}