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 654f9ace5..88931a2c7 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -569,8 +569,16 @@ public class InsnGen { private void fillArray(CodeWriter code, FillArrayInsn arrayNode) throws CodegenException { code.add("// fill-array-data instruction"); code.startLine(); - List args = arrayNode.getLiteralArgs(arrayNode.getElementType()); InsnArg arrArg = arrayNode.getArg(0); + ArgType arrayType = arrArg.getType(); + ArgType elemType; + if (arrayType.isTypeKnown() && arrayType.isArray()) { + elemType = arrayType.getArrayElement(); + } else { + ArgType elementType = arrayNode.getElementType(); // unknown type + elemType = elementType.selectFirst(); + } + List args = arrayNode.getLiteralArgs(elemType); int len = args.size(); for (int i = 0; i < len; i++) { if (i != 0) { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayData.java b/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayData.java index f24a5066b..ec1693b43 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayData.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayData.java @@ -14,7 +14,7 @@ import jadx.core.utils.exceptions.JadxRuntimeException; public final class FillArrayData extends InsnNode { - private static final ArgType ONE_BYTE_TYPE = ArgType.unknown(PrimitiveType.BOOLEAN, PrimitiveType.BYTE); + private static final ArgType ONE_BYTE_TYPE = ArgType.unknown(PrimitiveType.BYTE, PrimitiveType.BOOLEAN); private static final ArgType TWO_BYTES_TYPE = ArgType.unknown(PrimitiveType.SHORT, PrimitiveType.CHAR); private static final ArgType FOUR_BYTES_TYPE = ArgType.unknown(PrimitiveType.INT, PrimitiveType.FLOAT); private static final ArgType EIGHT_BYTES_TYPE = ArgType.unknown(PrimitiveType.LONG, PrimitiveType.DOUBLE); diff --git a/jadx-core/src/main/java/jadx/core/utils/EncodedValueUtils.java b/jadx-core/src/main/java/jadx/core/utils/EncodedValueUtils.java new file mode 100644 index 000000000..f9595b755 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/utils/EncodedValueUtils.java @@ -0,0 +1,53 @@ +package jadx.core.utils; + +import org.jetbrains.annotations.Nullable; + +import jadx.api.plugins.input.data.annotations.EncodedValue; +import jadx.core.dex.instructions.args.ArgType; +import jadx.core.dex.instructions.args.InsnArg; +import jadx.core.dex.instructions.args.LiteralArg; +import jadx.core.dex.nodes.RootNode; + +public class EncodedValueUtils { + + /** + * Return constant literal from {@code jadx.api.plugins.input.data.annotations.EncodedValue} + * + * @return LiteralArg, String, ArgType or null + */ + @Nullable + public static Object convertToConstValue(RootNode root, EncodedValue encodedValue) { + if (encodedValue == null) { + return null; + } + Object value = encodedValue.getValue(); + switch (encodedValue.getType()) { + case ENCODED_NULL: + return InsnArg.lit(0, ArgType.OBJECT); + case ENCODED_BOOLEAN: + return Boolean.TRUE.equals(value) ? LiteralArg.TRUE : LiteralArg.FALSE; + case ENCODED_BYTE: + return InsnArg.lit((Byte) value, ArgType.BYTE); + case ENCODED_SHORT: + return InsnArg.lit((Short) value, ArgType.SHORT); + case ENCODED_CHAR: + return InsnArg.lit((Character) value, ArgType.CHAR); + case ENCODED_INT: + return InsnArg.lit((Integer) value, ArgType.INT); + case ENCODED_LONG: + return InsnArg.lit((Long) value, ArgType.LONG); + case ENCODED_FLOAT: + return InsnArg.lit(Float.floatToIntBits((Float) value), ArgType.FLOAT); + case ENCODED_DOUBLE: + return InsnArg.lit(Double.doubleToLongBits((Double) value), ArgType.DOUBLE); + case ENCODED_STRING: + return (String) value; + + case ENCODED_TYPE: + return ArgType.parse((String) value); + + default: + return null; + } + } +} diff --git a/jadx-core/src/main/java/jadx/core/utils/InsnUtils.java b/jadx-core/src/main/java/jadx/core/utils/InsnUtils.java index c18ebc50c..69d88de1d 100644 --- a/jadx-core/src/main/java/jadx/core/utils/InsnUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/InsnUtils.java @@ -101,11 +101,8 @@ public class InsnUtils { return null; } FieldInitAttr attr = fieldNode.get(AType.FIELD_INIT); - if (attr != null) { - if (attr.getValueType() == FieldInitAttr.InitType.CONST) { - return attr.getEncodedValue().getValue(); - } - return attr.getInsn(); + if (attr != null && attr.getValueType() == FieldInitAttr.InitType.CONST) { + return EncodedValueUtils.convertToConstValue(root, attr.getEncodedValue()); } return null; diff --git a/jadx-core/src/test/java/jadx/tests/integration/arrays/TestArrayFill4.java b/jadx-core/src/test/java/jadx/tests/integration/arrays/TestArrayFill4.java new file mode 100644 index 000000000..1e19519aa --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/arrays/TestArrayFill4.java @@ -0,0 +1,29 @@ +package jadx.tests.integration.arrays; + +import org.junit.jupiter.api.Test; + +import jadx.tests.api.IntegrationTest; + +import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat; + +public class TestArrayFill4 extends IntegrationTest { + + public static class TestCls { + + // replaced constant break filled array creation + private static final int ARRAY_SIZE = 4; + + public long[] test() { + return new long[] { 0, 1, Long.MAX_VALUE, Long.MIN_VALUE + 1 }; + } + } + + @Test + public void test() { + noDebugInfo(); + assertThat(getClassNode(TestCls.class)) + .code() + .doesNotContain("new long[ARRAY_SIZE];") + .containsOne("return new long[]{0, 1, "); + } +}