diff --git a/src/main/java/info/sigterm/deob/ClassFile.java b/src/main/java/info/sigterm/deob/ClassFile.java index 8c1ed6d51d..5dcd60704d 100644 --- a/src/main/java/info/sigterm/deob/ClassFile.java +++ b/src/main/java/info/sigterm/deob/ClassFile.java @@ -185,11 +185,6 @@ public class ClassFile methods.buildInstructionGraph(); } - public void buildCallGraph() - { - methods.buildCallGraph(); - } - public boolean instanceOf(ClassFile other) { return this == other || interfaces.instanceOf(other) || (getParent() != null && getParent().instanceOf(other)); diff --git a/src/main/java/info/sigterm/deob/Method.java b/src/main/java/info/sigterm/deob/Method.java index ea48656a03..462ee6ee65 100644 --- a/src/main/java/info/sigterm/deob/Method.java +++ b/src/main/java/info/sigterm/deob/Method.java @@ -222,14 +222,6 @@ public class Method code.buildInstructionGraph(); } - public void buildCallGraph() - { - Code code = getCode(); - - if (code != null) - code.buildCallGraph(); - } - public void clearCallGraph() { callsTo.clear(); diff --git a/src/main/java/info/sigterm/deob/Methods.java b/src/main/java/info/sigterm/deob/Methods.java index c2de700b95..b9f9856d32 100644 --- a/src/main/java/info/sigterm/deob/Methods.java +++ b/src/main/java/info/sigterm/deob/Methods.java @@ -79,10 +79,4 @@ public class Methods for (Method m : methods) m.buildInstructionGraph(); } - - public void buildCallGraph() - { - for (Method m : methods) - m.buildCallGraph(); - } } diff --git a/src/main/java/info/sigterm/deob/attributes/Code.java b/src/main/java/info/sigterm/deob/attributes/Code.java index 5bfaa67200..599f18e0c3 100644 --- a/src/main/java/info/sigterm/deob/attributes/Code.java +++ b/src/main/java/info/sigterm/deob/attributes/Code.java @@ -68,9 +68,4 @@ public class Code extends Attribute { instructions.buildInstructionGraph(); } - - public void buildCallGraph() - { - instructions.buildCallGraph(); - } } 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 679bc33172..c52c091707 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instruction.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instruction.java @@ -195,10 +195,6 @@ public abstract class Instruction { } - public void buildCallGraph() - { - } - public abstract void execute(Frame e); /* does this terminate a block? */ 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 63d5103fcd..709c806320 100644 --- a/src/main/java/info/sigterm/deob/attributes/code/Instructions.java +++ b/src/main/java/info/sigterm/deob/attributes/code/Instructions.java @@ -183,12 +183,6 @@ public class Instructions for (Instruction i : instructions) i.buildInstructionGraph(); } - - public void buildCallGraph() - { - for (Instruction i : instructions) - i.buildCallGraph(); - } public Code getCode() { 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 ddb5b998af..5382135bc2 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 @@ -1,6 +1,7 @@ package info.sigterm.deob.attributes.code.instructions; import info.sigterm.deob.ClassFile; +import info.sigterm.deob.ClassGroup; import info.sigterm.deob.attributes.code.Instruction; import info.sigterm.deob.attributes.code.InstructionType; import info.sigterm.deob.attributes.code.Instructions; @@ -74,6 +75,9 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction StackContext object = stack.pop(); ins.pop(object); + // the method being invoked, looked up dynamically based on the type + //info.sigterm.deob.Method executedMethod = findVirtualMethod(object.getType()); + handleExceptions(frame); if (!method.getNameAndType().isVoid()) @@ -87,6 +91,31 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction frame.addInstructionContext(ins); } + private info.sigterm.deob.Method findVirtualMethod(Type type) + { + // 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(); + + ClassFile otherClass = group.findClass(type.type); + if (otherClass == null) + return null; // not our class + + // now find the method with the same signature as 'method' on this class, or subclass + return findMethodFromClass(otherClass); + } + + private info.sigterm.deob.Method findMethodFromClass(ClassFile clazz) + { + if (clazz == null) + return null; + + info.sigterm.deob.Method m = clazz.findMethod(method.getNameAndType()); + if (m != null) + return m; + + return findMethodFromClass(clazz.getParent()); + } + private void handleExceptions(Frame frame) { // jump to instruction handlers that can catch exceptions here @@ -95,6 +124,7 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction Instruction start = e.getStart(), end = e.getEnd(); + // XXX this relies on pc? // [start, end) if (this.getPc() >= start.getPc() && this.getPc() < end.getPc()) {