Finish methodmover

This commit is contained in:
Adam
2015-08-15 12:49:00 -04:00
parent f91f6f5918
commit fc3c0a258f
10 changed files with 93 additions and 22 deletions

View File

@@ -3,6 +3,9 @@ package info.sigterm.deob;
import info.sigterm.deob.deobfuscators.ConstantParameter;
import info.sigterm.deob.deobfuscators.IllegalStateExceptions;
import info.sigterm.deob.deobfuscators.MethodInliner;
import info.sigterm.deob.deobfuscators.MethodMover;
import info.sigterm.deob.deobfuscators.ModularArithmeticDeobfuscation;
import info.sigterm.deob.deobfuscators.RenameUnique;
import info.sigterm.deob.deobfuscators.RuntimeExceptions;
import info.sigterm.deob.deobfuscators.UnreachedCode;
import info.sigterm.deob.deobfuscators.UnusedFields;
@@ -21,6 +24,13 @@ import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
//move static methods
//move static fields
//math deob
//remove dead classes
//inline constant fields
//compare old and new
public class Deob
{
public static void main(String[] args) throws IOException
@@ -38,9 +48,6 @@ public class Deob
// remove except RuntimeException
bstart = System.currentTimeMillis();
new RuntimeExceptions().run(group);
// the blocks of runtime exceptions may contain interesting things like other obfuscations we identify later, but now that
// it can't be reached by the execution phase, those things become confused. so remove blocks here.
//new UnusedBlocks().run(group);
bdur = System.currentTimeMillis() - bstart;
System.out.println("runtime exception took " + bdur/1000L + " seconds");
@@ -92,9 +99,12 @@ public class Deob
bdur = System.currentTimeMillis() - bstart;
System.out.println("unused methods took " + bdur/1000L + " seconds");
//new ModularArithmeticDeobfuscation().run(group);
new MethodInliner().run(group);
// new ModularArithmeticDeobfuscation().run(group);
new MethodMover().run(group);
saveJar(group, args[1]);

View File

@@ -42,6 +42,8 @@ public class Method
public void write(DataOutputStream out) throws IOException
{
assert methods.getMethods().contains(this);
ConstantPool pool = methods.getClassFile().getPool();
out.writeShort(accessFlags);
@@ -55,6 +57,11 @@ public class Method
return methods;
}
public void setMethods(Methods methods)
{
this.methods = methods;
}
public String getName()
{
return name;

View File

@@ -226,7 +226,7 @@ public abstract class Instruction
{
}
public void renameMethod(Method m, String name)
public void renameMethod(Method oldMethod, info.sigterm.deob.pool.Method newMethod)
{
}
}

View File

@@ -238,9 +238,9 @@ public class Instructions
i.renameField(f, name);
}
public void renameMethod(Method m, String name)
public void renameMethod(Method oldMethod, info.sigterm.deob.pool.Method newMethod)
{
for (Instruction i : instructions)
i.renameMethod(m, name);
i.renameMethod(oldMethod, newMethod);
}
}

View File

@@ -13,6 +13,7 @@ import info.sigterm.deob.execution.StackContext;
import info.sigterm.deob.execution.Type;
import info.sigterm.deob.pool.Class;
import info.sigterm.deob.pool.InterfaceMethod;
import info.sigterm.deob.pool.Method;
import info.sigterm.deob.pool.NameAndType;
import info.sigterm.deob.pool.PoolEntry;
import info.sigterm.deob.signature.Signature;
@@ -149,10 +150,10 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
}
@Override
public void renameMethod(info.sigterm.deob.Method m, String name)
public void renameMethod(info.sigterm.deob.Method m, Method newMethod)
{
for (info.sigterm.deob.Method m2 : getMethods())
if (m2.equals(m))
method = new InterfaceMethod(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor()));
method = new InterfaceMethod(newMethod.getClassEntry(), newMethod.getNameAndType());
}
}

View File

@@ -142,10 +142,10 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
}
@Override
public void renameMethod(info.sigterm.deob.Method m, String name)
public void renameMethod(info.sigterm.deob.Method m, Method newMethod)
{
for (info.sigterm.deob.Method m2 : getMethods())
if (m2.equals(m))
method = new Method(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor()));
method = newMethod;
}
}

View File

@@ -139,7 +139,7 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
}
@Override
public void renameMethod(info.sigterm.deob.Method m, String name)
public void renameMethod(info.sigterm.deob.Method m, Method newMethod)
{
ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup();
ClassFile otherClass = group.findClass(method.getClassEntry().getName());
@@ -150,6 +150,6 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
assert other.isStatic();
if (other.equals(m))
method = new Method(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor()));
method = newMethod;
}
}

View File

@@ -147,10 +147,10 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
}
@Override
public void renameMethod(info.sigterm.deob.Method m, String name)
public void renameMethod(info.sigterm.deob.Method m, Method newMethod)
{
for (info.sigterm.deob.Method m2 : getMethods())
if (m2.equals(m))
method = new Method(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor()));
method = newMethod;
}
}

View File

@@ -9,15 +9,18 @@ import info.sigterm.deob.attributes.code.Instruction;
import info.sigterm.deob.attributes.code.Instructions;
import info.sigterm.deob.attributes.code.instructions.InvokeStatic;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections4.map.MultiValueMap;
// find static methods that are only called from methods of one class
// find static methods that are only called from non-static methods of one class
public class MethodMover implements Deobfuscator
{
private ClassGroup group;
private MultiValueMap<Method, Method> calls = new MultiValueMap<>();
private void buildCalls(ClassGroup group)
private void buildCalls()
{
calls.clear();
@@ -30,6 +33,9 @@ public class MethodMover implements Deobfuscator
if (code == null)
continue;
if (m.isStatic())
continue; // only want member methods
Instructions ins = code.getInstructions();
for (Instruction i : ins.getInstructions())
{
@@ -50,8 +56,10 @@ public class MethodMover implements Deobfuscator
}
}
private void look()
private int moveMethods()
{
int moved = 0;
for (Method m : calls.keySet())
{
Collection<Method> values = calls.getCollection(m);
@@ -76,15 +84,54 @@ public class MethodMover implements Deobfuscator
if (caller == null)
continue;
System.out.println(caller.getName() + " always calls " + m.getName() + " sz " + values.size());
if (m.getMethods().getClassFile() == caller)
continue;
++moved;
move(m, caller);
}
return moved;
}
private void move(Method method, ClassFile to)
{
assert method.getMethods().getClassFile() != to;
info.sigterm.deob.pool.Method newMethod = new info.sigterm.deob.pool.Method(
new info.sigterm.deob.pool.Class(to.getName()),
method.getNameAndType()
);
// move on instructions
for (ClassFile cf : group.getClasses())
{
for (Method m : cf.getMethods().getMethods())
{
Code code = m.getCode();
if (code == null)
continue;
code.getInstructions().renameMethod(method, newMethod);
}
}
// move the method
method.getMethods().removeMethod(method);
to.getMethods().getMethods().add(method);
method.setMethods(to.getMethods());
}
@Override
public void run(ClassGroup group)
{
this.group = group;
group.buildClassGraph();
buildCalls(group);
look();
buildCalls();
int count = moveMethods();
System.out.println("Moved " + count + " methods");
}
}

View File

@@ -174,7 +174,13 @@ public class RenameUnique implements Deobfuscator
{
Instructions instructions = method.getCode().getInstructions();
for (Method m : methods)
instructions.renameMethod(m, name);
{
info.sigterm.deob.pool.Method newMethod = new info.sigterm.deob.pool.Method(
new info.sigterm.deob.pool.Class(m.getMethods().getClassFile().getName()),
new NameAndType(name, m.getNameAndType().getDescriptor())
);
instructions.renameMethod(m, newMethod);
}
}
}
}