Fix not removing ctors, unused class deob. Can't yet move static fields to client until I can move clinit

This commit is contained in:
Adam
2015-08-16 19:08:22 -04:00
parent 4f11ca9f36
commit 5059f8cc75
6 changed files with 157 additions and 69 deletions

View File

@@ -20,6 +20,11 @@ public class ClassGroup
return cf;
}
public void removeClass(ClassFile cf)
{
classes.remove(cf);
}
public List<ClassFile> getClasses()
{
return classes;

View File

@@ -15,6 +15,15 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
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.RuntimeExceptions;
import net.runelite.deob.deobfuscators.UnreachedCode;
import net.runelite.deob.deobfuscators.UnusedClass;
import net.runelite.deob.deobfuscators.UnusedFields;
import net.runelite.deob.deobfuscators.UnusedMethods;
import net.runelite.deob.deobfuscators.UnusedParameters;
//move static methods
//move static fields
@@ -37,70 +46,72 @@ public class Deob
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("rename unique took " + bdur/1000L + " seconds");
// // remove except RuntimeException
// bstart = System.currentTimeMillis();
// new RuntimeExceptions().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("runtime exception took " + bdur/1000L + " seconds");
//
// // remove unused methods
// bstart = System.currentTimeMillis();
// new UnusedMethods().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("unused methods took " + bdur/1000L + " seconds");
//
// new UnreachedCode().run(group);
//
// // remove illegal state exceptions, frees up some parameters
// bstart = System.currentTimeMillis();
// new IllegalStateExceptions().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("illegal state exception took " + bdur/1000L + " seconds");
//
// // remove constant logically dead parameters
// bstart = System.currentTimeMillis();
// new ConstantParameter().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("constant param took " + bdur/1000L + " seconds");
//
// // remove unhit blocks
// bstart = System.currentTimeMillis();
// new UnreachedCode().run(group);
// //new UnusedBlocks().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("unused blocks took " + bdur/1000L + " seconds");
//
// // remove unused parameters
// bstart = System.currentTimeMillis();
// new UnusedParameters().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("unused params took " + bdur/1000L + " seconds");
//
// // remove jump obfuscation
// //new Jumps().run(group);
//
// // remove unused fields
// bstart = System.currentTimeMillis();
// new UnusedFields().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("unused fields took " + bdur/1000L + " seconds");
//
// // remove unused methods, again?
// bstart = System.currentTimeMillis();
// new UnusedMethods().run(group);
// bdur = System.currentTimeMillis() - bstart;
// System.out.println("unused methods took " + bdur/1000L + " seconds");
//
//
// new MethodInliner().run(group);
// remove except RuntimeException
bstart = System.currentTimeMillis();
new RuntimeExceptions().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("runtime exception took " + bdur/1000L + " seconds");
// remove unused methods
bstart = System.currentTimeMillis();
new UnusedMethods().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("unused methods took " + bdur/1000L + " seconds");
new UnreachedCode().run(group);
// remove illegal state exceptions, frees up some parameters
bstart = System.currentTimeMillis();
new IllegalStateExceptions().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("illegal state exception took " + bdur/1000L + " seconds");
// remove constant logically dead parameters
bstart = System.currentTimeMillis();
new ConstantParameter().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("constant param took " + bdur/1000L + " seconds");
// remove unhit blocks
bstart = System.currentTimeMillis();
new UnreachedCode().run(group);
//new UnusedBlocks().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("unused blocks took " + bdur/1000L + " seconds");
// remove unused parameters
bstart = System.currentTimeMillis();
new UnusedParameters().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("unused params took " + bdur/1000L + " seconds");
// remove jump obfuscation
//new Jumps().run(group);
// remove unused fields
bstart = System.currentTimeMillis();
new UnusedFields().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("unused fields took " + bdur/1000L + " seconds");
// remove unused methods, again?
bstart = System.currentTimeMillis();
new UnusedMethods().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("unused methods took " + bdur/1000L + " seconds");
new MethodInliner().run(group);
// new ModularArithmeticDeobfuscation().run(group);
// new MethodMover().run(group);
//
// new FieldMover().run(group);
new MethodMover().run(group);
new FieldMover().run(group);
new FieldInliner().run(group);
new UnusedClass().run(group);
saveJar(group, args[1]);

View File

@@ -1,5 +1,6 @@
package net.runelite.deob.deobfuscators;
import java.util.ArrayList;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Deobfuscator;
@@ -10,10 +11,13 @@ import net.runelite.deob.attributes.code.Instruction;
import net.runelite.deob.attributes.code.instruction.types.FieldInstruction;
import net.runelite.deob.pool.NameAndType;
import java.util.Collection;
import java.util.List;
import org.apache.commons.collections4.map.MultiValueMap;
public class FieldMover implements Deobfuscator
{
private static final String mainClass = "client";
private ClassGroup group;
private MultiValueMap<Field, ClassFile> fields = new MultiValueMap<>();
@@ -57,6 +61,46 @@ public class FieldMover implements Deobfuscator
}
}
private boolean isDowncastable(ClassFile from, ClassFile to)
{
while (from != null && from != to)
{
from = from.getParent();
}
return from != null;
}
private ClassFile getBase(ClassFile one, ClassFile two)
{
if (one == two)
return one;
if (isDowncastable(one, two))
return two;
if (isDowncastable(two, one))
return one;
return null;
}
private ClassFile findCommonBase(Collection<ClassFile> classes)
{
List<ClassFile> list = new ArrayList<>(classes);
if (list.size() == 1)
return list.get(0);
// ClassFile cf = getBase(list.get(0), list.get(1));
//
// for (int i = 2; i < list.size(); ++i)
// cf = getBase(cf, list.get(i));
//
// return cf;
return null; // to do this, would have to move static initializer
}
private int moveFields()
{
int count = 0;
@@ -65,18 +109,18 @@ public class FieldMover implements Deobfuscator
{
Collection<ClassFile> cfs = fields.getCollection(field);
if (cfs.size() != 1)
{
// XXX clinit
ClassFile to = findCommonBase(cfs);
if (to == null)
continue;
}
// no common base, move to entry class
//to = group.findClass(mainClass);
ClassFile cf = cfs.iterator().next();
assert to != null;
if (field.getFields().getClassFile() == cf)
if (field.getFields().getClassFile() == to)
continue;
moveField(field, cf);
moveField(field, to);
++count;
}

View File

@@ -0,0 +1,28 @@
package net.runelite.deob.deobfuscators;
import java.util.ArrayList;
import net.runelite.deob.ClassFile;
import net.runelite.deob.ClassGroup;
import net.runelite.deob.Deobfuscator;
public class UnusedClass implements Deobfuscator
{
@Override
public void run(ClassGroup group)
{
int count = 0;
for (ClassFile cf : new ArrayList<>(group.getClasses()))
{
if (!cf.getFields().getFields().isEmpty())
continue;
if (!cf.getMethods().getMethods().isEmpty())
continue;
group.removeClass(cf);
++count;
}
System.out.println("Removed " + count + " classes");
}
}

View File

@@ -14,7 +14,7 @@ public class UnusedMethods implements Deobfuscator
@Override
public void run(ClassGroup group)
{
group.buildClassGraph(); // does this use this?
group.buildClassGraph();
Execution execution = new Execution(group);
execution.populateInitialMethods();
@@ -25,7 +25,7 @@ public class UnusedMethods implements Deobfuscator
{
for (Method m : new ArrayList<>(cf.getMethods().getMethods()))
{
if (!Deob.isObfuscated(m.getName()))
if (!Deob.isObfuscated(m.getName()) && !m.getName().equals("<init>"))
continue;
if (!execution.methods.contains(m))

View File

@@ -31,7 +31,7 @@ public class Execution
{
for (Method m : cf.getMethods().getMethods())
{
if (!Deob.isObfuscated(m.getName()))
if (!Deob.isObfuscated(m.getName()) && !m.getName().equals("<init>"))
{
addMethod(m); // I guess this method name is overriding a jre interface (init, run, ?).
}