From 72fac36a5c6742eb2e6769a1f51b90ee89907c27 Mon Sep 17 00:00:00 2001
From: amosshi byte
type.
*/
@@ -39,60 +39,60 @@ public class PosDataInputStream extends DataInputStream implements DataInputEx {
/**
* Shift Operators, offset with 8.
*/
- private static final int SHIFT_8 = 8;
+ protected static final int SHIFT_8 = 8;
/**
* Shift Operators, offset with 16.
*/
- private static final int SHIFT_16 = 16;
+ protected static final int SHIFT_16 = 16;
/**
* Shift Operators, offset with 24.
*/
- private static final int SHIFT_24 = 24;
+ protected static final int SHIFT_24 = 24;
/**
* Shift Operators, offset with 32.
*/
- private static final int SHIFT_32 = 32;
+ protected static final int SHIFT_32 = 32;
/**
* Shift Operators, offset with 40.
*/
- private static final int SHIFT_40 = 40;
+ protected static final int SHIFT_40 = 40;
/**
* Shift Operators, offset with 48.
*/
- private static final int SHIFT_48 = 48;
+ protected static final int SHIFT_48 = 48;
/**
* Shift Operators, offset with 56.
*/
- private static final int SHIFT_56 = 56;
+ protected static final int SHIFT_56 = 56;
/**
* Half Byte length: 4.
*/
- private static final int BYTE_LENGTH_4 = 4;
+ protected static final int BYTE_LENGTH_4 = 4;
/**
* Full Byte length: 8.
*/
- private static final int BYTE_LENGTH_8 = 8;
+ protected static final int BYTE_LENGTH_8 = 8;
/** Byte offset 0. */
- private static final int BYTE_OFFSET_0 = 0;
+ protected static final int BYTE_OFFSET_0 = 0;
/** Byte offset 1. */
- private static final int BYTE_OFFSET_1 = 1;
+ protected static final int BYTE_OFFSET_1 = 1;
/** Byte offset 2. */
- private static final int BYTE_OFFSET_2 = 2;
+ protected static final int BYTE_OFFSET_2 = 2;
/** Byte offset 3. */
- private static final int BYTE_OFFSET_3 = 3;
+ protected static final int BYTE_OFFSET_3 = 3;
/** Byte offset 4. */
- private static final int BYTE_OFFSET_4 = 4;
+ protected static final int BYTE_OFFSET_4 = 4;
/** Byte offset 5. */
- private static final int BYTE_OFFSET_5 = 5;
+ protected static final int BYTE_OFFSET_5 = 5;
/** Byte offset 6. */
- private static final int BYTE_OFFSET_6 = 6;
+ protected static final int BYTE_OFFSET_6 = 6;
/** Byte offset 7. */
- private static final int BYTE_OFFSET_7 = 7;
+ protected static final int BYTE_OFFSET_7 = 7;
/**
* Byte max value: 255.
*/
- private static final int BYTE_MAX_255 = 255;
+ protected static final int BYTE_MAX_255 = 255;
/**
* New line character: LINE FEED (LF).
diff --git a/CommonLib/src/main/java/org/freeinternals/commonlib/ui/UITool.java b/CommonLib/src/main/java/org/freeinternals/commonlib/ui/UITool.java
index cb3d300..fefc241 100644
--- a/CommonLib/src/main/java/org/freeinternals/commonlib/ui/UITool.java
+++ b/CommonLib/src/main/java/org/freeinternals/commonlib/ui/UITool.java
@@ -33,7 +33,7 @@ public final class UITool {
*
* @see #left(String)
*/
- public static final int TREENODE_STRING_MAXLEN = 30;
+ public static final int TREENODE_STRING_MAXLEN = 64;
private UITool() {
}
diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/DexFile.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/DexFile.java
index 2bb6c8e..344ab84 100644
--- a/FormatDEX/src/main/java/org/freeinternals/format/dex/DexFile.java
+++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/DexFile.java
@@ -10,9 +10,6 @@
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
@@ -65,8 +62,10 @@ public final class DexFile extends FileFormat {
* monotonically over time as the format evolves.
*
* java:S100 - Method names should comply with a naming convention --- We use different naming convention for better readablity + * java:S1110 - Redundant parenthesis --- Redundant parenthesis is needed for readability **/ -@SuppressWarnings("java:S100") +@SuppressWarnings({"java:S100", "java:S1110"}) public class PosDataInputStreamDex extends PosDataInputStream { + /** + * Full Byte length: 3. + */ + private static final int BYTE_LENGTH_3 = 3; + private static final int BYTE_LENGTH_5 = 5; + private static final int BYTE_LENGTH_6 = 6; + private static final int BYTE_LENGTH_7 = 7; + + /** + * Byte position: 6. + */ + private static final int BYTE_POSITION_5 = 5; + /** * Endian of the {@link DexFile}. The default value is little-endian * {@link header_item.Endian#ENDIAN_CONSTANT}, as the DEX format @@ -102,6 +117,20 @@ public Type_int Dex_int() throws IOException { } } + /** + * Read a 3-byte {@link Type_int} from the input stream. + * + * @return a {@link Type_int} + * @throws IOException I/O Error + */ + public Type_int Dex_int3() throws IOException { + if (this.endian == header_item.Endian.ENDIAN_CONSTANT) { + return new Type_int(this.readInt3()); + } else { + return new Type_int(this.readInt3InLittleEndian()); + } + } + /** * Read a {@link Type_uint} from the input stream. * @@ -116,6 +145,20 @@ public Type_uint Dex_uint() throws IOException { } } + /** + * Read a {@link Type_uint} from the input stream for only 3 bytes. + * + * @return a {@link Type_uint} + * @throws IOException I/O Error + */ + public Type_uint Dex_uint3() throws IOException { + if (this.endian.value == header_item.Endian.ENDIAN_CONSTANT.value) { + return new Type_uint(this.readUnsignedInt3()); + } else { + return new Type_uint(this.readUnsignedInt3InLittleEndian()); + } + } + /** * Read a {@link Type_long} from the input stream. * @@ -130,6 +173,39 @@ public Type_long Dex_long() throws IOException { } } + /** + * Read a 5/6/7-byte {@link Type_long} from the input stream. + * + * @param length Dynamic long length value: 5, 6, or 7 + * @return a {@link Type_long} + * @throws IOException I/O Error + */ + public Type_long Dex_long(int length) throws IOException { + if (this.endian == header_item.Endian.ENDIAN_CONSTANT) { + switch (length) { + case 5: + return new Type_long(this.readLong5()); + case 6: + return new Type_long(this.readLong6()); + case 7: + return new Type_long(this.readLong7()); + default: + } + } else { + switch (length) { + case 5: + return new Type_long(this.readLong5InLittleEndian()); + case 6: + return new Type_long(this.readLong6InLittleEndian()); + case 7: + return new Type_long(this.readLong7InLittleEndian()); + default: + } + } + + throw new IllegalArgumentException(String.format("Unexpected long value length: %d", length)); + } + /** * Read a {@link Type_ulong} from the input stream. * @@ -213,4 +289,178 @@ public Type_uleb128p1 Dex_uleb128p1() throws IOException, FileFormatException { Type_uleb128 uleb128 = this.Dex_uleb128(); return new Type_uleb128p1(uleb128.value - 1, uleb128.length); } + + /** + * Read 3-byte int. + */ + private int readInt3() throws IOException { + int ch1 = this.in.read(); + int ch2 = this.in.read(); + int ch3 = this.in.read(); + if ((ch1 | ch2 | ch3) < 0) { + throw new EOFException(); + } + + if ((ch3 & 0x80) > 0) { + System.out.println("TODO verify - 3-byte int test case at 0x" + Integer.toHexString(this.getPos()) + " ----------------------- readInt3 ----"); + return 0xFF000000 | (ch1 << SHIFT_16) | (ch2 << SHIFT_8) | (ch3); + } else { + return (ch1 << SHIFT_16) | (ch2 << SHIFT_8) | (ch3); + } + } + + /** + * Read 3-byte int in little-endian. + */ + private int readInt3InLittleEndian() throws IOException { + int ch1 = this.in.read(); + int ch2 = this.in.read(); + int ch3 = this.in.read(); + if ((ch1 | ch2 | ch3) < 0) { + throw new EOFException(); + } + + if ((ch3 & 0x80) > 0) { + // System.out.println("TODO verify via Java source code via minus value - 3-byte int test case at 0x" + Integer.toHexString(this.getPos()) + " ----------------------- readIntInLittleEndian3 ----"); + return 0xFF000000 | (ch3 << SHIFT_16) | (ch2 << SHIFT_8) | (ch1); + } else { + return (ch3 << SHIFT_16) | (ch2 << SHIFT_8) | (ch1); + } + } + + private long readLong5() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + super.readFully(readBuffer, 3, BYTE_LENGTH_5); + + // TODO + return (((long) readBuffer[BYTE_OFFSET_7] << SHIFT_56) + | ((long) (readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_48) + | ((long) (readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_40) + | ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_32) + | ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_24) + | ((readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_16) + | ((readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_8) + | ((readBuffer[BYTE_OFFSET_0] & BYTE_MAX_255))); + } + private long readLong5InLittleEndian() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + super.readFully(readBuffer, 3, BYTE_LENGTH_5); + + // TODO + return (((long) readBuffer[BYTE_OFFSET_7] << SHIFT_56) + | ((long) (readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_48) + | ((long) (readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_40) + | ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_32) + | ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_24) + | ((readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_16) + | ((readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_8) + | ((readBuffer[BYTE_OFFSET_0] & BYTE_MAX_255))); + } + + private long readLong6() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + super.readFully(readBuffer, 2, BYTE_LENGTH_6); + + // TODO + return (((long) readBuffer[BYTE_OFFSET_7] << SHIFT_56) + | ((long) (readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_48) + | ((long) (readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_40) + | ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_32) + | ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_24) + | ((readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_16) + | ((readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_8) + | ((readBuffer[BYTE_OFFSET_0] & BYTE_MAX_255))); + } + private long readLong6InLittleEndian() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + super.readFully(readBuffer, 2, BYTE_LENGTH_6); + + // TODO + return (((long) readBuffer[BYTE_OFFSET_7] << SHIFT_56) + | ((long) (readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_48) + | ((long) (readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_40) + | ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_32) + | ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_24) + | ((readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_16) + | ((readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_8) + | ((readBuffer[BYTE_OFFSET_0] & BYTE_MAX_255))); + } + + private long readLong7() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + super.readFully(readBuffer, 1, BYTE_LENGTH_7); + + // TODO + return (((long) readBuffer[BYTE_OFFSET_7] << SHIFT_56) + | ((long) (readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_48) + | ((long) (readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_40) + | ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_32) + | ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_24) + | ((readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_16) + | ((readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_8) + | ((readBuffer[BYTE_OFFSET_0] & BYTE_MAX_255))); + } + private long readLong7InLittleEndian() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + super.readFully(readBuffer, 1, BYTE_LENGTH_7); + + // TODO + return (((long) readBuffer[BYTE_OFFSET_7] << SHIFT_56) + | ((long) (readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_48) + | ((long) (readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_40) + | ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_32) + | ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_24) + | ((readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_16) + | ((readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_8) + | ((readBuffer[BYTE_OFFSET_0] & BYTE_MAX_255))); + } + + /** + * Read 3-byte unsigned int. + */ + private long readUnsignedInt3() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + + super.readFully(readBuffer, BYTE_POSITION_5, BYTE_LENGTH_3); + readBuffer[BYTE_OFFSET_0] = 0; + readBuffer[BYTE_OFFSET_1] = 0; + readBuffer[BYTE_OFFSET_2] = 0; + readBuffer[BYTE_OFFSET_3] = 0; + readBuffer[BYTE_OFFSET_4] = 0; + + return (((long) readBuffer[BYTE_OFFSET_0] << SHIFT_56) + + ((long) (readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_48) + + ((long) (readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_40) + + ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_32) + + ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_24) + + ((readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_16) + + ((readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_8) + + ((readBuffer[BYTE_OFFSET_7] & BYTE_MAX_255))); + } + + /** + * Read 3-byte unsigned int in little-endian. + */ + private long readUnsignedInt3InLittleEndian() throws IOException { + final byte[] readBuffer = new byte[BYTE_LENGTH_8]; + + super.readFully(readBuffer, 0, BYTE_LENGTH_3); + readBuffer[BYTE_OFFSET_7] = readBuffer[BYTE_OFFSET_0]; + readBuffer[BYTE_OFFSET_6] = readBuffer[BYTE_OFFSET_1]; + readBuffer[BYTE_OFFSET_5] = readBuffer[BYTE_OFFSET_2]; + readBuffer[BYTE_OFFSET_4] = 0; + readBuffer[BYTE_OFFSET_3] = 0; + readBuffer[BYTE_OFFSET_2] = 0; + readBuffer[BYTE_OFFSET_1] = 0; + readBuffer[BYTE_OFFSET_0] = 0; + + return (((long) readBuffer[BYTE_OFFSET_0] << SHIFT_56) + + ((long) (readBuffer[BYTE_OFFSET_1] & BYTE_MAX_255) << SHIFT_48) + + ((long) (readBuffer[BYTE_OFFSET_2] & BYTE_MAX_255) << SHIFT_40) + + ((long) (readBuffer[BYTE_OFFSET_3] & BYTE_MAX_255) << SHIFT_32) + + ((long) (readBuffer[BYTE_OFFSET_4] & BYTE_MAX_255) << SHIFT_24) + + ((readBuffer[BYTE_OFFSET_5] & BYTE_MAX_255) << SHIFT_16) + + ((readBuffer[BYTE_OFFSET_6] & BYTE_MAX_255) << SHIFT_8) + + ((readBuffer[BYTE_OFFSET_7] & BYTE_MAX_255))); + } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/annotation_set_ref_list.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/annotation_set_ref_list.java index df3fa83..0f47533 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/annotation_set_ref_list.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/annotation_set_ref_list.java @@ -89,8 +89,12 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) UITool.icon4Offset() ); + if (refItem.annotations_off.value == 0) { + continue; + } + FileComponent fc = dexFile.data.get(refItem.annotations_off.value); - //annotation_set_item item = (annotation_set_item) + //annotation_set_item item = (annotation_set_item) DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( fc.getStartPos(), fc.getLength(), @@ -100,7 +104,7 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) )); refItemNode.add(itemNode); if (fc instanceof GenerateTreeNodeDexFile) { - ((GenerateTreeNodeDexFile)fc).generateTreeNode(itemNode, dexFile); + ((GenerateTreeNodeDexFile) fc).generateTreeNode(itemNode, dexFile); } } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_annotation.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_annotation.java index ada48c2..f21358f 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_annotation.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_annotation.java @@ -139,9 +139,10 @@ public static class annotation_element extends FileComponent implements Generate super.startPos = stream.getPos(); this.name_idx = stream.Dex_uleb128(); - try { // Dev phase only + try { // TODO Dev phase only this.value = new encoded_value(stream); } catch (FileFormatException e) { + // This should never happen LOGGER.log(Level.SEVERE, e.getMessage(), e); } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_array.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_array.java index 62a0a28..f22af3c 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_array.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_array.java @@ -7,6 +7,8 @@ package org.freeinternals.format.dex; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.tree.DefaultMutableTreeNode; import org.freeinternals.commonlib.core.FileComponent; import org.freeinternals.commonlib.core.FileFormatException; @@ -27,6 +29,7 @@ @SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) public class encoded_array extends FileComponent implements GenerateTreeNodeDexFile { + private static final Logger LOGGER = Logger.getLogger(encoded_array.class.getName()); public final Type_uleb128 size; public final encoded_value[] values; @@ -36,7 +39,12 @@ public class encoded_array extends FileComponent implements GenerateTreeNodeDexF if (this.size.value > 0) { this.values = new encoded_value[this.size.value]; for (int i = 0; i < this.size.value; i++) { - this.values[i] = new encoded_value(stream); + try { + this.values[i] = new encoded_value(stream); + } catch (FileFormatException e) { + // This should never happen + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } } } else { this.values = null; @@ -74,16 +82,21 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) for (int i = 0; i < this.values.length; i++) { encoded_value value = this.values[i]; - DefaultMutableTreeNode valueNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - value.getStartPos(), - value.getLength(), - String.format("%s[%d] %s", value.getClass().getSimpleName(), i, value.toString()), - UITool.icon4Data(), - MESSAGES.getString("msg_encoded_value") - )); + if (value != null) { + DefaultMutableTreeNode valueNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + value.getStartPos(), + value.getLength(), + String.format("%s[%d] %s", value.getClass().getSimpleName(), i, value.toString()), + UITool.icon4Data(), + MESSAGES.getString("msg_encoded_value") + )); - valuesNode.add(valueNode); - value.generateTreeNode(valueNode, dexFile); + valuesNode.add(valueNode); + value.generateTreeNode(valueNode, dexFile); + } else { + // This should never happen + LOGGER.log(Level.SEVERE, "{0} at 0x{1} : value[{2}] is null", new Object[]{this.getClass().getSimpleName(), Integer.toHexString(this.getStartPos()), i}); + } } } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_value.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_value.java index 4fd1ebd..5cf3e9b 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_value.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/encoded_value.java @@ -56,6 +56,12 @@ public class encoded_value extends FileComponent implements GenerateTreeNodeDexF private encoded_annotation union_value_annotation; private Boolean union_value_bollean; + /** + *
+ * java:S3776 - Cognitive Complexity of methods should not be too high --- No, it is not high + *+ */ + @SuppressWarnings({"java:S127", "java:S3776"}) encoded_value(final PosDataInputStreamDex stream) throws IOException, FileFormatException { super.startPos = stream.getPos(); value_arg_and_type = stream.Dex_ubyte(); @@ -84,21 +90,12 @@ public class encoded_value extends FileComponent implements GenerateTreeNodeDexF this.union_value_int = this.read_int(stream, this.value_arg); break; case VALUE_LONG: - if (this.value_arg != 7) { - System.out.println(this.getClass().getSimpleName() + " VALUE_LONG value_arg is not 7 but " + this.value_arg + " - to test"); - } - this.union_value_long = this.read_long(stream, length); + this.union_value_long = this.read_long(stream, this.value_arg); break; case VALUE_FLOAT: - if (this.value_arg != 3) { - System.out.println(this.getClass().getSimpleName() + " VALUE_FLOAT value_arg is not 3 but " + this.value_arg + " - to test"); - } this.union_value_float = this.read_float(stream, this.value_arg); break; case VALUE_DOUBLE: - if (this.value_arg != 7) { - System.out.println(this.getClass().getSimpleName() + " VALUE_DOUBLE value_arg is not 7 but " + this.value_arg + " - to test"); - } this.union_value_double = this.read_double(stream, this.value_arg); break; case VALUE_METHOD_TYPE: @@ -220,22 +217,22 @@ private Type_long read_long(final PosDataInputStreamDex stream, final int arg) t result = new Type_long(stream.Dex_short().value); break; + case 2: + result = new Type_long(stream.Dex_int3().value); + if (result.value < 0) { + System.out.println(this.getClass().getSimpleName() + String.format(" : read_long for triple bytes (minus value) at 0x%X ======= to verify =======", stream.getPos()) ); + } + break; + case 3: result = new Type_long(stream.Dex_int().value); break; - case 2: case 4: case 5: case 6: - // TODO - byte[] raw = new byte[arg + 1]; - int rb = stream.read(raw); - System.out.println(this.getClass().getSimpleName() + " Unhandled case encountered for long - TODO implement logic - readbytes=" + rb); - if (rb != arg + 1) { - throw new IOException(String.format("Cannot read enough bytes for long. expected=%d readbytes=%d", arg + 1, rb)); - } - result = new Type_long(5); + System.out.println(this.getClass().getSimpleName() + " : read_long for bytes 5/6/7 at 0x" + Integer.toHexString(stream.getPos()).toUpperCase() + " ======= to verify ======="); + result = stream.Dex_long(arg + 1); break; case 7: @@ -256,6 +253,10 @@ private Type_long read_long(final PosDataInputStreamDex stream, final int arg) t private Float read_float(final PosDataInputStreamDex stream, final int arg) throws IOException{ Float result = Float.MIN_VALUE; // TODO convert the bytes to float + if (arg != 3) { + System.out.println(this.getClass().getSimpleName() + " VALUE_FLOAT value_arg is not 3 but " + this.value_arg + " at 0x" + Integer.toHexString(stream.getPos()) + " - to implment"); + } + byte[] raw = new byte[arg + 1]; int rb = stream.read(raw); if (rb != arg + 1) { @@ -264,10 +265,14 @@ private Float read_float(final PosDataInputStreamDex stream, final int arg) thro return result; } - + private Double read_double(final PosDataInputStreamDex stream, final int arg) throws IOException{ Double result = Double.MAX_VALUE; // TODO convert the bytes to double + if (arg != 7) { + System.out.println(this.getClass().getSimpleName() + " VALUE_DOUBLE value_arg is not 7 but " + this.value_arg + " at 0x" + Integer.toHexString(stream.getPos()) + " - to implment"); + } + byte[] raw = new byte[arg + 1]; int rb = stream.read(raw); if (rb != arg + 1) { @@ -328,14 +333,7 @@ private Type_int read_int(final PosDataInputStreamDex stream, final int arg) thr result = new Type_int(stream.Dex_short().value); break; case 2: - // TODO - byte[] raw = new byte[arg + 1]; - int rb = stream.read(raw); - System.out.println(this.getClass().getSimpleName() + " Unhandled case encountered: triple bytes int - TODO implement logic - readbytes=" + rb); - if (rb != arg + 1) { - throw new IOException(String.format("Cannot read enough bytes for float. expected=%d readbytes=%d", arg + 1, rb)); - } - result = new Type_int(3); + result = stream.Dex_int3(); break; case 3: result = stream.Dex_int(); @@ -361,14 +359,7 @@ private Type_uint read_uint(final PosDataInputStreamDex stream, final int arg) t result = new Type_uint(stream.Dex_ushort().value); break; case 2: - // todo - byte[] raw = new byte[arg + 1]; - int rb = stream.read(raw); - System.out.println(this.getClass().getSimpleName() + " Unhandled case encountered: triple bytes uint - TODO implement logic - readbytes=" + rb); - if (rb != arg + 1) { - throw new IOException(String.format("Cannot read enough bytes for float. expected=%d readbytes=%d", arg + 1, rb)); - } - result = new Type_uint(2); + result = stream.Dex_uint3(); break; case 3: result = stream.Dex_uint(); diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/header_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/header_item.java index 64eff11..5ae1e11 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/header_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/header_item.java @@ -119,7 +119,7 @@ public class header_item extends FileComponent implements GenerateTreeNode { this.data_size = stream.Dex_uint(); this.data_off = stream.Dex_uint(); - super.length = this.header_size.intValue() - DexFile.DEX_FILE_MAGIC1.size() - DexFile.DEX_FILE_MAGIC2.size(); + super.length = this.header_size.intValue() - DexFile.DEX_FILE_MAGIC1.length - DexFile.DEX_FILE_MAGIC2.length; } @Override