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 b677bdcb9d92a7865fe9c2ac1e44c2508202d536..4f23e1e22d2625cf46abde3c2d273c6feb8a7bec 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -20,6 +20,7 @@ import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InvokeNode; import jadx.core.dex.instructions.InvokeType; +import jadx.core.dex.instructions.NewArrayNode; import jadx.core.dex.instructions.SwitchNode; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.FieldArg; @@ -341,7 +342,7 @@ public class InsnGen { break; case NEW_ARRAY: { - ArgType arrayType = insn.getResult().getType(); + ArgType arrayType = ((NewArrayNode) insn).getArrayType(); code.add("new "); useType(code, arrayType.getArrayRootElement()); code.add('['); diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java index 58d6cd063be9dd5cb42f46d99421e8fb0a74608e..c6cb7fcd679970688b25583009fac7b5d6945237 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/FilledNewArrayNode.java @@ -3,11 +3,13 @@ package jadx.core.dex.instructions; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.nodes.InsnNode; +import org.jetbrains.annotations.NotNull; + public class FilledNewArrayNode extends InsnNode { private final ArgType elemType; - public FilledNewArrayNode(ArgType elemType, int size) { + public FilledNewArrayNode(@NotNull ArgType elemType, int size) { super(InsnType.FILLED_NEW_ARRAY, size); this.elemType = elemType; } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java index 68ca3da98fac3650b7651ce50c8e013c9e6cc897..91c09cd78adb01c48cc9464ef4b2de69fcb82940 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java @@ -535,8 +535,9 @@ public class InsnDecoder { InsnArg.reg(insn, 0, dex.getType(insn.getIndex()))); case Opcodes.NEW_ARRAY: - return insn(InsnType.NEW_ARRAY, - InsnArg.reg(insn, 0, dex.getType(insn.getIndex())), + ArgType arrType = dex.getType(insn.getIndex()); + return new NewArrayNode(arrType, + InsnArg.reg(insn, 0, arrType), InsnArg.reg(insn, 1, ArgType.INT)); case Opcodes.FILL_ARRAY_DATA: diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/NewArrayNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/NewArrayNode.java new file mode 100644 index 0000000000000000000000000000000000000000..24d34cb6e9ef986da2a9ba1d518253170c6df381 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/NewArrayNode.java @@ -0,0 +1,41 @@ +package jadx.core.dex.instructions; + +import jadx.core.dex.instructions.args.ArgType; +import jadx.core.dex.instructions.args.InsnArg; +import jadx.core.dex.instructions.args.RegisterArg; +import jadx.core.dex.nodes.InsnNode; + +import org.jetbrains.annotations.NotNull; + +public class NewArrayNode extends InsnNode { + + private final ArgType arrType; + + public NewArrayNode(@NotNull ArgType arrType, RegisterArg res, InsnArg size) { + super(InsnType.NEW_ARRAY, 1); + this.arrType = arrType; + setResult(res); + addArg(size); + } + + public ArgType getArrayType() { + return arrType; + } + + @Override + public boolean isSame(InsnNode obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof NewArrayNode) || !super.isSame(obj)) { + return false; + } + NewArrayNode other = (NewArrayNode) obj; + return arrType == other.arrType; + } + + @Override + public String toString() { + return super.toString() + " type: " + arrType; + } +} diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java index 871d4219aa332ea562595be3aed98505cce162f9..1e2c046a8e706e0564ddb0fd384703c868e35e6a 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java @@ -222,7 +222,9 @@ public class ConstInlinerVisitor extends AbstractVisitor { break; case NEW_ARRAY: - litArg.merge(ArgType.INT); + if (litArg == insn.getArg(0)) { + litArg.merge(ArgType.INT); + } break; default: 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 fbd5a961ec38f57ab09f563f7f486621ab5dcee7..aac7a0f2849765eea3b01ba814f3de73debd5ed6 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 @@ -12,6 +12,7 @@ import jadx.core.dex.instructions.FilledNewArrayNode; import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InvokeNode; +import jadx.core.dex.instructions.NewArrayNode; import jadx.core.dex.instructions.SwitchNode; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; @@ -108,7 +109,8 @@ public class ModVisitor extends AbstractVisitor { InsnNode ni = block.getInstructions().get(next); if (ni.getType() == InsnType.FILL_ARRAY) { ni.getResult().merge(insn.getResult()); - ((FillArrayNode) ni).mergeElementType(insn.getResult().getType().getArrayElement()); + ArgType arrType = ((NewArrayNode) insn).getArrayType(); + ((FillArrayNode) ni).mergeElementType(arrType.getArrayElement()); remover.add(insn); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java index 44fd2f1bc6f5929f0c9ab221ed0894c375d967b7..a9f0876ce35cf84c124cac05f119d8f10491b503 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java @@ -9,6 +9,7 @@ import jadx.core.dex.instructions.FilledNewArrayNode; import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InvokeNode; +import jadx.core.dex.instructions.NewArrayNode; import jadx.core.dex.instructions.SwitchNode; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; @@ -70,19 +71,21 @@ public class ReSugarCode extends AbstractVisitor { */ private static InsnNode processNewArray(MethodNode mth, List instructions, int i, InstructionRemover remover) { - InsnNode insn = instructions.get(i); - InsnArg arg = insn.getArg(0); + NewArrayNode newArrayInsn = (NewArrayNode) instructions.get(i); + InsnArg arg = newArrayInsn.getArg(0); if (!arg.isLiteral()) { return null; } int len = (int) ((LiteralArg) arg).getLiteral(); int size = instructions.size(); - if (len <= 0 || i + len >= size || instructions.get(i + len).getType() != InsnType.APUT) { + if (len <= 0 + || i + len >= size + || instructions.get(i + len).getType() != InsnType.APUT) { return null; } - ArgType arrType = insn.getResult().getType(); + ArgType arrType = newArrayInsn.getArrayType(); InsnNode filledArr = new FilledNewArrayNode(arrType.getArrayElement(), len); - filledArr.setResult(insn.getResult()); + filledArr.setResult(newArrayInsn.getResult()); for (int j = 0; j < len; j++) { InsnNode put = instructions.get(i + 1 + j); if (put.getType() != InsnType.APUT) { diff --git a/jadx-core/src/test/java/jadx/tests/integration/arrays/TestArrays3.java b/jadx-core/src/test/java/jadx/tests/integration/arrays/TestArrays3.java new file mode 100644 index 0000000000000000000000000000000000000000..c4a601db82c7f0aaa7b94d5630fba7291dca2cd8 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/arrays/TestArrays3.java @@ -0,0 +1,32 @@ +package jadx.tests.integration.arrays; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.IntegrationTest; + +import org.junit.Test; + +import static jadx.tests.api.utils.JadxMatchers.containsOne; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.assertThat; + +public class TestArrays3 extends IntegrationTest { + public static class TestCls { + + private Object test(byte[] bArr) { + return new Object[]{bArr}; + } + + public void check() { + assertThat(test(new byte[]{1, 2}), instanceOf(Object[].class)); + } + } + + @Test + public void test() { + noDebugInfo(); + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + + assertThat(code, containsOne("return new Object[]{bArr};")); + } +}