From 406d9878d80b5d1379bcfe82d2e6e85c6aac8746 Mon Sep 17 00:00:00 2001 From: Skylot Date: Sun, 26 Apr 2015 15:03:23 +0300 Subject: [PATCH] core: fix invoke args skipping --- .../main/java/jadx/core/codegen/InsnGen.java | 14 ++-- .../jadx/core/dex/attributes/AttrNode.java | 7 +- .../core/dex/attributes/AttributeStorage.java | 4 ++ .../core/dex/attributes/EmptyAttrStorage.java | 5 ++ .../dex/instructions/args/RegisterArg.java | 1 + .../core/dex/instructions/args/Typed.java | 3 +- .../jadx/core/dex/visitors/ModVisitor.java | 2 +- .../inner/TestAnonymousClass11.java | 64 +++++++++++++++++++ 8 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/inner/TestAnonymousClass11.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 5dc568e29..4de5cac7b 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -29,7 +29,6 @@ import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.Named; import jadx.core.dex.instructions.args.RegisterArg; -import jadx.core.dex.instructions.args.SSAVar; import jadx.core.dex.instructions.mods.ConstructorInsn; import jadx.core.dex.instructions.mods.TernaryInsn; import jadx.core.dex.nodes.ClassNode; @@ -645,20 +644,17 @@ public class InsnGen { boolean overloaded = callMth != null && callMth.isArgsOverload(); for (int i = k; i < argsCount; i++) { InsnArg arg = insn.getArg(i); - if (arg.isRegister()) { - SSAVar sVar = ((RegisterArg) arg).getSVar(); - if (sVar != null && sVar.contains(AFlag.SKIP_ARG)) { - continue; - } + if (arg.contains(AFlag.SKIP_ARG)) { + continue; + } + if (i != k) { + code.add(", "); } boolean cast = overloaded && processOverloadedArg(code, callMth, arg, i - startArgNum); if (!cast && i == argsCount - 1 && processVarArg(code, callMth, arg)) { continue; } addArg(code, arg, false); - if (i < argsCount - 1) { - code.add(", "); - } } } code.add(')'); diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java index ff298a827..2cf100908 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java @@ -27,10 +27,13 @@ public abstract class AttrNode implements IAttributeNode { @Override public void copyAttributesFrom(AttrNode attrNode) { - initStorage().addAll(attrNode.storage); + AttributeStorage copyFrom = attrNode.storage; + if (!copyFrom.isEmpty()) { + initStorage().addAll(copyFrom); + } } - AttributeStorage initStorage() { + private AttributeStorage initStorage() { AttributeStorage store = storage; if (store == EMPTY_ATTR_STORAGE) { store = new AttributeStorage(); diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java index d7b82f2c1..2b3595814 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java @@ -111,6 +111,10 @@ public class AttributeStorage { return list; } + public boolean isEmpty() { + return flags.isEmpty() && attributes.isEmpty(); + } + @Override public String toString() { List list = getAttributeStrings(); diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/EmptyAttrStorage.java b/jadx-core/src/main/java/jadx/core/dex/attributes/EmptyAttrStorage.java index 364db9b78..2e1125fe3 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/EmptyAttrStorage.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/EmptyAttrStorage.java @@ -53,6 +53,11 @@ public final class EmptyAttrStorage extends AttributeStorage { return Collections.emptyList(); } + @Override + public boolean isEmpty() { + return true; + } + @Override public String toString() { return ""; diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java index 3f5cf0d51..1b9695be7 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java @@ -79,6 +79,7 @@ public class RegisterArg extends InsnArg implements Named { public RegisterArg duplicate() { RegisterArg dup = new RegisterArg(getRegNum(), getType()); dup.setSVar(sVar); + dup.copyAttributesFrom(this); return dup; } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java index 08447b86c..125d9f540 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java @@ -1,8 +1,9 @@ package jadx.core.dex.instructions.args; +import jadx.core.dex.attributes.AttrNode; import jadx.core.dex.nodes.DexNode; -public abstract class Typed { +public abstract class Typed extends AttrNode { protected ArgType type; 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 e508ba59a..6decea5fe 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 @@ -277,8 +277,8 @@ public class ModVisitor extends AbstractVisitor { if (sVar != null) { sVar.add(AFlag.FINAL); sVar.add(AFlag.DONT_INLINE); - sVar.add(AFlag.SKIP_ARG); } + reg.add(AFlag.SKIP_ARG); } } } diff --git a/jadx-core/src/test/java/jadx/tests/integration/inner/TestAnonymousClass11.java b/jadx-core/src/test/java/jadx/tests/integration/inner/TestAnonymousClass11.java new file mode 100644 index 000000000..91c604f03 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/inner/TestAnonymousClass11.java @@ -0,0 +1,64 @@ +package jadx.tests.integration.inner; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.IntegrationTest; + +import java.util.Random; + +import org.junit.Test; + +import static jadx.tests.api.utils.JadxMatchers.containsOne; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertThat; + +public class TestAnonymousClass11 extends IntegrationTest { + + public static class TestCls { + + public void test() { + final int a = new Random().nextInt(); + final long l = new Random().nextLong(); + func(new A(l) { + @Override + public void m() { + System.out.println(a); + } + }); + System.out.println("a" + a); + print(a); + print2(1, a); + print3(1, l); + } + + public abstract class A { + public A(long l) { + } + + public abstract void m(); + + } + + private void func(A a) { + } + + private void print(int a) { + } + + private void print2(int i, int a) { + } + + private void print3(int i, long l) { + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + + assertThat(code, containsOne("System.out.println(\"a\" + a);")); + assertThat(code, containsOne("print(a);")); + assertThat(code, not(containsString("synthetic"))); + } +}