From 9c3b0b4754f9d19c05a2eab89e8ab1f01c3ad90f Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 4 Aug 2015 20:40:20 -0400 Subject: [PATCH] Fix identifying vmethods incorrectly if two classes can be reached in the classgraph with two methods that have the same name and signature but are otherwise unrelated --- src/main/java/info/sigterm/deob/Deob.java | 2 +- .../deob/deobfuscators/RenameUnique.java | 48 ++++++++++++++----- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/main/java/info/sigterm/deob/Deob.java b/src/main/java/info/sigterm/deob/Deob.java index dd0e388730..33ce50dc77 100644 --- a/src/main/java/info/sigterm/deob/Deob.java +++ b/src/main/java/info/sigterm/deob/Deob.java @@ -72,7 +72,7 @@ public class Deob bstart = System.currentTimeMillis(); new UnusedParameters().run(group); bdur = System.currentTimeMillis() - bstart; - System.out.println("unused blocks took " + bdur/1000L + " seconds"); + System.out.println("unused params took " + bdur/1000L + " seconds"); // remove jump obfuscation //new Jumps().run(group); diff --git a/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java b/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java index 763dab908a..40e3e1cba2 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java @@ -12,6 +12,7 @@ import info.sigterm.deob.Method; import info.sigterm.deob.attributes.code.Exceptions; import info.sigterm.deob.attributes.code.Instructions; import info.sigterm.deob.pool.Class; +import info.sigterm.deob.pool.NameAndType; import info.sigterm.deob.signature.Signature; import info.sigterm.deob.signature.Type; import java.util.HashSet; @@ -102,24 +103,44 @@ public class RenameUnique implements Deobfuscator field.setName(name); } - private void findMethod(List list, Set visited, ClassFile cf, Method method) + // find the base methods for a method. search goes up from there to see if two + // different methods can be invoked with the same instruction. + private List findBaseMethods(List methods, ClassFile cf, NameAndType method) + { + if (cf == null) + return methods; + + Method m = cf.findMethod(method); + if (m != null && !m.isStatic()) + methods.add(m); + + List parentMethods = findBaseMethods(new ArrayList(), cf.getParent(), method); + + for (ClassFile inter : cf.getInterfaces().getMyInterfaces()) + findBaseMethods(parentMethods, inter, method); + + // parentMethods take precedence over our methods + return parentMethods.isEmpty() ? methods : parentMethods; + } + + private List findBaseMethods(Method method) + { + return findBaseMethods(new ArrayList(), method.getMethods().getClassFile(), method.getNameAndType()); + } + + private void findMethodUp(List methods, Set visited, ClassFile cf, NameAndType method) { if (cf == null || visited.contains(cf)) return; - visited.add(cf); + visited.add(cf); // can do diamond inheritance with interfaces - Method m = cf.findMethod(method.getNameAndType()); + Method m = cf.findMethod(method); if (m != null && !m.isStatic()) - list.add(m); + methods.add(m); - findMethod(list, visited, cf.getParent(), method); - - for (ClassFile inter : cf.getInterfaces().getMyInterfaces()) - findMethod(list, visited, inter, method); - for (ClassFile child : cf.getChildren()) - findMethod(list, visited, child, method); + findMethodUp(methods, visited, child, method); } private List getVirutalMethods(Method method) @@ -132,7 +153,12 @@ public class RenameUnique implements Deobfuscator return list; } - findMethod(list, new HashSet(), method.getMethods().getClassFile(), method); + List bases = findBaseMethods(method); // base methods method overrides + assert !bases.isEmpty(); // must contain at least a method + + // now search up from bases, appending to list. + for (Method m : bases) + findMethodUp(list, new HashSet(), m.getMethods().getClassFile(), m.getNameAndType()); return list; }