From 2478fc3a1b3e405dd2c5c0de9717b6ec72e7fc95 Mon Sep 17 00:00:00 2001 From: Anton Dyachenko Date: Tue, 2 Sep 2014 19:55:26 +0400 Subject: [PATCH] core: fix instance initializer producing (don't generate super() call) --- .../java/jadx/core/dex/nodes/ClassNode.java | 5 +- .../java/jadx/core/dex/nodes/MethodNode.java | 25 +++++ .../jadx/core/dex/visitors/ModVisitor.java | 6 + .../java/jadx/samples/TestInitializers.java | 104 ++++++++++++++++++ 4 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 jadx-samples/src/main/java/jadx/samples/TestInitializers.java diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index 9c70ac94f..8e9b15333 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -377,10 +377,7 @@ public class ClassNode extends LineAttrNode implements ILoadable { public MethodNode getDefaultConstructor() { for (MethodNode mth : methods) { - if (mth.getAccessFlags().isConstructor() - && mth.getMethodInfo().isConstructor() - && (mth.getMethodInfo().getArgsCount() == 0 - || (mth.getArguments(false) != null && mth.getArguments(false).isEmpty()))) { + if (mth.isDefaultConstructor()) { return mth; } } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java index 2688347f1..b393422cc 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java @@ -461,6 +461,31 @@ public class MethodNode extends LineAttrNode implements ILoadable { } return false; } + + public boolean isDefaultConstructor() { + boolean result = false; + + if (accFlags.isConstructor() && mthInfo.isConstructor()) { + int defaultArgCount = 0; + + /** workaround for non-static inner class constructor, that has + * synthetic argument */ + if ((parentClass != null) && parentClass.getClassInfo().isInner()) { + if (!parentClass.getAccessFlags().isStatic()) { + ClassNode outerCls = parentClass.getParentClass(); + if ((argsList != null) && (argsList.size() >= 1)) { + if (argsList.get(0).getType().equals(outerCls.getClassInfo().getType())) { + defaultArgCount = 1; + } + } + } + } + + result = (argsList == null) || (argsList.size() == defaultArgCount); + } + + return result; + } public int getRegsCount() { return regsCount; diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java index 7e9126385..dfa5be1ea 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java @@ -76,6 +76,12 @@ public class ModVisitor extends AbstractVisitor { remove = true; } } + + // remove super() call in instance initializer + if (parentClass.isAnonymous() && mth.isDefaultConstructor() && co.isSuper()) { + remove = true; + } + if (remove) { remover.add(insn); } else { diff --git a/jadx-samples/src/main/java/jadx/samples/TestInitializers.java b/jadx-samples/src/main/java/jadx/samples/TestInitializers.java new file mode 100644 index 000000000..660814c00 --- /dev/null +++ b/jadx-samples/src/main/java/jadx/samples/TestInitializers.java @@ -0,0 +1,104 @@ +package jadx.samples; + +public class TestInitializers extends AbstractTest { + + private static String a; + private static int counter; + private A c_a; + + public static class A { + public static String a; + + static { + a = "a1"; + } + + public boolean z() { + return true; + } + } + + public class B { + private int b; + private int bbb; + + public B() { + if (c_a.z()) { + b = -1; + } else { + b = 1; + } + } + + public B(int _b) { + b = _b; + } + + public void setB(int _b) { + b = _b; + } + + public int getB() { + return b; + } + + public int getBBB() { + return bbb; + } + + { + bbb = 123; + } + } + + static { + a = "a0"; + counter = 0; + } + + { + c_a = new A(); + } + + @Override + public boolean testRun() throws Exception { + assertTrue(counter == 0); + assertTrue(a.equals("a0")); + assertTrue(A.a.equals("a1")); + + B b1 = new B() { + { + TestInitializers.counter++; + setB(TestInitializers.counter); + } + }; + assertTrue(b1.getB() == 1); + + B b2 = new B() { + @SuppressWarnings("unused") + private int bb; + + public int getB() { + return super.getB(); + } + + { + bb = 100; + } + }; + assertTrue(b2.getB() == -1); + + assertTrue((new B()).getB() == -1); + assertTrue(counter == 1); + + B b3 = new B(3); + assertTrue((b3.getB() == 3) && (b3.getBBB() == 123)); + + return true; + } + + public static void main(String[] args) throws Exception { + new TestInitializers().testRun(); + } + +}