From 6a1717a6241f5aec3c9d5a18b539fccea12f1a9d Mon Sep 17 00:00:00 2001 From: Skylot Date: Sat, 15 Dec 2018 17:45:37 +0300 Subject: [PATCH] fix: use original call class for invoke inherited methods (#413) --- .../main/java/jadx/core/codegen/InsnGen.java | 20 +++++++---- .../dex/visitors/DependencyCollector.java | 4 +++ .../java/jadx/core/utils/CodegenUtils.java | 2 +- .../invoke/TestInheritedStaticInvoke.java | 36 +++++++++++++++++++ 4 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/invoke/TestInheritedStaticInvoke.java diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 516d1cf9d..b54d0291c 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -602,11 +602,8 @@ public class InsnGen { // inline method MethodNode callMthNode = mth.root().deepResolveMethod(callMth); - if (callMthNode != null) { - if (inlineMethod(callMthNode, insn, code)) { - return; - } - callMth = callMthNode.getMethodInfo(); + if (callMthNode != null && inlineMethod(callMthNode, insn, code)) { + return; } int k = 0; @@ -640,8 +637,10 @@ public class InsnGen { } if (callMthNode != null) { code.attachAnnotation(callMthNode); + code.add(callMthNode.getAlias()); + } else { + code.add(callMth.getAlias()); } - code.add(callMth.getAlias()); generateMethodArguments(code, insn, k, callMthNode); } @@ -694,7 +693,14 @@ public class InsnGen { * Add additional cast for overloaded method argument. */ private boolean processOverloadedArg(CodeWriter code, MethodNode callMth, InsnArg arg, int origPos) { - ArgType origType = callMth.getArguments(false).get(origPos).getInitType(); + ArgType origType; + List arguments = callMth.getArguments(false); + if (arguments.isEmpty()) { + mth.addComment("JADX WARN: used method not loaded: " + callMth + ", types can be incorrect"); + origType = callMth.getMethodInfo().getArgumentsTypes().get(origPos); + } else { + origType = arguments.get(origPos).getInitType(); + } if (!arg.getType().equals(origType)) { code.add('('); useType(code, origType); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java b/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java index 558ef3fb4..92cffd845 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java @@ -11,6 +11,7 @@ import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.RegisterArg; +import jadx.core.dex.instructions.mods.ConstructorInsn; import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.DexNode; @@ -90,6 +91,9 @@ public class DependencyCollector extends AbstractVisitor { } else if (insn instanceof InvokeNode) { ClassInfo declClass = ((InvokeNode) insn).getCallMth().getDeclClass(); addDep(dex, depList, declClass); + } else if (insn instanceof ConstructorInsn) { + ClassInfo declClass = ((ConstructorInsn) insn).getCallMth().getDeclClass(); + addDep(dex, depList, declClass); } } diff --git a/jadx-core/src/main/java/jadx/core/utils/CodegenUtils.java b/jadx-core/src/main/java/jadx/core/utils/CodegenUtils.java index 68647637c..7d588d987 100644 --- a/jadx-core/src/main/java/jadx/core/utils/CodegenUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/CodegenUtils.java @@ -8,7 +8,7 @@ public class CodegenUtils { public static void addComments(CodeWriter code, AttrNode node) { for (String comment : node.getAll(AType.COMMENTS)) { - code.startLine("/* ").add(comment).add(" */"); + code.startLine("/* ").addMultiLine(comment).add(" */"); } } } diff --git a/jadx-core/src/test/java/jadx/tests/integration/invoke/TestInheritedStaticInvoke.java b/jadx-core/src/test/java/jadx/tests/integration/invoke/TestInheritedStaticInvoke.java new file mode 100644 index 000000000..7f677e6d9 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/invoke/TestInheritedStaticInvoke.java @@ -0,0 +1,36 @@ +package jadx.tests.integration.invoke; + +import org.junit.Test; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.IntegrationTest; + +import static jadx.tests.api.utils.JadxMatchers.containsOne; +import static org.junit.Assert.assertThat; + +public class TestInheritedStaticInvoke extends IntegrationTest { + + public static class TestCls { + public static class A { + public static int a() { + return 1; + } + } + + public static class B extends A { + } + + public int test() { + return B.a(); // not A.a() + } + } + + @Test + public void test() { + noDebugInfo(); + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + + assertThat(code, containsOne("return B.a();")); + } +}