diff --git a/src/main/java/info/sigterm/deob/ClassFile.java b/src/main/java/info/sigterm/deob/ClassFile.java index c02c916872..ab61ba7a48 100644 --- a/src/main/java/info/sigterm/deob/ClassFile.java +++ b/src/main/java/info/sigterm/deob/ClassFile.java @@ -149,7 +149,7 @@ public class ClassFile return children; } - public Field findField(NameAndType nat) + public Field findFieldDeep(NameAndType nat) { Field f = fields.findField(nat); if (f != null) @@ -157,12 +157,12 @@ public class ClassFile ClassFile parent = getParent(); if (parent != null) - return parent.findField(nat); + return parent.findFieldDeep(nat); return null; } - public Method findMethod(NameAndType nat) + public Method findMethodDeep(NameAndType nat) { Method m = methods.findMethod(nat); if (m != null) @@ -170,12 +170,17 @@ public class ClassFile ClassFile parent = getParent(); if (parent != null) - return parent.findMethod(nat); + return parent.findMethodDeep(nat); return null; } - public Method findMethod(String name) + public Method findMethod(NameAndType nat) + { + return methods.findMethod(nat); + } + + public Method findMethodDeep(String name) { Method m = methods.findMethod(name); if (m != null) @@ -183,7 +188,7 @@ public class ClassFile ClassFile parent = getParent(); if (parent != null) - return parent.findMethod(name); + return parent.findMethodDeep(name); return null; } diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index aa9eb585d8..7bbbe5c8b4 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -58,6 +58,11 @@ public class Method { return name; } + + public void setName(String name) + { + this.name = name; + } public Signature getDescriptor() { diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java index 9fe1e03e0a..7bfe972d3d 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java @@ -3,6 +3,7 @@ package info.sigterm.deob.attributes.code; import info.sigterm.deob.ClassFile; import info.sigterm.deob.ConstantPool; import info.sigterm.deob.Field; +import info.sigterm.deob.Method; import info.sigterm.deob.execution.Frame; import java.io.DataOutputStream; @@ -216,4 +217,8 @@ public abstract class Instruction public void renameField(Field f, String name) { } + + public void renameMethod(Method m, String name) + { + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java index af783f6c7a..d820bd67c3 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java @@ -2,6 +2,7 @@ package info.sigterm.deob.attributes.code; import info.sigterm.deob.ClassFile; import info.sigterm.deob.Field; +import info.sigterm.deob.Method; import info.sigterm.deob.attributes.Code; import info.sigterm.deob.attributes.code.instruction.types.JumpingInstruction; @@ -209,4 +210,10 @@ public class Instructions for (Instruction i : instructions) i.renameField(f, name); } + + public void renameMethod(Method m, String name) + { + for (Instruction i : instructions) + i.renameMethod(m, name); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java index 3a4e20f8e8..2ea2f1257c 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/GetStatic.java @@ -62,7 +62,7 @@ public class GetStatic extends Instruction implements GetFieldInstruction if (cf == null) return; - info.sigterm.deob.Field f = cf.findField(nat); + info.sigterm.deob.Field f = cf.findFieldDeep(nat); assert f != null; f.addReference(this); diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java index bd7af501a2..c78cb7b809 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeInterface.java @@ -64,7 +64,7 @@ public class InvokeInterface extends Instruction implements InvokeInstruction private void findMethodFromClass(List list, ClassFile clazz) { - info.sigterm.deob.Method m = clazz.findMethod(method.getNameAndType()); + info.sigterm.deob.Method m = clazz.findMethodDeep(method.getNameAndType()); if (m != null) list.add(m); @@ -163,4 +163,11 @@ public class InvokeInterface extends Instruction implements InvokeInstruction if (method.getClassEntry().getName().equals(cf.getName())) method = new InterfaceMethod(new Class(name), method.getNameAndType()); } + + @Override + public void renameMethod(info.sigterm.deob.Method m, String name) + { + if (method.getNameAndType().equals(m.getNameAndType()) && method.getClassEntry().getName().equals(m.getMethods().getClassFile().getName())) + method = new InterfaceMethod(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor())); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java index 068c8e7ae2..22fa9e8bd4 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeSpecial.java @@ -51,7 +51,7 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction if (otherClass == null) return new ArrayList<>(); // not our class - info.sigterm.deob.Method other = otherClass.findMethod(method.getNameAndType()); + info.sigterm.deob.Method other = otherClass.findMethodDeep(method.getNameAndType()); List list = new ArrayList<>(); list.add(other); @@ -155,4 +155,11 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction if (method.getClassEntry().getName().equals(cf.getName())) method = new Method(new Class(name), method.getNameAndType()); } + + @Override + public void renameMethod(info.sigterm.deob.Method m, String name) + { + if (method.getNameAndType().equals(m.getNameAndType()) && method.getClassEntry().getName().equals(m.getMethods().getClassFile().getName())) + method = new Method(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor())); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java index bb45bbcd24..6571d058fb 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeStatic.java @@ -51,7 +51,7 @@ public class InvokeStatic extends Instruction implements InvokeInstruction if (otherClass == null) return new ArrayList<>(); // not our class - info.sigterm.deob.Method other = otherClass.findMethod(method.getNameAndType()); + info.sigterm.deob.Method other = otherClass.findMethodDeep(method.getNameAndType()); List list = new ArrayList<>(); list.add(other); @@ -152,4 +152,11 @@ public class InvokeStatic extends Instruction implements InvokeInstruction if (method.getClassEntry().getName().equals(cf.getName())) method = new Method(new Class(name), method.getNameAndType()); } + + @Override + public void renameMethod(info.sigterm.deob.Method m, String name) + { + if (method.getNameAndType().equals(m.getNameAndType()) && method.getClassEntry().getName().equals(m.getMethods().getClassFile().getName())) + method = new Method(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor())); + } } diff --git a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java index ba645f08fa..15b699d047 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java +++ b/src/main/java/info/sigterm/deob/attributes/code/instructions/InvokeVirtual.java @@ -99,7 +99,7 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction private void findMethodFromClass(List list, ClassFile clazz) { - info.sigterm.deob.Method m = clazz.findMethod(method.getNameAndType()); + info.sigterm.deob.Method m = clazz.findMethodDeep(method.getNameAndType()); if (m != null) list.add(m); @@ -162,4 +162,11 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction if (method.getClassEntry().getName().equals(cf.getName())) method = new Method(new Class(name), method.getNameAndType()); } + + @Override + public void renameMethod(info.sigterm.deob.Method m, String name) + { + if (method.getNameAndType().equals(m.getNameAndType()) && method.getClassEntry().getName().equals(m.getMethods().getClassFile().getName())) + method = new Method(method.getClassEntry(), new NameAndType(name, method.getNameAndType().getDescriptor())); + } } diff --git a/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java b/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java index 522b223491..7680df7dc5 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/ModularArithmeticDeobfuscation.java @@ -123,7 +123,7 @@ public class ModularArithmeticDeobfuscation implements Deobfuscator ClassFile cf = group.findClass(field.getClassEntry().getName()); if (cf == null) return null; - return cf.findField(field.getNameAndType()); + return cf.findFieldDeep(field.getNameAndType()); } private List checkDown(InstructionContext context) @@ -261,7 +261,7 @@ public class ModularArithmeticDeobfuscation implements Deobfuscator // get Field from pool Field info.sigterm.deob.pool.Field field = gf.getField(); - Field f = group.findClass(field.getClassEntry().getName()).findField(field.getNameAndType()); + Field f = group.findClass(field.getClassEntry().getName()).findFieldDeep(field.getNameAndType()); assert f != null; @@ -296,7 +296,7 @@ public class ModularArithmeticDeobfuscation implements Deobfuscator // get Field from pool Field info.sigterm.deob.pool.Field field = sf.getField(); - Field f = group.findClass(field.getClassEntry().getName()).findField(field.getNameAndType()); + Field f = group.findClass(field.getClassEntry().getName()).findFieldDeep(field.getNameAndType()); assert f != null; @@ -424,7 +424,7 @@ public class ModularArithmeticDeobfuscation implements Deobfuscator // get Field from pool Field info.sigterm.deob.pool.Field field = gf.getField(); - Field f = group.findClass(field.getClassEntry().getName()).findField(field.getNameAndType()); + Field f = group.findClass(field.getClassEntry().getName()).findFieldDeep(field.getNameAndType()); Magic magic = workMagics.getMagic(f); diff --git a/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java b/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java index d1bcb6ee31..296e8e31a3 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/RenameUnique.java @@ -1,5 +1,6 @@ package info.sigterm.deob.deobfuscators; +import java.util.ArrayList; import java.util.List; import info.sigterm.deob.ClassFile; @@ -93,6 +94,70 @@ public class RenameUnique implements Deobfuscator field.setName(name); } + + private void findMethodDown(List list, ClassFile cf, Method method) + { + if (cf == null) + return; + + Method m = cf.findMethod(method.getNameAndType()); + if (m != null && !m.isStatic()) + list.add(m); + + findMethodDown(list, cf.getParent(), method); + + for (ClassFile inter : cf.getInterfaces().getMyInterfaces()) + findMethodDown(list, inter, method); + } + + private void findMethodUp(List list, ClassFile cf, Method method) + { + Method m = cf.findMethod(method.getNameAndType()); + if (m != null && !m.isStatic()) + list.add(m); + + for (ClassFile child : cf.getChildren()) + findMethodUp(list, child, method); + } + + private List getVirutalMethods(Method method) + { + List list = new ArrayList<>(); + + list.add(method); + + if (method.isStatic()) + return list; + + ClassFile classOfMethod = method.getMethods().getClassFile(); + findMethodDown(list, classOfMethod.getParent(), method); + + for (ClassFile inter : classOfMethod.getInterfaces().getMyInterfaces()) + findMethodDown(list, inter, method); + + for (ClassFile child : classOfMethod.getChildren()) + findMethodUp(list, child, method); + + return list; + } + + private void renameMethod(ClassGroup group, Method m, String name) + { + for (ClassFile c : group.getClasses()) + { + for (Method method : c.getMethods().getMethods()) + { + // rename on instructions + if (method.getCode() != null) + { + Instructions instructions = method.getCode().getInstructions(); + instructions.renameMethod(m, name); + } + } + } + + m.setName(name); + } @Override public void run(ClassGroup group) @@ -120,7 +185,23 @@ public class RenameUnique implements Deobfuscator ++fields; } + group.buildClassGraph(); + // rename methods + for (ClassFile cf : group.getClasses()) + for (Method method : cf.getMethods().getMethods()) + { + if (method.getName().length() > 2) + continue; + + List virtualMethods = getVirutalMethods(method); + assert !virtualMethods.isEmpty(); + if (virtualMethods.size() != 1) + continue; // do next + + renameMethod(group, method, "method" + i++); + ++methods; + } System.out.println("Uniquely renamed " + classes + " classes, " + fields + " fields, and " + methods + " methods"); } diff --git a/src/main/java/info/sigterm/deob/deobfuscators/UnusedFields.java b/src/main/java/info/sigterm/deob/deobfuscators/UnusedFields.java index ce820aa03c..11a0c33571 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/UnusedFields.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/UnusedFields.java @@ -37,7 +37,7 @@ public class UnusedFields implements Deobfuscator if (clazz == null) continue; - Field f = clazz.findField(ff.getNameAndType()); + Field f = clazz.findFieldDeep(ff.getNameAndType()); if (field == f) { diff --git a/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java b/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java index b223dc3157..546eb98a31 100644 --- a/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java +++ b/src/main/java/info/sigterm/deob/deobfuscators/UnusedParameters.java @@ -34,7 +34,7 @@ public class UnusedParameters implements Deobfuscator visited.add(cf); - Method method = cf.findMethod(nat); // XXX this searches down + Method method = cf.findMethodDeep(nat); // XXX this searches down if (method != null && !method.isStatic()) list.add(method);