wip removal of unused methods based on execution from init.
This commit is contained in:
@@ -9,6 +9,7 @@ import java.io.DataInputStream;
|
|||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ClassFile
|
public class ClassFile
|
||||||
{
|
{
|
||||||
@@ -18,7 +19,7 @@ public class ClassFile
|
|||||||
private DataInputStream is;
|
private DataInputStream is;
|
||||||
|
|
||||||
private ClassFile parent; // super class
|
private ClassFile parent; // super class
|
||||||
private ArrayList<ClassFile> children = new ArrayList<ClassFile>(); // classes which inherit from this
|
private List<ClassFile> children = new ArrayList<>(); // classes which inherit from this
|
||||||
|
|
||||||
private short minor_version;
|
private short minor_version;
|
||||||
private short major_version;
|
private short major_version;
|
||||||
@@ -125,10 +126,12 @@ public class ClassFile
|
|||||||
|
|
||||||
public ClassFile getParent()
|
public ClassFile getParent()
|
||||||
{
|
{
|
||||||
String superName = super_class.getName();
|
return parent;
|
||||||
ClassFile other = group.findClass(superName);
|
}
|
||||||
assert other != this;
|
|
||||||
return other;
|
public List<ClassFile> getChildren()
|
||||||
|
{
|
||||||
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field findField(NameAndType nat)
|
public Field findField(NameAndType nat)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public class ClassGroup
|
public class ClassGroup
|
||||||
{
|
{
|
||||||
private ArrayList<ClassFile> classes = new ArrayList<ClassFile>();
|
private List<ClassFile> classes = new ArrayList<>();
|
||||||
|
|
||||||
public ClassGroup()
|
public ClassGroup()
|
||||||
{
|
{
|
||||||
@@ -45,16 +45,4 @@ public class ClassGroup
|
|||||||
for (ClassFile c : classes)
|
for (ClassFile c : classes)
|
||||||
c.buildInstructionGraph();
|
c.buildInstructionGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildCallGraph()
|
|
||||||
{
|
|
||||||
for (ClassFile c : classes)
|
|
||||||
for (Method m : c.getMethods().getMethods())
|
|
||||||
{
|
|
||||||
m.callsTo.clear();
|
|
||||||
m.callsFrom.clear();
|
|
||||||
}
|
|
||||||
for (ClassFile c : classes)
|
|
||||||
c.buildCallGraph();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public class Deob
|
|||||||
|
|
||||||
ClassGroup group = loadJar(args[0]);
|
ClassGroup group = loadJar(args[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
// remove except RuntimeException
|
// remove except RuntimeException
|
||||||
new RuntimeExceptions().run(group);
|
new RuntimeExceptions().run(group);
|
||||||
|
|
||||||
@@ -48,18 +49,19 @@ public class Deob
|
|||||||
new IllegalStateExceptions().run(group);
|
new IllegalStateExceptions().run(group);
|
||||||
|
|
||||||
// remove code blocks that used to be the runtime exception handlers
|
// remove code blocks that used to be the runtime exception handlers
|
||||||
new UnusedBlocks().run(group);
|
new UnusedBlocks().run(group);*/
|
||||||
|
|
||||||
// remove unused methods
|
// remove unused methods
|
||||||
new UnusedMethods().run(group);
|
new UnusedMethods().run(group);
|
||||||
|
|
||||||
|
/*
|
||||||
// remove unused parameters
|
// remove unused parameters
|
||||||
new UnusedParameters().run(group);
|
new UnusedParameters().run(group);
|
||||||
|
|
||||||
// remove jump obfuscation
|
// remove jump obfuscation
|
||||||
new Jumps().run(group);
|
new Jumps().run(group);
|
||||||
|
|
||||||
new ModularArithmeticDeobfuscation().run(group);
|
new ModularArithmeticDeobfuscation().run(group);*/
|
||||||
|
|
||||||
saveJar(group, args[1]);
|
saveJar(group, args[1]);
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ public class Method
|
|||||||
private String name;
|
private String name;
|
||||||
private Signature arguments;
|
private Signature arguments;
|
||||||
private Attributes attributes;
|
private Attributes attributes;
|
||||||
List<Node> callsTo = new ArrayList<>();
|
|
||||||
List<Node> callsFrom = new ArrayList<>();
|
|
||||||
|
|
||||||
Method(Methods methods) throws IOException
|
Method(Methods methods) throws IOException
|
||||||
{
|
{
|
||||||
@@ -60,11 +58,12 @@ public class Method
|
|||||||
|
|
||||||
protected void remove()
|
protected void remove()
|
||||||
{
|
{
|
||||||
assert callsFrom.isEmpty();
|
//assert callsFrom.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeParameter(Execution execution, int paramIndex, int lvtIndex)
|
public void removeParameter(Execution execution, int paramIndex, int lvtIndex)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
Set<Instruction> done = new HashSet<>();
|
Set<Instruction> done = new HashSet<>();
|
||||||
for (Node n : callsFrom)
|
for (Node n : callsFrom)
|
||||||
{
|
{
|
||||||
@@ -160,6 +159,7 @@ public class Method
|
|||||||
}
|
}
|
||||||
|
|
||||||
arguments.remove(paramIndex);
|
arguments.remove(paramIndex);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public Methods getMethods()
|
public Methods getMethods()
|
||||||
@@ -222,13 +222,13 @@ public class Method
|
|||||||
code.buildInstructionGraph();
|
code.buildInstructionGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearCallGraph()
|
/*public void clearCallGraph()
|
||||||
{
|
{
|
||||||
callsTo.clear();
|
callsTo.clear();
|
||||||
callsFrom.clear();
|
callsFrom.clear();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
public boolean isUsed()
|
/*public boolean isUsed()
|
||||||
{
|
{
|
||||||
if (!callsFrom.isEmpty())
|
if (!callsFrom.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
@@ -240,8 +240,9 @@ public class Method
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
public void addCallTo(Instruction ins, Method method)
|
public void addCallTo(Instruction ins, Method method)
|
||||||
{
|
{
|
||||||
assert method != null;
|
assert method != null;
|
||||||
@@ -249,6 +250,7 @@ public class Method
|
|||||||
callsTo.add(node);
|
callsTo.add(node);
|
||||||
method.callsFrom.add(node);
|
method.callsFrom.add(node);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Instruction & LVTInstruction> List<T> findLVTInstructionsForVariable(int index)
|
public <T extends Instruction & LVTInstruction> List<T> findLVTInstructionsForVariable(int index)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package info.sigterm.deob.attributes.code.instruction.types;
|
package info.sigterm.deob.attributes.code.instruction.types;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import info.sigterm.deob.Method;
|
import info.sigterm.deob.Method;
|
||||||
import info.sigterm.deob.pool.PoolEntry;
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package info.sigterm.deob.attributes.code.instructions;
|
package info.sigterm.deob.attributes.code.instructions;
|
||||||
|
|
||||||
import info.sigterm.deob.ClassFile;
|
import info.sigterm.deob.ClassFile;
|
||||||
|
import info.sigterm.deob.ClassGroup;
|
||||||
import info.sigterm.deob.attributes.code.Instruction;
|
import info.sigterm.deob.attributes.code.Instruction;
|
||||||
import info.sigterm.deob.attributes.code.InstructionType;
|
import info.sigterm.deob.attributes.code.InstructionType;
|
||||||
import info.sigterm.deob.attributes.code.Instructions;
|
import info.sigterm.deob.attributes.code.Instructions;
|
||||||
@@ -11,7 +12,6 @@ import info.sigterm.deob.execution.Stack;
|
|||||||
import info.sigterm.deob.execution.StackContext;
|
import info.sigterm.deob.execution.StackContext;
|
||||||
import info.sigterm.deob.execution.Type;
|
import info.sigterm.deob.execution.Type;
|
||||||
import info.sigterm.deob.pool.InterfaceMethod;
|
import info.sigterm.deob.pool.InterfaceMethod;
|
||||||
import info.sigterm.deob.pool.Method;
|
|
||||||
import info.sigterm.deob.pool.NameAndType;
|
import info.sigterm.deob.pool.NameAndType;
|
||||||
import info.sigterm.deob.pool.PoolEntry;
|
import info.sigterm.deob.pool.PoolEntry;
|
||||||
import info.sigterm.deob.signature.Signature;
|
import info.sigterm.deob.signature.Signature;
|
||||||
@@ -19,6 +19,8 @@ import info.sigterm.deob.signature.Signature;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class InvokeInterface extends Instruction implements InvokeInstruction
|
public class InvokeInterface extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -45,20 +47,28 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
|
|||||||
out.writeByte(0);
|
out.writeByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private List<info.sigterm.deob.Method> getMethods()
|
||||||
public void buildCallGraph()
|
|
||||||
{
|
{
|
||||||
info.sigterm.deob.pool.Class clazz = method.getClassEntry();
|
ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup();
|
||||||
NameAndType nat = method.getNameAndType();
|
|
||||||
|
|
||||||
info.sigterm.deob.Method thisMethod = this.getInstructions().getCode().getAttributes().getMethod();
|
ClassFile otherClass = group.findClass(method.getClassEntry().getName());
|
||||||
|
|
||||||
ClassFile otherClass = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName());
|
|
||||||
if (otherClass == null)
|
if (otherClass == null)
|
||||||
return;
|
return new ArrayList<>(); // not our class
|
||||||
info.sigterm.deob.Method other = otherClass.findMethod(nat);
|
|
||||||
|
|
||||||
thisMethod.addCallTo(this, other);
|
// look up this method in this class and anything that inherits from it
|
||||||
|
List<info.sigterm.deob.Method> list = new ArrayList<>();
|
||||||
|
findMethodFromClass(list, otherClass);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findMethodFromClass(List<info.sigterm.deob.Method> list, ClassFile clazz)
|
||||||
|
{
|
||||||
|
info.sigterm.deob.Method m = clazz.findMethod(method.getNameAndType());
|
||||||
|
if (m != null)
|
||||||
|
list.add(m);
|
||||||
|
|
||||||
|
for (ClassFile cf : clazz.getChildren())
|
||||||
|
findMethodFromClass(list, cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -89,6 +99,12 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|
||||||
|
for (info.sigterm.deob.Method method : getMethods())
|
||||||
|
{
|
||||||
|
// add possible method call to execution
|
||||||
|
frame.getExecution().addMethod(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleExceptions(Frame frame)
|
private void handleExceptions(Frame frame)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package info.sigterm.deob.attributes.code.instructions;
|
package info.sigterm.deob.attributes.code.instructions;
|
||||||
|
|
||||||
import info.sigterm.deob.ClassFile;
|
import info.sigterm.deob.ClassFile;
|
||||||
|
import info.sigterm.deob.ClassGroup;
|
||||||
import info.sigterm.deob.attributes.code.Instruction;
|
import info.sigterm.deob.attributes.code.Instruction;
|
||||||
import info.sigterm.deob.attributes.code.InstructionType;
|
import info.sigterm.deob.attributes.code.InstructionType;
|
||||||
import info.sigterm.deob.attributes.code.Instructions;
|
import info.sigterm.deob.attributes.code.Instructions;
|
||||||
@@ -18,6 +19,8 @@ import info.sigterm.deob.signature.Signature;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class InvokeSpecial extends Instruction implements InvokeInstruction
|
public class InvokeSpecial extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -39,21 +42,19 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
|
|||||||
out.writeShort(this.getPool().make(method));
|
out.writeShort(this.getPool().make(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private List<info.sigterm.deob.Method> getMethods()
|
||||||
public void buildCallGraph()
|
|
||||||
{
|
{
|
||||||
info.sigterm.deob.pool.Class clazz = method.getClassEntry();
|
ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup();
|
||||||
NameAndType nat = method.getNameAndType();
|
|
||||||
|
|
||||||
info.sigterm.deob.Method thisMethod = this.getInstructions().getCode().getAttributes().getMethod();
|
ClassFile otherClass = group.findClass(method.getClassEntry().getName());
|
||||||
|
|
||||||
ClassFile otherClass = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName());
|
|
||||||
if (otherClass == null)
|
if (otherClass == null)
|
||||||
return;
|
return new ArrayList<>(); // not our class
|
||||||
|
|
||||||
info.sigterm.deob.Method other = otherClass.findMethod(nat);
|
info.sigterm.deob.Method other = otherClass.findMethod(method.getNameAndType());
|
||||||
|
|
||||||
thisMethod.addCallTo(this, other);
|
List<info.sigterm.deob.Method> list = new ArrayList<>();
|
||||||
|
list.add(other);
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -84,6 +85,12 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|
||||||
|
for (info.sigterm.deob.Method method : getMethods())
|
||||||
|
{
|
||||||
|
// add possible method call to execution
|
||||||
|
frame.getExecution().addMethod(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleExceptions(Frame frame)
|
private void handleExceptions(Frame frame)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package info.sigterm.deob.attributes.code.instructions;
|
package info.sigterm.deob.attributes.code.instructions;
|
||||||
|
|
||||||
import info.sigterm.deob.ClassFile;
|
import info.sigterm.deob.ClassFile;
|
||||||
|
import info.sigterm.deob.ClassGroup;
|
||||||
import info.sigterm.deob.attributes.code.Instruction;
|
import info.sigterm.deob.attributes.code.Instruction;
|
||||||
import info.sigterm.deob.attributes.code.InstructionType;
|
import info.sigterm.deob.attributes.code.InstructionType;
|
||||||
import info.sigterm.deob.attributes.code.Instructions;
|
import info.sigterm.deob.attributes.code.Instructions;
|
||||||
@@ -18,6 +19,8 @@ import info.sigterm.deob.signature.Signature;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class InvokeStatic extends Instruction implements InvokeInstruction
|
public class InvokeStatic extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -39,21 +42,19 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
|||||||
out.writeShort(this.getPool().make(method));
|
out.writeShort(this.getPool().make(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private List<info.sigterm.deob.Method> getMethods()
|
||||||
public void buildCallGraph()
|
|
||||||
{
|
{
|
||||||
info.sigterm.deob.pool.Class clazz = method.getClassEntry();
|
ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup();
|
||||||
NameAndType nat = method.getNameAndType();
|
|
||||||
|
|
||||||
info.sigterm.deob.Method thisMethod = this.getInstructions().getCode().getAttributes().getMethod();
|
ClassFile otherClass = group.findClass(method.getClassEntry().getName());
|
||||||
|
|
||||||
ClassFile otherClass = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName());
|
|
||||||
if (otherClass == null)
|
if (otherClass == null)
|
||||||
return;
|
return new ArrayList<>(); // not our class
|
||||||
|
|
||||||
info.sigterm.deob.Method other = otherClass.findMethod(nat);
|
info.sigterm.deob.Method other = otherClass.findMethod(method.getNameAndType());
|
||||||
|
|
||||||
thisMethod.addCallTo(this, other);
|
List<info.sigterm.deob.Method> list = new ArrayList<>();
|
||||||
|
list.add(other);
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -81,6 +82,12 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|
||||||
|
for (info.sigterm.deob.Method method : getMethods())
|
||||||
|
{
|
||||||
|
// add possible method call to execution
|
||||||
|
frame.getExecution().addMethod(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleExceptions(Frame frame)
|
private void handleExceptions(Frame frame)
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import info.sigterm.deob.signature.Signature;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class InvokeVirtual extends Instruction implements InvokeInstruction
|
public class InvokeVirtual extends Instruction implements InvokeInstruction
|
||||||
{
|
{
|
||||||
@@ -40,24 +42,6 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
|||||||
out.writeShort(this.getPool().make(method));
|
out.writeShort(this.getPool().make(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void buildCallGraph()
|
|
||||||
{
|
|
||||||
info.sigterm.deob.pool.Class clazz = method.getClassEntry();
|
|
||||||
NameAndType nat = method.getNameAndType();
|
|
||||||
|
|
||||||
info.sigterm.deob.Method thisMethod = this.getInstructions().getCode().getAttributes().getMethod();
|
|
||||||
|
|
||||||
ClassFile otherClass = this.getInstructions().getCode().getAttributes().getClassFile().getGroup().findClass(clazz.getName());
|
|
||||||
if (otherClass == null)
|
|
||||||
return;
|
|
||||||
info.sigterm.deob.Method other = otherClass.findMethod(nat);
|
|
||||||
if (other == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
thisMethod.addCallTo(this, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Frame frame)
|
public void execute(Frame frame)
|
||||||
{
|
{
|
||||||
@@ -75,9 +59,6 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
|||||||
StackContext object = stack.pop();
|
StackContext object = stack.pop();
|
||||||
ins.pop(object);
|
ins.pop(object);
|
||||||
|
|
||||||
// the method being invoked, looked up dynamically based on the type
|
|
||||||
//info.sigterm.deob.Method executedMethod = findVirtualMethod(object.getType());
|
|
||||||
|
|
||||||
handleExceptions(frame);
|
handleExceptions(frame);
|
||||||
|
|
||||||
if (!method.getNameAndType().isVoid())
|
if (!method.getNameAndType().isVoid())
|
||||||
@@ -89,31 +70,39 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame.addInstructionContext(ins);
|
frame.addInstructionContext(ins);
|
||||||
|
|
||||||
|
for (info.sigterm.deob.Method method : getMethods())
|
||||||
|
{
|
||||||
|
// add possible method call to execution
|
||||||
|
frame.getExecution().addMethod(method);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private info.sigterm.deob.Method findVirtualMethod(Type type)
|
// find the possible methods this instruction might be invoking. we can't know for sure
|
||||||
|
// which method is being invoked without tracking the types of objects in fields and when
|
||||||
|
// passed in parameters/return values.
|
||||||
|
private List<info.sigterm.deob.Method> getMethods()
|
||||||
{
|
{
|
||||||
// invokevirtual 'method' on 'type', see if we can find the actual method that would be invoked based on the type of the object
|
|
||||||
ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup();
|
ClassGroup group = this.getInstructions().getCode().getAttributes().getClassFile().getGroup();
|
||||||
|
|
||||||
ClassFile otherClass = group.findClass(type.type);
|
ClassFile otherClass = group.findClass(method.getClassEntry().getName());
|
||||||
if (otherClass == null)
|
if (otherClass == null)
|
||||||
return null; // not our class
|
return new ArrayList<>(); // not our class
|
||||||
|
|
||||||
// now find the method with the same signature as 'method' on this class, or subclass
|
// look up this method in this class and anything that inherits from it
|
||||||
return findMethodFromClass(otherClass);
|
List<info.sigterm.deob.Method> list = new ArrayList<>();
|
||||||
|
findMethodFromClass(list, otherClass);
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private info.sigterm.deob.Method findMethodFromClass(ClassFile clazz)
|
private void findMethodFromClass(List<info.sigterm.deob.Method> list, ClassFile clazz)
|
||||||
{
|
{
|
||||||
if (clazz == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
info.sigterm.deob.Method m = clazz.findMethod(method.getNameAndType());
|
info.sigterm.deob.Method m = clazz.findMethod(method.getNameAndType());
|
||||||
if (m != null)
|
if (m != null)
|
||||||
return m;
|
list.add(m);
|
||||||
|
|
||||||
return findMethodFromClass(clazz.getParent());
|
for (ClassFile cf : clazz.getChildren())
|
||||||
|
findMethodFromClass(list, cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleExceptions(Frame frame)
|
private void handleExceptions(Frame frame)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package info.sigterm.deob.deobfuscators;
|
|||||||
import info.sigterm.deob.ClassFile;
|
import info.sigterm.deob.ClassFile;
|
||||||
import info.sigterm.deob.ClassGroup;
|
import info.sigterm.deob.ClassGroup;
|
||||||
import info.sigterm.deob.Method;
|
import info.sigterm.deob.Method;
|
||||||
|
import info.sigterm.deob.execution.Execution;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -10,7 +11,9 @@ public class UnusedMethods
|
|||||||
{
|
{
|
||||||
public void run(ClassGroup group)
|
public void run(ClassGroup group)
|
||||||
{
|
{
|
||||||
group.buildCallGraph();
|
Execution execution = new Execution(group);
|
||||||
|
execution.populateInitialMethods();
|
||||||
|
execution.run();
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ClassFile cf : group.getClasses())
|
for (ClassFile cf : group.getClasses())
|
||||||
@@ -21,7 +24,8 @@ public class UnusedMethods
|
|||||||
if (m.getName().length() > 2)
|
if (m.getName().length() > 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!m.isUsed())
|
if (!execution.methods.contains(m))
|
||||||
|
//if (!m.isUsed())
|
||||||
{
|
{
|
||||||
cf.getMethods().removeMethod(m);
|
cf.getMethods().removeMethod(m);
|
||||||
++i;
|
++i;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class UnusedParameters
|
|||||||
int collide = 0;
|
int collide = 0;
|
||||||
int overrides = 0;
|
int overrides = 0;
|
||||||
|
|
||||||
group.buildCallGraph(); // method.removeParameter uses the callgraph
|
//group.buildCallGraph(); // method.removeParameter uses the callgraph
|
||||||
|
|
||||||
for (ClassFile cf : group.getClasses())
|
for (ClassFile cf : group.getClasses())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,36 +6,65 @@ import info.sigterm.deob.Method;
|
|||||||
import info.sigterm.deob.attributes.code.Exceptions;
|
import info.sigterm.deob.attributes.code.Exceptions;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class Execution
|
public class Execution
|
||||||
{
|
{
|
||||||
private ClassGroup group;
|
private ClassGroup group;
|
||||||
public List<Frame> frames = new ArrayList<>(),
|
public List<Frame> frames = new ArrayList<>(),
|
||||||
processedFrames = new ArrayList<>();
|
processedFrames = new ArrayList<>();
|
||||||
|
private List<Method> pendingMethods = new ArrayList<>(); // pending methods
|
||||||
|
public Set<Method> methods = new HashSet<>(); // all methods
|
||||||
|
|
||||||
public Execution(ClassGroup group)
|
public Execution(ClassGroup group)
|
||||||
{
|
{
|
||||||
this.group = group;
|
this.group = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void populateInitialMethods()
|
||||||
|
{
|
||||||
|
for (ClassFile cf : group.getClasses())
|
||||||
|
{
|
||||||
|
for (Method m : cf.getMethods().getMethods())
|
||||||
|
{
|
||||||
|
// ob'd names seem to be <= 2
|
||||||
|
if (m.getName().length() > 2)
|
||||||
|
{
|
||||||
|
addMethod(m); // I guess this method name is overriding a jre interface (init, run, ?).
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMethod(Method method)
|
||||||
|
{
|
||||||
|
if (methods.contains(method))
|
||||||
|
return; // already processed
|
||||||
|
|
||||||
|
pendingMethods.add(method);
|
||||||
|
methods.add(method);
|
||||||
|
}
|
||||||
|
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
// XXX update pc? some instructiosn rely on it still.
|
// XXX update pc? some instructiosn rely on it still.
|
||||||
|
|
||||||
int count = 0, fcount = 0;
|
int count = 0, fcount = 0;
|
||||||
for (ClassFile cf : group.getClasses())
|
while (!pendingMethods.isEmpty())
|
||||||
for (Method method : cf.getMethods().getMethods())
|
{
|
||||||
{
|
Method method = pendingMethods.remove(0);
|
||||||
if (method.getCode() == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Frame f = new Frame(this, method);
|
if (method.getCode() == null)
|
||||||
frames.add(f);
|
continue;
|
||||||
|
|
||||||
fcount += this.runFrames();
|
Frame f = new Frame(this, method);
|
||||||
++count;
|
frames.add(f);
|
||||||
}
|
|
||||||
|
fcount += this.runFrames();
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("Processed " + count + " methods and " + fcount + " paths");
|
System.out.println("Processed " + count + " methods and " + fcount + " paths");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,11 @@ public class Frame
|
|||||||
executing = false;
|
executing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Execution getExecution()
|
||||||
|
{
|
||||||
|
return execution;
|
||||||
|
}
|
||||||
|
|
||||||
public Method getMethod()
|
public Method getMethod()
|
||||||
{
|
{
|
||||||
return method;
|
return method;
|
||||||
|
|||||||
Reference in New Issue
Block a user