Finish methodmover
This commit is contained in:
@@ -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]);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user