diff --git a/src/main/java/info/sigterm/deob/ClassFile.java b/src/main/java/info/sigterm/deob/ClassFile.java index 2dc16ef1cf..395b00f659 100644 --- a/src/main/java/info/sigterm/deob/ClassFile.java +++ b/src/main/java/info/sigterm/deob/ClassFile.java @@ -92,6 +92,11 @@ public class ClassFile { return pool; } + + public Interfaces getInterfaces() + { + return interfaces; + } public Fields getFields() { diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index e0456f572d..d07ee7d205 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -8,6 +8,7 @@ import java.io.DataOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -37,7 +38,7 @@ public class Deob group.buildInstructionGraph(); group.buildCallGraph(); - //checkCallGraph(group); + checkCallGraph(group); //execute(group); @@ -69,15 +70,23 @@ public class Deob private static void checkCallGraph(ClassGroup group) { + int i = 0; for (ClassFile cf : group.getClasses()) { - for (Method m : cf.getMethods().getMethods()) + for (Method m : new ArrayList<>(cf.getMethods().getMethods())) { - if (m.callsFrom.isEmpty()) + /* assume obfuscated names are <= 2 chars */ + if (m.getName().length() > 2) + continue; + + if (!m.isUsed()) { System.out.println(cf.getName() + " " + m.getName()); + cf.getMethods().removeMethod(m); + ++i; } } } + System.out.println("Removed " + i + " methods"); } } diff --git a/src/main/java/info/sigterm/deob/Interfaces.java b/src/main/java/info/sigterm/deob/Interfaces.java index d911fa870d..e464beffa4 100644 --- a/src/main/java/info/sigterm/deob/Interfaces.java +++ b/src/main/java/info/sigterm/deob/Interfaces.java @@ -5,6 +5,8 @@ import info.sigterm.deob.pool.Class; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class Interfaces { @@ -26,6 +28,19 @@ public class Interfaces interfaces[i] = is.readUnsignedShort(); } + public List getInterfaces() + { + List l = new ArrayList<>(); + for (int i : interfaces) + { + Class clazz = (Class) classFile.getPool().getEntry(i); + ClassFile iface = classFile.getGroup().findClass(clazz.getName()); + if (iface != null) + l.add(iface); + } + return l; + } + public void write(DataOutputStream out) throws IOException { out.writeShort(count); diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index c9e06356ae..d4971630d3 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -70,6 +70,28 @@ public class Method { return (Code) attributes.findType(AttributeType.CODE); } + + public List getOverriddenMethods() + { + List m = new ArrayList(); + + ClassFile parent = methods.getClassFile().getParent(); + if (parent != null) + { + Method other = parent.getMethods().findMethod(getName(), getDescriptor()); + if (other != null) + m.add(other); + } + + for (ClassFile inter : methods.getClassFile().getInterfaces().getInterfaces()) + { + Method other = inter.getMethods().findMethod(getName(), getDescriptor()); + if (other != null) + m.add(other); + } + + return m; + } public void buildInstructionGraph() { @@ -87,6 +109,20 @@ public class Method code.buildCallGraph(); } + public boolean isUsed() + { + if (!callsFrom.isEmpty()) + return true; + + for (Method sm : getOverriddenMethods()) + { + if (sm.isUsed()) + return true; + } + + return false; + } + public void addCallTo(Instruction ins, Method method) { Node node = new Node(this, method, ins); diff --git a/src/main/java/info/sigterm/deob/Methods.java b/src/main/java/info/sigterm/deob/Methods.java index 5c3e31f0ec..c3dabe4330 100644 --- a/src/main/java/info/sigterm/deob/Methods.java +++ b/src/main/java/info/sigterm/deob/Methods.java @@ -36,7 +36,7 @@ public class Methods public void removeMethod(Method m) { m.remove(); - methods.remove(methods); + methods.remove(m); } public ClassFile getClassFile() @@ -57,6 +57,14 @@ public class Methods return null; } + public Method findMethod(String name, String type) + { + for (Method m : methods) + if (m.getName().equals(name) && m.getDescriptor().equals(type)) + return m; + return null; + } + public Method findMethod(String name) { for (Method m : methods)