diff --git a/BinaryInternalsViewer/src/main/java/org/freeinternals/biv/JDialogPlugins.java b/BinaryInternalsViewer/src/main/java/org/freeinternals/biv/JDialogPlugins.java index 9984d70..3cef8ee 100644 --- a/BinaryInternalsViewer/src/main/java/org/freeinternals/biv/JDialogPlugins.java +++ b/BinaryInternalsViewer/src/main/java/org/freeinternals/biv/JDialogPlugins.java @@ -125,7 +125,7 @@ public static class PluginsModel extends AbstractTableModel { @Override public int getRowCount() { - return this.rowData.size() + 2; + return this.rowData.size() + 1; } @Override 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 fdfd9a1..f1869f0 100644 --- a/CommonLib/src/main/java/org/freeinternals/commonlib/ui/UITool.java +++ b/CommonLib/src/main/java/org/freeinternals/commonlib/ui/UITool.java @@ -28,6 +28,12 @@ public final class UITool { * Size ratio of the pop-up window and its parent. */ public static final float POPUP_RATIO = 0.8f; + /** + * Max length for tree node string. + * + * @see #left(String) + */ + public static final int TREENODE_STRING_MAXLEN = 30; private UITool() { } @@ -59,7 +65,8 @@ public static void generateTreeNodeDiff( diffStr))); } - private static final Map iconCache = new HashMap<>(); + private static final Map iconCache = new HashMap<>(); + private static Icon icon(String url) { return iconCache.computeIfAbsent(url, k -> new ImageIcon(UITool.class.getResource(url))); } @@ -68,27 +75,19 @@ private static Icon icon(String url) { * Icon for binary file. * * @return Icon for binary file - * @see Binary File icon by Icons8 + * @see Binary File + * icon by Icons8 */ public static Icon icon4BinaryFile() { return icon("/image/icons8-binary-file-20.png"); } - /** - * Icon for bytes. - * - * @return Icon for bytes - * @see Scart icon by Icons8 - */ - public static Icon icon4Bytes() { - return icon("/image/icons8-scart-16.png"); - } - /** * Icon for checksum. * * @return Icon for checksum - * @see Check Mark icon by Icons8 + * @see Check + * Mark icon by Icons8 */ public static Icon icon4Checksum() { return icon("/image/icons8-check-mark-16.png"); @@ -98,27 +97,40 @@ public static Icon icon4Checksum() { * Icon for counter. * * @return Icon for counter - * @see Abacus icon by Icons8 + * @see Abacus + * icon by Icons8 */ public static Icon icon4Counter() { return icon("/image/icons8-abacus-16.png"); } + + /** + * Icon for raw Data. + * + * @return Icon for raw data + * @see Blockchain Technology icon by Icons8 + */ + public static Icon icon4Data() { + return icon("/image/icons8-blockchain-technology-16.png"); + } /** * Icon for DEX file. * * @return Icon for dex file - * @see APK icon by Icons8 + * @see APK icon by + * Icons8 */ public static Icon icon4Dex() { return icon("/image/icons8-apk-20.png"); } - + /** * Icon for endian. * * @return Icon for endian - * @see Up Down Arrow icon by Icons8 + * @see Up Down + * Arrow icon by Icons8 */ public static Icon icon4Endian() { return icon("/image/icons8-up-down-arrow-16.png"); @@ -128,12 +140,23 @@ public static Icon icon4Endian() { * Icon for length. * * @return Icon for length - * @see Length icon by Icons8 + * @see Length icon by + * Icons8 */ public static Icon icon4Length() { return icon("/image/icons8-length-16.png"); } + /** + * Icon for Index. + * + * @return Icon for Index + * @see One Finger icon by Icons8 + */ + public static Icon icon4Index() { + return icon("/image/icons8-one-finger-16.png"); + } + /** * Icon for Java. * @@ -142,34 +165,56 @@ public static Icon icon4Length() { public static Icon icon4Java() { return icon("/image/icons8-java-20.png"); } - + /** * Icon for Offset / Location / Index. * * @return Icon for Offset - * @see Map Pin icon by Icons8 + * @see Map Pin + * icon by Icons8 */ public static Icon icon4Offset() { return icon("/image/icons8-map-pin-16.png"); } + /** + * Icon for parameter, of a method. + * + * @return Icon for Offset + * @see Filter icon by Icons8 + */ + public static Icon icon4Parameter() { + return icon("/image/icons8-filter-16.png"); + } + /** * Icon for magic number. * * @return Icon for magic number - * @see Magic Wand icon by Icons8 + * @see Magic + * Wand icon by Icons8 */ public static Icon icon4Magic() { return icon("/image/icons8-magic-wand-16.png"); } + /** + * Icon for return type, of a method. + * + * @return return type icon + * + * @see Return icon by Icons8 + */ + public static Icon icon4Return() { + return icon("/image/icons8-return-16.png"); + } + /** * Icon for shortcut. * * @return Shortcut icon * - * @see Shortcut icon - * by Icons8 + * @see Shortcut icon by Icons8 */ public static Icon icon4Shortcut() { return icon("/image/icons8-shortcut-16.png"); @@ -179,28 +224,31 @@ public static Icon icon4Shortcut() { * Icon for signature. * * @return Icon for signature - * @see Signature icon by Icons8 + * @see + * Signature + * icon by Icons8 */ public static Icon icon4Signature() { return icon("/image/icons8-signature-16.png"); } - + /** * Icon for Size. - * + * * @return Shortcut icon - * @see Page Size icon by Icons8 + * @see Page + * Size icon by Icons8 */ public static Icon icon4Size() { return icon("/image/icons8-page-size-16.png"); } - /** * Icon for tag. - * + * * @return tag icon - * @see Tag icon by Icons8 + * @see Tag icon by + * Icons8 */ public static Icon icon4Tag() { return icon("/image/icons8-tag-16.png"); @@ -210,13 +258,42 @@ public static Icon icon4Tag() { * Icon for version. * * @return Icon for versions - * @see Versions icon by Icons8 - * @see Versions icon by Icons8 + * @see Versions icon + * by Icons8 + * @see Versions icon + * by Icons8 */ public static Icon icon4Versions() { return icon("/image/icons8-versions-16.png"); } + /** + * Get left part of string for tree node. + * + * @param s The String to get left part + * @return Left part of string + */ + public static String left(String s) { + return left(s, TREENODE_STRING_MAXLEN); + } + + /** + * Get left part of string. + * + * @param s The String to get left part + * @param length Length to get + * @return Left part of string + */ + public static String left(String s, int length) { + if (s == null) { + return s; + } else if (s.length() < length) { + return s; + } else { + return s.substring(0, length - 1) + " ..."; + } + } + /** * Show a popup window with given message. * diff --git a/CommonLib/src/main/resources/image/icons8-blockchain-technology-16.png b/CommonLib/src/main/resources/image/icons8-blockchain-technology-16.png new file mode 100644 index 0000000..05f1fd2 Binary files /dev/null and b/CommonLib/src/main/resources/image/icons8-blockchain-technology-16.png differ diff --git a/CommonLib/src/main/resources/image/icons8-filter-16.png b/CommonLib/src/main/resources/image/icons8-filter-16.png new file mode 100644 index 0000000..5b3235a Binary files /dev/null and b/CommonLib/src/main/resources/image/icons8-filter-16.png differ diff --git a/CommonLib/src/main/resources/image/icons8-one-finger-16.png b/CommonLib/src/main/resources/image/icons8-one-finger-16.png new file mode 100644 index 0000000..1f60a8f Binary files /dev/null and b/CommonLib/src/main/resources/image/icons8-one-finger-16.png differ diff --git a/CommonLib/src/main/resources/image/icons8-return-16.png b/CommonLib/src/main/resources/image/icons8-return-16.png new file mode 100644 index 0000000..5fe6992 Binary files /dev/null and b/CommonLib/src/main/resources/image/icons8-return-16.png differ diff --git a/CommonLib/src/main/resources/image/icons8-scart-16.png b/CommonLib/src/main/resources/image/icons8-scart-16.png deleted file mode 100644 index d2a6029..0000000 Binary files a/CommonLib/src/main/resources/image/icons8-scart-16.png and /dev/null differ diff --git a/CommonLib/src/main/resources/image/icons8-shortcut-16.png b/CommonLib/src/main/resources/image/icons8-shortcut-16.png index bb8109d..7854bc0 100644 Binary files a/CommonLib/src/main/resources/image/icons8-shortcut-16.png and b/CommonLib/src/main/resources/image/icons8-shortcut-16.png differ diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/GenerateClassfileTreeNode.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/GenerateTreeNodeClassFile.java similarity index 57% rename from FormatCLASS/src/main/java/org/freeinternals/format/classfile/GenerateClassfileTreeNode.java rename to FormatCLASS/src/main/java/org/freeinternals/format/classfile/GenerateTreeNodeClassFile.java index bb8a7e7..b8fde44 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/GenerateClassfileTreeNode.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/GenerateTreeNodeClassFile.java @@ -1,5 +1,5 @@ /* - * GenerateClassfileTreeNode.java September 07, 2019, 21:22 + * GenerateTreeNodeClassFile.java September 07, 2019, 21:22 * * Copyright 2019, FreeInternals.org. All rights reserved. * Use is subject to license terms. @@ -12,12 +12,13 @@ import javax.swing.tree.DefaultMutableTreeNode; /** + * Interface for generating tree node for {@link ClassFile}. * * @author Amos Shi */ -public interface GenerateClassfileTreeNode { +public interface GenerateTreeNodeClassFile { - ResourceBundle MESSAGES = ResourceBundle.getBundle(GenerateClassfileTreeNode.class.getPackageName() + ".MessagesBundle", Locale.ROOT); + ResourceBundle MESSAGES = ResourceBundle.getBundle(GenerateTreeNodeClassFile.class.getPackageName() + ".MessagesBundle", Locale.ROOT); void generateTreeNode(final DefaultMutableTreeNode parentNode, ClassFile classFile); diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/JTreeClassFile.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/JTreeClassFile.java index db83456..324fff6 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/JTreeClassFile.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/JTreeClassFile.java @@ -51,7 +51,7 @@ void generateTreeNodes(final DefaultMutableTreeNode rootNode) { u4.LENGTH, "magic", UITool.icon4Magic(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_magic")))); + GenerateTreeNodeClassFile.MESSAGES.getString("msg_magic")))); this.generateTreeNodeClsssFileVersion(); this.generateConstantPool(); @@ -69,7 +69,7 @@ private void generateTreeNodeClsssFileVersion() { u2.LENGTH, "minor_version: " + this.classFile.minor_version.value, UITool.icon4Versions(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_version") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_version") ))); startPos += u2.LENGTH; @@ -78,7 +78,7 @@ private void generateTreeNodeClsssFileVersion() { u2.LENGTH, "major_version: " + this.classFile.major_version.value, UITool.icon4Versions(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_version") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_version") ))); } @@ -92,7 +92,7 @@ private void generateConstantPool() { u2.LENGTH, "constant_pool_count: " + cpCount, UITool.icon4Counter(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_constant_pool_count") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_constant_pool_count") ))); startPos += u2.LENGTH; @@ -101,7 +101,7 @@ private void generateConstantPool() { startPos, cp[cpCount - 1].getStartPos() + cp[cpCount - 1].getLength() - startPos, CP_PREFIX + cpCount + "]", - GenerateClassfileTreeNode.MESSAGES.getString("msg_constant_pool_table") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_constant_pool_table") )); this.root.add(constantPool); @@ -114,12 +114,12 @@ private void generateConstantPool() { 1, "tag: " + cp[i].tag.value, UITool.icon4Tag(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_cp_tag") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_cp_tag") ))); cp[i].generateTreeNode(cpInfoNode, this.classFile); } else { cpInfoNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent(0, 0, i + ". [Empty Item]", - GenerateClassfileTreeNode.MESSAGES.getString("msg_cp_empty"))); + GenerateTreeNodeClassFile.MESSAGES.getString("msg_cp_empty"))); } constantPool.add(cpInfoNode); @@ -133,7 +133,7 @@ private void generateClassDeclaration() { this.classFile.access_flags.getStartPos(), this.classFile.access_flags.getLength(), MESSAGE_ACCESS_FLAGS + BytesTool.getBinaryString(this.classFile.access_flags.value.value) + " " + this.classFile.getModifiers(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_access_flags") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_access_flags") )); this.root.add(accessFlags); @@ -144,7 +144,7 @@ private void generateClassDeclaration() { this.classFile.this_class.getStartPos(), this.classFile.this_class.getLength(), sb.toString(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_this_class") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_this_class") )); this.root.add(thisClass); @@ -160,7 +160,7 @@ private void generateClassDeclaration() { this.classFile.super_class.getStartPos(), this.classFile.super_class.getLength(), sb.toString(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_super_class") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_super_class") )); this.root.add(superClass); @@ -170,7 +170,7 @@ private void generateClassDeclaration() { this.classFile.interfaces_count.getLength(), "interfaces_count: " + interfaceCount, UITool.icon4Counter(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_interfaces_count") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_interfaces_count") )); this.root.add(interfacesCount); @@ -181,7 +181,7 @@ private void generateClassDeclaration() { interfaces[0].getStartPos(), interfaces[interfaceCount - 1].getStartPos() + interfaces[interfaceCount - 1].getLength() - interfaces[0].getStartPos(), "interfaces[" + interfaceCount + "]", - GenerateClassfileTreeNode.MESSAGES.getString("msg_interfaces_table") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_interfaces_table") )); this.root.add(interfacesNode); @@ -210,7 +210,7 @@ private void generateFields() { this.classFile.fields_count.getLength(), "fields_count: " + fieldCount, UITool.icon4Counter(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_fields_count") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_fields_count") )); this.root.add(fieldsCount); @@ -220,7 +220,7 @@ private void generateFields() { fields[0].getStartPos(), fields[fieldCount - 1].getStartPos() + fields[fieldCount - 1].getLength() - fields[0].getStartPos(), FIELDS_PREFIX + fieldCount + "]", - GenerateClassfileTreeNode.MESSAGES.getString("msg_fields_table") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_fields_table") )); this.root.add(fieldsNode); @@ -301,7 +301,7 @@ private void generateMethods() { this.classFile.methods_count.getLength(), "methods_count: " + methodCount, UITool.icon4Counter(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_methods_count") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_methods_count") )); this.root.add(methodsCount); @@ -311,7 +311,7 @@ private void generateMethods() { methods[0].getStartPos(), methods[methodCount - 1].getStartPos() + methods[methodCount - 1].getLength() - methods[0].getStartPos(), METHODS_PERFIX + methodCount + "]", - GenerateClassfileTreeNode.MESSAGES.getString("msg_methods_table") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_methods_table") )); this.root.add(methodsNode); @@ -391,7 +391,7 @@ private void generateAttributes() { this.classFile.attributes_count.getLength(), MESSAGE_ATTR_COUNT + attrCount, UITool.icon4Counter(), - GenerateClassfileTreeNode.MESSAGES.getString("msg_attributes_count") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_attributes_count") )); this.root.add(attrsCount); @@ -401,7 +401,7 @@ private void generateAttributes() { attrs[0].getStartPos(), attrs[attrCount - 1].getStartPos() + attrs[attrCount - 1].getLength() - attrs[0].getStartPos(), "attributes[" + attrCount + "]", - GenerateClassfileTreeNode.MESSAGES.getString("msg_attributes_table") + GenerateTreeNodeClassFile.MESSAGES.getString("msg_attributes_table") )); this.root.add(attrsNode); diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/SignatureConvertor.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/SignatureConvertor.java index 697193d..2272815 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/SignatureConvertor.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/SignatureConvertor.java @@ -57,6 +57,10 @@ public final class SignatureConvertor { * */ public static final char METHODDESCRIPTOR_RIGHT = ')'; + /** + * void return type for method. + */ + public static final String METHODRETURN_VOID = "V"; private SignatureConvertor() { } @@ -85,9 +89,20 @@ public static SignatureResult methodReturnTypeExtractor(final String signature) throw new IllegalArgumentException(String.format("There is no ')' in the method signature: %s", signature)); } - SignatureResult returnValue; final String returnType = signature.substring(bracketEnd + 1); - if ("V".equals(returnType)) { + return methodReturnTypeJLS(returnType); + } + + /** + * JLS format of return type. + * + * @param returnType Return type in binary format + * @return Method return type in Java Programming language format + * @throws FileFormatException + */ + public static SignatureResult methodReturnTypeJLS(final String returnType) throws FileFormatException { + SignatureResult returnValue; + if (METHODRETURN_VOID.equals(returnType)) { returnValue = new SignatureResult(0, returnType, JavaLangSpec.Keyword.VOID.text); } else { returnValue = SignatureConvertor.fieldDescriptorExtractor(returnType); @@ -96,6 +111,7 @@ public static SignatureResult methodReturnTypeExtractor(final String signature) return returnValue; } + /** * Get parameters type from method descriptor {@link method_info#descriptor_index}. * diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/InnerClasses_attribute.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/InnerClasses_attribute.java index b5220d6..8008d42 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/InnerClasses_attribute.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/InnerClasses_attribute.java @@ -15,9 +15,9 @@ import org.freeinternals.commonlib.core.FileFormatException; import org.freeinternals.format.classfile.AccessFlag; import org.freeinternals.format.classfile.ClassFile; -import org.freeinternals.format.classfile.GenerateClassfileTreeNode; import org.freeinternals.format.classfile.constant.CONSTANT_Class_info; import org.freeinternals.format.classfile.u2; +import org.freeinternals.format.classfile.GenerateTreeNodeClassFile; /** * The class for the {@code InnerClasses} attribute. The {@code InnerClasses} @@ -126,7 +126,7 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, final ClassFile * * @author Amos Shi */ - public static final class Class extends FileComponent implements GenerateClassfileTreeNode { + public static final class Class extends FileComponent implements GenerateTreeNodeClassFile { /** * The length of current component. diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/Record_attribute.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/Record_attribute.java index cac24f6..d56adc5 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/Record_attribute.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/Record_attribute.java @@ -13,9 +13,9 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.core.FileFormatException; import org.freeinternals.format.classfile.ClassFile; -import org.freeinternals.format.classfile.GenerateClassfileTreeNode; import org.freeinternals.format.classfile.constant.cp_info; import org.freeinternals.format.classfile.u2; +import org.freeinternals.format.classfile.GenerateTreeNodeClassFile; /** * @@ -131,7 +131,7 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, ClassFile classF * */ @SuppressWarnings("java:S101") - public static final class record_component_info extends FileComponent implements GenerateClassfileTreeNode { + public static final class record_component_info extends FileComponent implements GenerateTreeNodeClassFile { /** * The value of the name_index item must be a valid index into the diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/attribute_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/attribute_info.java index 30dc4f0..5f48189 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/attribute_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/attribute/attribute_info.java @@ -17,7 +17,6 @@ import org.freeinternals.commonlib.core.PosDataInputStream; import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.format.classfile.ClassFile; -import org.freeinternals.format.classfile.GenerateClassfileTreeNode; import org.freeinternals.format.classfile.JavaSEVersion; import org.freeinternals.format.classfile.attribute.aspectj.AjSynthetic_attribute; import org.freeinternals.format.classfile.attribute.aspectj.MethodDeclarationLineNumber_attribute; @@ -30,6 +29,7 @@ import org.freeinternals.format.classfile.method_info; import org.freeinternals.format.classfile.u2; import org.freeinternals.format.classfile.u4; +import org.freeinternals.format.classfile.GenerateTreeNodeClassFile; /** * Super class for attributes in class file. All attributes have the following @@ -58,7 +58,7 @@ * */ @SuppressWarnings({"java:S101", "java:S116"}) -public abstract class attribute_info extends FileComponent implements GenerateClassfileTreeNode { +public abstract class attribute_info extends FileComponent implements GenerateTreeNodeClassFile { private static final Logger LOG = Logger.getLogger(attribute_info.class.getName()); diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Double_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Double_info.java index 92ce28f..9b7784e 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Double_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Double_info.java @@ -79,14 +79,14 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, ClassFile classF super.startPos + 1, 4, "high_bytes - value: " + this.doubleValue + " - " + BytesTool.getByteDataHexView(this.rawData), - UITool.icon4Bytes(), + UITool.icon4Data(), MESSAGES.getString("msg_const_double_bytes") ))); parentNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( super.startPos + 5, 4, "low_bytes", - UITool.icon4Bytes(), + UITool.icon4Data(), MESSAGES.getString("msg_const_double_bytes") ))); } diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Float_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Float_info.java index 399e48f..28307aa 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Float_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Float_info.java @@ -75,7 +75,7 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, ClassFile classF this.getStartPos() + 1, 4, "bytes: " + this.floatValue + " - " + BytesTool.getByteDataHexView(this.rawData), - UITool.icon4Bytes(), + UITool.icon4Data(), MESSAGES.getString("msg_const_float_bytes") ))); } diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Integer_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Integer_info.java index 6c93f7e..927f07a 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Integer_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Integer_info.java @@ -13,7 +13,7 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; /** * The class for the {@code CONSTANT_Integer_info} structure in constant pool. @@ -75,7 +75,7 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, ClassFile classF super.startPos + 1, 4, "bytes: " + this.integerValue + " - " + BytesTool.getByteDataHexView(this.rawData), - UITool.icon4Bytes(), + UITool.icon4Data(), MESSAGES.getString("msg_const_int_bytes") ))); } diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_InvokeDynamic_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_InvokeDynamic_info.java index 42c094a..9e4662c 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_InvokeDynamic_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_InvokeDynamic_info.java @@ -13,7 +13,7 @@ import org.freeinternals.commonlib.core.FileFormatException; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; import org.freeinternals.format.classfile.u2; /** diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Long_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Long_info.java index a118d35..509c914 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Long_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Long_info.java @@ -13,7 +13,7 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; /** * The class for the {@code CONSTANT_Long_info} structure in constant pool. The @@ -81,14 +81,14 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, ClassFile classF this.startPos + 1, 4, "high_bytes - value: " + this.longValue + " - " + BytesTool.getByteDataHexView(this.rawData), - UITool.icon4Bytes(), + UITool.icon4Data(), MESSAGES.getString("msg_const_long_bytes") ))); parentNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( this.startPos + 5, 4, "low_bytes", - UITool.icon4Bytes(), + UITool.icon4Data(), MESSAGES.getString("msg_const_long_bytes") ))); } diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_MethodType_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_MethodType_info.java index 714cdc5..8b76869 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_MethodType_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_MethodType_info.java @@ -15,7 +15,7 @@ import org.freeinternals.commonlib.core.FileFormatException; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; import org.freeinternals.format.classfile.SignatureConvertor; import org.freeinternals.format.classfile.u2; diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Methodref_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Methodref_info.java index 82aa2b0..610baec 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Methodref_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Methodref_info.java @@ -12,7 +12,7 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; /** * The class for the {@code CONSTANT_Methodref_info} structure in constant pool. diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Module_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Module_info.java index 146270f..4b25c9a 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Module_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Module_info.java @@ -12,7 +12,7 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; import org.freeinternals.format.classfile.u2; /** diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_NameAndType_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_NameAndType_info.java index 6b4ca06..40af144 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_NameAndType_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_NameAndType_info.java @@ -12,7 +12,7 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; import org.freeinternals.format.classfile.u2; /** diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Package_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Package_info.java index 0812fe0..3db4b5e 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Package_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Package_info.java @@ -12,7 +12,7 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; import org.freeinternals.format.classfile.u2; /** diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_String_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_String_info.java index 4241ed9..5316f2a 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_String_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_String_info.java @@ -12,7 +12,7 @@ import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; import org.freeinternals.format.classfile.ClassFile; -import static org.freeinternals.format.classfile.GenerateClassfileTreeNode.MESSAGES; +import static org.freeinternals.format.classfile.GenerateTreeNodeClassFile.MESSAGES; import org.freeinternals.format.classfile.u2; /** diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Utf8_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Utf8_info.java index 8f76f8b..8f568b2 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Utf8_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/CONSTANT_Utf8_info.java @@ -107,7 +107,7 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode, ClassFile classF startPos + 3, this.length_utf8.value, "bytes: " + this.getValue(), - UITool.icon4Bytes(), + UITool.icon4Data(), MESSAGES.getString("msg_const_utf8_bytes") ))); } diff --git a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/cp_info.java b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/cp_info.java index c234e4a..e829928 100644 --- a/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/cp_info.java +++ b/FormatCLASS/src/main/java/org/freeinternals/format/classfile/constant/cp_info.java @@ -13,9 +13,9 @@ import org.freeinternals.commonlib.core.PosDataInputStream; import org.freeinternals.commonlib.core.FileFormatException; import org.freeinternals.format.classfile.ClassFile; -import org.freeinternals.format.classfile.GenerateClassfileTreeNode; import org.freeinternals.format.classfile.JavaSEVersion; import org.freeinternals.format.classfile.u1; +import org.freeinternals.format.classfile.GenerateTreeNodeClassFile; /** * The super class for constant pool items in class file. All constant pool @@ -41,7 +41,7 @@ * */ @SuppressWarnings("java:S101") -public abstract class cp_info extends FileComponent implements GenerateClassfileTreeNode { +public abstract class cp_info extends FileComponent implements GenerateTreeNodeClassFile { /** * Warning message for un-recognized type. diff --git a/FormatDEX/pom.xml b/FormatDEX/pom.xml index f54a586..46f35c0 100644 --- a/FormatDEX/pom.xml +++ b/FormatDEX/pom.xml @@ -19,6 +19,11 @@ freeinternals.commonlib ${commonlib.version} + + ${project.groupId} + freeinternals.format.class + 17.0 + 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 0f8d0a5..5a1cbcd 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/DexFile.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/DexFile.java @@ -14,6 +14,8 @@ import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.Icon; import javax.swing.tree.DefaultMutableTreeNode; import org.freeinternals.commonlib.core.BytesTool; @@ -33,13 +35,16 @@ * Dalvik Executable (DEX) format * *
+ * java:S100 - Method names should comply with a naming convention --- We respect the name from DEX spec instead
  * java:S116 - Field names should comply with a naming convention --- We respect the DEX spec name instead
  * java:S1104 - Class variable fields should not have public accessibility --- No, we like the simplified final value manner
  * 
*/ -@SuppressWarnings({"java:S116", "java:S1104"}) +@SuppressWarnings({"java:S100", "java:S116", "java:S1104"}) public class DexFile extends FileFormat { + private static final Logger LOGGER = Logger.getLogger(DexFile.class.getName()); + /** * The constant array/string * {@link #DEX_FILE_MAGIC1}|{@link #DEX_FILE_MAGIC2} is the list of bytes @@ -68,17 +73,16 @@ public class DexFile extends FileFormat { /** * The file header. */ - public header_item header; + public final header_item header; /** - * String identifiers list, or null{@link header_item#string_ids_off} - * is 0 + * String identifiers list, or null. */ - public string_id_item[] string_ids; - public type_id_item[] type_ids; - public proto_id_item[] proto_ids; - public field_id_item[] field_ids; - public method_id_item[] method_ids; - public class_def_item[] class_defs; + public final string_id_item[] string_ids; + public final type_id_item[] type_ids; + public final proto_id_item[] proto_ids; + public final field_id_item[] field_ids; + public final method_id_item[] method_ids; + public final class_def_item[] class_defs; // public Dex_ubyte[] data; /** * The parsed file components. @@ -86,6 +90,16 @@ public class DexFile extends FileFormat { public SortedMap data = new TreeMap<>(); public Type_ubyte[] link_data; + /** + *
+     * java:S3776 - Cognitive Complexity of methods should not be too high - We need this logic together
+     * 
+ * + * @param file + * @throws IOException + * @throws FileFormatException + */ + @SuppressWarnings("java:S3776") public DexFile(File file) throws IOException, FileFormatException { super(file); @@ -101,55 +115,7 @@ public DexFile(File file) throws IOException, FileFormatException { throw new FileFormatException("This is not a valid DEX file, because the DEX file signature does not exist at the beginning of this file."); } - this.parse(); - } - - static void checkUint(String fieldName, Type_uint uint, int streamPosition) throws FileFormatException { - if (uint.value > Integer.MAX_VALUE) { - throw new FileFormatException(String.format("%s is too big cannot be handled here: %d, position 0x%X", fieldName, uint.value, streamPosition)); - } - } - - @Override - public Icon getIcon() { - return UITool.icon4Dex(); - } - - /** - * Get the underlying String value for a {@link #string_ids} item. - * - * @param index Index in the {@link #string_ids} array - * @return String value for the {@link #string_ids} item, or - * null for invalid index - */ - public String getString(int index) { - if (index < -1 || this.string_ids == null || index >= this.string_ids.length) { - return null; - } - - FileComponent fc = this.data.get(this.string_ids[index].string_data_off.value); - if (fc instanceof string_data_item) { - return ((string_data_item) fc).getString(); - } else { - return null; - } - } - - public String getTypeDescriptor(int index) { - if (index < -1 || this.type_ids == null || index >= this.type_ids.length) { - return null; - } - - return this.getString(this.type_ids[index].descriptor_idx.intValue()); - } - - /** - *
-     * java:S3776 - Cognitive Complexity of methods should not be too high - We need this logic together
-     * 
- */ - @SuppressWarnings("java:S3776") - private void parse() throws IOException, FileFormatException { + // Parse section by section PosDataInputStream parseEndian = new PosDataInputStream(new PosByteArrayInputStream(super.fileByteArray)); BytesTool.skip(parseEndian, DEX_FILE_MAGIC1.size()); @@ -261,7 +227,54 @@ private void parse() throws IOException, FileFormatException { } } + } + + static void check_uint(String fieldName, Type_uint uint, int streamPosition) throws FileFormatException { + if (uint.value > Integer.MAX_VALUE) { + throw new FileFormatException(String.format("%s is too big cannot be handled here: %d, position 0x%X", fieldName, uint.value, streamPosition)); + } + } + + @Override + public Icon getIcon() { + return UITool.icon4Dex(); + } + + /** + * Get the underlying String value for a {@link #string_ids} item. + * + * @param index Index in the {@link #string_ids} array + * @return String value for the {@link #string_ids} item, or + * null for invalid index + */ + public String get_string_ids_string(int index) { + if (index < -1 || this.string_ids == null || index >= this.string_ids.length) { + LOGGER.log(Level.WARNING, "Return null for invalid string_ids index={0}", index); + return null; + } + + FileComponent fc = this.data.get(this.string_ids[index].string_data_off.value); + if (fc instanceof string_data_item) { + return ((string_data_item) fc).getString(); + } else { + return null; + } + } + + /** + * Get the underlying String value for a {@link #type_ids} item. + * + * @param index Index in the {@link #type_ids} array + * @return String value for the {@link #type_ids} item, or null + * for invalid index + */ + public String get_type_ids_string(int index) { + if (index < -1 || this.type_ids == null || index >= this.type_ids.length) { + LOGGER.log(Level.WARNING, "Return null for invalid type_ids index={0}", index); + return null; + } + return this.get_string_ids_string(this.type_ids[index].descriptor_idx.intValue()); } @Override @@ -271,6 +284,6 @@ public String getContentTabName() { @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - TreeNodeGenerator.generate(this, parentNode); + (new JTreeDexFile()).generateTreeNode(parentNode, this); } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/GenerateTreeNodeDexFile.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/GenerateTreeNodeDexFile.java new file mode 100644 index 0000000..e5784f0 --- /dev/null +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/GenerateTreeNodeDexFile.java @@ -0,0 +1,25 @@ +/* + * GenerateTreeNodeDexFile.java August 18, 2021, 19:13 + * + * Copyright 2021, FreeInternals.org. All rights reserved. + * Use is subject to license terms. + */ + +package org.freeinternals.format.dex; + +import java.util.Locale; +import java.util.ResourceBundle; +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * Interface for generating tree node for {@link DexFile}. + * + * @author Amos Shi + */ +public interface GenerateTreeNodeDexFile { + static final ResourceBundle MESSAGES = ResourceBundle.getBundle(JTreeDexFile.class.getPackageName() + ".MessagesBundle", Locale.ROOT); + static final String FORMAT_STRING_STRING = "%s - %s"; + + void generateTreeNode(final DefaultMutableTreeNode parentNode, DexFile dexFile); + +} diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/JTreeDexFile.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/JTreeDexFile.java new file mode 100644 index 0000000..cb632ff --- /dev/null +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/JTreeDexFile.java @@ -0,0 +1,323 @@ +/* + * JTreeDexFile.java June 15, 2015, 23:45 + * + * Copyright 2015, FreeInternals.org. All rights reserved. + * Use is subject to license terms. + */ +package org.freeinternals.format.dex; + +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.Icon; +import javax.swing.tree.DefaultMutableTreeNode; +import org.freeinternals.commonlib.core.FileComponent; +import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; +import org.freeinternals.commonlib.ui.UITool; + +/** + * + * @author Amos Shi + * + *
+ * java:S100 - Method names should comply with a naming convention --- We respect the name from DEX spec instead
+ * 
+ */ +@SuppressWarnings("java:S100") +public class JTreeDexFile implements GenerateTreeNodeDexFile { + + private static final Logger LOGGER = Logger.getLogger(JTreeDexFile.class.getName()); + private static final String MESSAGE_CLASS_IDX = "class_idx"; + + JTreeDexFile() { + } + + protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value) { + return addNode(parentNode, startPos, len, name, value, null, null); + } + + protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value, Icon icon) { + return addNode(parentNode, startPos, len, name, value, null, icon); + } + + protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value, String msgkey) { + return addNode(parentNode, startPos, len, name, value, msgkey, null); + } + + protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value, String msgkey, Icon icon) { + JTreeNodeFileComponent fileComp = new JTreeNodeFileComponent( + startPos, + len, + name + ": " + value.toString() + ); + if (msgkey != null) { + fileComp.setDescription(GenerateTreeNodeDexFile.MESSAGES.getString(msgkey)); + } + fileComp.setIcon(icon); + + DefaultMutableTreeNode node = new DefaultMutableTreeNode(fileComp); + parentNode.add(node); + return node; + } + + @Override + public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) { + this.generate_magic(parentNode, dexFile); + dexFile.header.generateTreeNode(parentNode); + this.generate_string_ids(parentNode, dexFile); + this.generate_type_ids(parentNode, dexFile); + this.generate_proto_ids(parentNode, dexFile); + this.generate_field_ids(parentNode, dexFile); + this.generate_method_ids(parentNode, dexFile); + this.generate_class_defs(parentNode, dexFile); + this.generate_data(parentNode, dexFile); + } + + private void generate_magic(DefaultMutableTreeNode parentNode, DexFile dexFile) { + int startPos = 0; + + DefaultMutableTreeNode magicNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + DexFile.DEX_FILE_MAGIC1.size() + DexFile.DEX_FILE_MAGIC2.size(), + "magic")); + parentNode.add(magicNode); + + magicNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + DexFile.DEX_FILE_MAGIC1.size(), + "magic 1: " + new String(dexFile.magic1, StandardCharsets.UTF_8), + UITool.icon4Magic(), + GenerateTreeNodeDexFile.MESSAGES.getString("msg_dex_file_magic1") + ))); + startPos += DexFile.DEX_FILE_MAGIC1.size(); + + magicNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + DexFile.DEX_FILE_MAGIC2.size(), + "magic 2: " + new String(dexFile.magic2, StandardCharsets.UTF_8), + UITool.icon4Magic(), + GenerateTreeNodeDexFile.MESSAGES.getString("msg_dex_file_magic2") + ))); + } + + private void generate_string_ids(DefaultMutableTreeNode parentNode, DexFile dexFile) { + if (dexFile.string_ids == null || dexFile.string_ids.length < 1) { + return; + } + + int startPos = dexFile.header.string_ids_off.intValue(); + int size = dexFile.string_ids.length; + + DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + size * Type_uint.LENGTH, + String.format("string_ids [%,d]", size))); + parentNode.add(node); + + for (int i = 0; i < size; i++) { + string_id_item item = dexFile.string_ids[i]; + FileComponent fc = dexFile.data.get(item.string_data_off.value); + string_data_item strData = null; + String strDataValue = ""; + if (fc instanceof string_data_item) { + strData = (string_data_item) fc; + strDataValue = strData.getString(); + } else { + LOGGER.log(Level.SEVERE, String.format("This case should never happen. The string_ids did not point to string_data_item: index=%d offset=0x%08X", i, fc.getStartPos())); + } + + DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + item.getStartPos(), + item.getLength(), + String.format("string_id_item[%,d] : %s", i, UITool.left(strDataValue)) + )); + node.add(itemNode); + item.generateTreeNode(itemNode); + + if (strData != null) { + DefaultMutableTreeNode dataNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + strData.getStartPos(), + strData.getLength(), + "string_data_item", + UITool.icon4Shortcut(), + GenerateTreeNodeDexFile.MESSAGES.getString("msg_string_data_item") + )); + itemNode.add(dataNode); + strData.generateTreeNode(dataNode); + } + } + } + + private void generate_type_ids(DefaultMutableTreeNode parentNode, DexFile dexFile) { + if (dexFile.type_ids == null || dexFile.type_ids.length < 1) { + return; + } + + int startPos = dexFile.header.type_ids_off.intValue(); + int size = dexFile.type_ids.length; + + DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + size * Type_uint.LENGTH, + String.format("type_ids [%,d]", size))); + parentNode.add(node); + + for (int i = 0; i < size; i++) { + type_id_item item = dexFile.type_ids[i]; + DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + item.getStartPos(), + item.getLength(), + String.format("type_id_item[%,d] : %s", i, item.get_descriptor_jls(dexFile)) + )); + node.add(itemNode); + item.generateTreeNode(itemNode, dexFile); + } + } + + private void generate_proto_ids(DefaultMutableTreeNode parentNode, DexFile dexFile) { + if (dexFile.proto_ids == null || dexFile.proto_ids.length < 1) { + return; + } + + int size = dexFile.proto_ids.length; + + DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + dexFile.header.proto_ids_off.intValue(), + size * proto_id_item.ITEM_SIZE, + String.format("proto_ids [%,d]", size))); + parentNode.add(node); + + for (int i = 0; i < size; i++) { + proto_id_item item = dexFile.proto_ids[i]; + DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + item.getStartPos(), + item.getLength(), + "proto_id_item[" + String.format("%,d", i) + "]")); + item.generateTreeNode(itemNode, dexFile); + node.add(itemNode); + } + } + + private void generate_field_ids(DefaultMutableTreeNode parentNode, DexFile dexFile) { + if (dexFile.field_ids == null || dexFile.field_ids.length < 1) { + return; + } + + int size = dexFile.field_ids.length; + DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + dexFile.header.field_ids_off.intValue(), + size * field_id_item.ITEM_SIZE, + String.format("field_ids [%,d]", size))); + parentNode.add(node); + + for (int i = 0; i < size; i++) { + field_id_item item = dexFile.field_ids[i]; + DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + item.getStartPos(), + item.getLength(), + String.format("field_id_item[%,d] : %s", i, item.toString(dexFile)))); + item.generateTreeNode(itemNode, dexFile); + node.add(itemNode); + } + } + + private void generate_method_ids(DefaultMutableTreeNode parentNode, DexFile dexFile) { + if (dexFile.method_ids == null || dexFile.method_ids.length < 1) { + return; + } + + int size = dexFile.method_ids.length; + DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + dexFile.header.method_ids_off.intValue(), + size * method_id_item.ITEM_SIZE, + String.format("method_ids [%,d]", size))); + parentNode.add(node); + + for (int i = 0; i < size; i++) { + method_id_item item = dexFile.method_ids[i]; + int startPos = item.getStartPos(); + DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + item.getLength(), + String.format("method_id_item[%,d] : %s", i, item.toString(dexFile)))); + item.generateTreeNode(itemNode, dexFile); + node.add(itemNode); + } + } + + private void generate_class_defs(DefaultMutableTreeNode parentNode, DexFile dexFile) { + if (dexFile.class_defs == null || dexFile.class_defs.length < 1) { + return; + } + + int size = dexFile.class_defs.length; + DefaultMutableTreeNode nodeTemp; + + DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + dexFile.header.class_defs_off.intValue(), + size * class_def_item.ITEM_SIZE, + String.format("class_defs [%,d]", size))); + parentNode.add(node); + + for (int i = 0; i < size; i++) { + class_def_item item = dexFile.class_defs[i]; + int startPos = item.getStartPos(); + DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + item.getLength(), + "class_def_item[" + String.format("%,d", i) + "]")); + node.add(itemNode); + + nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, MESSAGE_CLASS_IDX, item.class_idx); + startPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); + + nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "access_flags", item.access_flags); + startPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); + + nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "superclass_idx", item.superclass_idx); + startPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); + + nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "interfaces_off", item.interfaces_off); + startPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); + + nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "source_file_idx", item.source_file_idx); + startPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); + + nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "annotations_off", item.annotations_off); + startPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); + + nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "class_data_off", item.class_data_off); + startPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); + + addNode(itemNode, startPos, Type_uint.LENGTH, "static_values_off", item.static_values_off); + } + } + + private void generate_data(DefaultMutableTreeNode parentNode, DexFile dexFile) { + if (dexFile.data.size() < 1) { + return; + } + + DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + dexFile.header.data_off.intValue(), + dexFile.header.data_size.intValue(), + "data")); + parentNode.add(node); + + for (Map.Entry item : dexFile.data.entrySet()) { + FileComponent fc = item.getValue(); + int startPos = fc.getStartPos(); + + DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( + startPos, + fc.getLength(), + Type_uint.toString(startPos) + " - " + fc.getClass().getSimpleName())); + node.add(itemNode); + + if (fc instanceof string_data_item) { + ((string_data_item) fc).generateTreeNode(itemNode); + } + } + } +} diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/PosDataInputStreamDex.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/PosDataInputStreamDex.java index 94cac0d..74eb2fb 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/PosDataInputStreamDex.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/PosDataInputStreamDex.java @@ -25,7 +25,7 @@ public class PosDataInputStreamDex extends PosDataInputStream { /** * Endian of the {@link DexFile}. The default value is little-endian - * {@link HeaderItem.Endian#ENDIAN_CONSTANT}, as the DEX format + * {@link header_item.Endian#ENDIAN_CONSTANT}, as the DEX format * specification said. */ protected final header_item.Endian endian; diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/TreeNodeGenerator.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/TreeNodeGenerator.java deleted file mode 100644 index 9cb276f..0000000 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/TreeNodeGenerator.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * TreeNodeGenerator.java June 15, 2015, 23:45 - * - * Copyright 2015, FreeInternals.org. All rights reserved. - * Use is subject to license terms. - */ -package org.freeinternals.format.dex; - -import java.nio.charset.StandardCharsets; -import java.util.Locale; -import java.util.Map; -import java.util.ResourceBundle; -import javax.swing.Icon; -import javax.swing.tree.DefaultMutableTreeNode; -import org.freeinternals.commonlib.core.FileComponent; -import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; -import org.freeinternals.commonlib.ui.UITool; - -/** - * - * @author Amos Shi - */ -public class TreeNodeGenerator { - static final ResourceBundle MESSAGES = ResourceBundle.getBundle(TreeNodeGenerator.class.getPackageName() + ".MessagesBundle", Locale.ROOT); - private static final String MESSAGE_CLASS_IDX = "class_idx"; - private final DexFile dexFile; - private final DefaultMutableTreeNode rootNode; - - public static void generate(DexFile dexFile, DefaultMutableTreeNode parentNode) { - new TreeNodeGenerator(dexFile, parentNode).start(); - } - - TreeNodeGenerator(DexFile dexFile, DefaultMutableTreeNode parentNode) { - this.dexFile = dexFile; - this.rootNode = parentNode; - } - - private void start() { - this.generateMagic(); - this.dexFile.header.generateTreeNode(this.rootNode); - this.generateStringIds(); - this.generateTypeIds(); - this.generateProtoIds(); - this.generateFieldIds(); - this.generateMethodIds(); - this.generateClassDefs(); - this.generateData(); - } - - protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value) { - return addNode(parentNode, startPos, len, name, value, null, null); - } - - protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value, Icon icon) { - return addNode(parentNode, startPos, len, name, value, null, icon); - } - - protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value, String msgkey) { - return addNode(parentNode, startPos, len, name, value, msgkey, null); - } - protected static DefaultMutableTreeNode addNode(DefaultMutableTreeNode parentNode, int startPos, int len, String name, Object value, String msgkey, Icon icon) { - JTreeNodeFileComponent fileComp = new JTreeNodeFileComponent( - startPos, - len, - name + ": " + value.toString() - ); - if (msgkey != null) { - fileComp.setDescription(MESSAGES.getString(msgkey)); - } - fileComp.setIcon(icon); - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(fileComp); - parentNode.add(node); - return node; - } - - private void generateMagic() { - int startPos = 0; - - DefaultMutableTreeNode magicNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - DexFile.DEX_FILE_MAGIC1.size() + DexFile.DEX_FILE_MAGIC2.size(), - "magic")); - this.rootNode.add(magicNode); - - magicNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - DexFile.DEX_FILE_MAGIC1.size(), - "magic 1: " + new String(this.dexFile.magic1, StandardCharsets.UTF_8), - UITool.icon4Magic(), - MESSAGES.getString("msg_dex_file_magic1") - ))); - startPos += DexFile.DEX_FILE_MAGIC1.size(); - - magicNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - DexFile.DEX_FILE_MAGIC2.size(), - "magic 2: " + new String(this.dexFile.magic2, StandardCharsets.UTF_8), - UITool.icon4Magic(), - MESSAGES.getString("msg_dex_file_magic2") - ))); - } - - private void generateStringIds() { - if (this.dexFile.string_ids == null || this.dexFile.string_ids.length < 1) { - return; - } - - int startPos = this.dexFile.header.string_ids_off.intValue(); - int size = this.dexFile.string_ids.length; - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - size * Type_uint.LENGTH, - String.format("string_ids [%,d]", size))); - this.rootNode.add(node); - - for (int i = 0; i < size; i++) { - string_id_item item = this.dexFile.string_ids[i]; - DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - item.getStartPos(), - item.getLength(), - "string_id_item[" + String.format("%,d", i) + "]")); - node.add(itemNode); - item.generateTreeNode(itemNode); - - FileComponent fc = this.dexFile.data.get(item.string_data_off.value); - if (fc instanceof string_data_item) { - ((string_data_item) fc).generateTreeNode(itemNode); - } else { - // Unexpected case - itemNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( - 0, - 0, - "ERROR: No String Item Found"))); - } - } - } - - private void generateTypeIds() { - if (this.dexFile.type_ids == null || this.dexFile.type_ids.length < 1) { - return; - } - - int startPos = this.dexFile.header.type_ids_off.intValue(); - int size = this.dexFile.type_ids.length; - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - size * Type_uint.LENGTH, - String.format("type_ids [%,d]", size))); - this.rootNode.add(node); - - for (int i = 0; i < size; i++) { - type_id_item item = this.dexFile.type_ids[i]; - DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - item.getStartPos(), - item.getLength(), - "type_id_item[" + String.format("%,d", i) + "].descriptor_idx: " + item.descriptor_idx.toString())); - node.add(itemNode); - itemNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( - 0, - 0, - this.dexFile.getString(item.descriptor_idx.intValue())))); - } - } - - private void generateProtoIds() { - if (this.dexFile.proto_ids == null || this.dexFile.proto_ids.length < 1) { - return; - } - - int size = this.dexFile.proto_ids.length; - DefaultMutableTreeNode nodeTemp; - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - this.dexFile.header.proto_ids_off.intValue(), - size * proto_id_item.LENGTH, - String.format("proto_ids [%,d]", size))); - this.rootNode.add(node); - - for (int i = 0; i < size; i++) { - proto_id_item item = this.dexFile.proto_ids[i]; - int startPos = item.getStartPos(); - DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - item.getLength(), - "proto_id_item[" + String.format("%,d", i) + "]")); - node.add(itemNode); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "shorty_idx", item.shorty_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - addNode(nodeTemp, 0, 0, "Value", this.dexFile.getString(item.shorty_idx.intValue())); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "return_type_idx", item.return_type_idx); - addNode(nodeTemp, 0, 0, "Value", this.dexFile.getTypeDescriptor(item.return_type_idx.intValue())); - } - } - - private void generateFieldIds() { - if (this.dexFile.field_ids == null || this.dexFile.field_ids.length < 1) { - return; - } - - int size = this.dexFile.field_ids.length; - DefaultMutableTreeNode nodeTemp; - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - this.dexFile.header.field_ids_off.intValue(), - size * field_id_item.LENGTH, - String.format("field_ids [%,d]", size))); - this.rootNode.add(node); - - for (int i = 0; i < size; i++) { - field_id_item item = this.dexFile.field_ids[i]; - int startPos = item.getStartPos(); - DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - item.getLength(), - "proto_id_item[" + String.format("%,d", i) + "]")); - node.add(itemNode); - - nodeTemp = addNode(itemNode, startPos, Type_ushort.LENGTH, MESSAGE_CLASS_IDX, item.class_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_ushort.LENGTH, "type_idx", item.type_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - addNode(itemNode, startPos, Type_uint.LENGTH, "name_idx", item.name_idx); - } - } - - private void generateMethodIds() { - if (this.dexFile.method_ids == null || this.dexFile.method_ids.length < 1) { - return; - } - - int size = this.dexFile.method_ids.length; - DefaultMutableTreeNode nodeTemp; - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - this.dexFile.header.method_ids_off.intValue(), - size * method_id_item.LENGTH, - String.format("method_ids [%,d]", size))); - this.rootNode.add(node); - - for (int i = 0; i < size; i++) { - method_id_item item = this.dexFile.method_ids[i]; - int startPos = item.getStartPos(); - DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - item.getLength(), - "method_id_item[" + String.format("%,d", i) + "]")); - node.add(itemNode); - - nodeTemp = addNode(itemNode, startPos, Type_ushort.LENGTH, MESSAGE_CLASS_IDX, item.class_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_ushort.LENGTH, "proto_idx", item.proto_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - addNode(itemNode, startPos, Type_uint.LENGTH, "name_idx", item.name_idx); - } - } - - private void generateClassDefs() { - if (this.dexFile.class_defs == null || this.dexFile.class_defs.length < 1) { - return; - } - - int size = this.dexFile.class_defs.length; - DefaultMutableTreeNode nodeTemp; - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - this.dexFile.header.class_defs_off.intValue(), - size * class_def_item.LENGTH, - String.format("class_defs [%,d]", size))); - this.rootNode.add(node); - - for (int i = 0; i < size; i++) { - class_def_item item = this.dexFile.class_defs[i]; - int startPos = item.getStartPos(); - DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - item.getLength(), - "class_def_item[" + String.format("%,d", i) + "]")); - node.add(itemNode); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, MESSAGE_CLASS_IDX, item.class_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "access_flags", item.access_flags); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "superclass_idx", item.superclass_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "interfaces_off", item.interfaces_off); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "source_file_idx", item.source_file_idx); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "annotations_off", item.annotations_off); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - nodeTemp = addNode(itemNode, startPos, Type_uint.LENGTH, "class_data_off", item.class_data_off); - startPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - - addNode(itemNode, startPos, Type_uint.LENGTH, "static_values_off", item.static_values_off); - } - } - - private void generateData() { - if (this.dexFile.data.size() < 1) { - return; - } - - DefaultMutableTreeNode node = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - this.dexFile.header.data_off.intValue(), - this.dexFile.header.data_size.intValue(), - "data")); - this.rootNode.add(node); - - for (Map.Entry item : this.dexFile.data.entrySet()) { - FileComponent fc = item.getValue(); - int startPos = fc.getStartPos(); - - DefaultMutableTreeNode itemNode = new DefaultMutableTreeNode(new JTreeNodeFileComponent( - startPos, - fc.getLength(), - Type_uint.toString(startPos) + " - " + fc.getClass().getSimpleName())); - node.add(itemNode); - - if (fc instanceof string_data_item) { - ((string_data_item) fc).generateTreeNode(itemNode); - } - } - } -} diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/class_data_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/class_data_item.java index 2f43f95..0efc604 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/class_data_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/class_data_item.java @@ -35,6 +35,12 @@ public class class_data_item extends FileComponent implements GenerateTreeNode { public final encoded_method[] direct_methods; public final encoded_method[] virtual_methods; + /** + *
+     * java:S3776 - Cognitive Complexity of methods should not be too high - We need this logic together
+     * 
+ */ + @SuppressWarnings("java:S3776") class_data_item(PosDataInputStreamDex stream) throws IOException, FileFormatException { super.startPos = stream.getPos(); this.static_fields_size = stream.Dex_uleb128(); @@ -83,7 +89,7 @@ public class class_data_item extends FileComponent implements GenerateTreeNode { @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 1."); } public static class encoded_field extends FileComponent implements GenerateTreeNode { @@ -100,7 +106,7 @@ public static class encoded_field extends FileComponent implements GenerateTreeN @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 2."); } } @@ -120,7 +126,7 @@ public static class encoded_method extends FileComponent implements GenerateTree @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 3."); } } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/class_def_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/class_def_item.java index 0df80c5..a0a5cfe 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/class_def_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/class_def_item.java @@ -24,8 +24,10 @@ public class class_def_item extends FileComponent { /** * Item Size In Bytes. + * + * @see map_list.TypeCodes#TYPE_CLASS_DEF_ITEM */ - public static final int LENGTH = 0x20; + public static final int ITEM_SIZE = 0x20; /** * index into the type_ids list for this class. This must be a class type, diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/code_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/code_item.java index 3daf8b7..ab2f36f 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/code_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/code_item.java @@ -49,7 +49,7 @@ public class code_item extends FileComponent implements GenerateTreeNode { this.insns_size = stream.Dex_uint(); if (this.insns_size.value > 0) { - DexFile.checkUint("code_item.insns_size", this.insns_size, stream.getPos()); + DexFile.check_uint("code_item.insns_size", this.insns_size, stream.getPos()); this.insns = new Type_ushort[(int) this.insns_size.value]; for (int i = 0; i < this.insns_size.value; i++) { this.insns[i] = stream.Dex_ushort(); @@ -82,7 +82,7 @@ public class code_item extends FileComponent implements GenerateTreeNode { @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 1."); } @@ -102,7 +102,7 @@ public static class try_item extends FileComponent implements GenerateTreeNode { @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 2."); } } @@ -127,7 +127,7 @@ public static class encoded_catch_handler_list extends FileComponent implements @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 3."); } } @@ -162,7 +162,7 @@ public static class encoded_catch_handler extends FileComponent implements Gener @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 4."); } } @@ -180,7 +180,7 @@ public static class encoded_type_addr_pair extends FileComponent implements Gene @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { - throw new UnsupportedOperationException("Not supported yet."); + throw new UnsupportedOperationException("Not supported yet 5."); } } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/field_id_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/field_id_item.java index c3f84be..7ceaa22 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/field_id_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/field_id_item.java @@ -7,40 +7,53 @@ package org.freeinternals.format.dex; import java.io.IOException; +import javax.swing.tree.DefaultMutableTreeNode; import org.freeinternals.commonlib.core.FileComponent; +import org.freeinternals.commonlib.ui.UITool; +import static org.freeinternals.format.dex.JTreeDexFile.addNode; /** * * @author Amos Shi * *
+ * java:S100 - Method names should comply with a naming convention --- We respect the name from DEX spec instead
  * java:S101 - Class names should comply with a naming convention --- We respect the name from DEX Spec instead
  * java:S116 - Field names should comply with a naming convention --- We respect the DEX spec name instead
  * java:S1104 - Class variable fields should not have public accessibility --- No, we like the simplified final value manner
  * 
*/ -@SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) -public class field_id_item extends FileComponent { +@SuppressWarnings({"java:S100", "java:S101", "java:S116", "java:S1104"}) +public class field_id_item extends FileComponent implements GenerateTreeNodeDexFile { /** * Item Size In Bytes. + * + * @see map_list.TypeCodes#TYPE_FIELD_ID_ITEM */ - public static final int LENGTH = 8; + public static final int ITEM_SIZE = 0x08; /** * index into the type_ids list for the definer of this field. This must be * a class type, and not an array or primitive type. */ public Type_ushort class_idx; + private String clazz = null; + private String clazz_jls = null; + /** * index into the type_ids list for the type of this field. */ public Type_ushort type_idx; + private String type = null; + private String type_jls = null; + /** * index into the string_ids list for the name of this field. The string * must conform to the syntax for MemberName, defined above. */ public Type_uint name_idx; + private String name = null; field_id_item(PosDataInputStreamDex stream) throws IOException { super.startPos = stream.getPos(); @@ -49,4 +62,115 @@ public class field_id_item extends FileComponent { this.name_idx = stream.Dex_uint(); super.length = stream.getPos() - super.startPos; } + + /** + * Get {@link #class_idx} name. + * + * @param dexFile Current {@link DexFile} + * @return class name + * @see #class_idx + */ + public String get_class(DexFile dexFile) { + if (this.clazz == null) { + this.clazz = dexFile.get_type_ids_string(class_idx.value); + } + return this.clazz; + } + + /** + * Get {@link #class_idx} name in Java Language Specification format. + * + * @param dexFile Current {@link DexFile} + * @return class name in JLS format + * @see #class_idx + */ + public String get_class_jls(DexFile dexFile) { + if (this.clazz_jls == null) { + this.clazz_jls = dexFile.type_ids[class_idx.value].get_descriptor_jls(dexFile).toString(); + } + return this.clazz_jls; + } + + /** + * Get {@link #type_idx} name. + * + * @param dexFile Current {@link DexFile} + * @return type name + * @see #type_idx + */ + public String get_type(DexFile dexFile) { + if (this.type == null) { + this.type = dexFile.get_type_ids_string(type_idx.value); + } + return this.type; + } + + /** + * Get {@link #type_idx} name in Java Language Specification format. + * + * @param dexFile Current {@link DexFile} + * @return type name in JLS format + * @see #type_idx + */ + public String get_type_jls(DexFile dexFile) { + if (this.type_jls == null) { + this.type_jls = dexFile.type_ids[type_idx.value].get_descriptor_jls(dexFile).toString(); + } + return this.type_jls; + } + + /** + * Get {@link #name_idx} name. + * + * @param dexFile Current {@link DexFile} + * @return field name + * @see #name_idx + */ + public String get_name(DexFile dexFile) { + if (this.name == null) { + this.name = dexFile.get_string_ids_string(name_idx.intValue()); + } + return this.name; + } + + /** + * String format of current {@link field_id_item}. + * + * @param dexFile Current {@link DexFile} + * @return String format of a field + */ + public String toString(DexFile dexFile) { + return String.format("field %s.%s type %s", this.get_class_jls(dexFile), this.get_name(dexFile), this.get_type_jls(dexFile)); + } + + @Override + public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) { + int floatPos = super.startPos; + + addNode(parentNode, + floatPos, + Type_ushort.LENGTH, + "class_idx", + String.format(FORMAT_STRING_STRING, this.class_idx, this.get_class_jls(dexFile)), + "msg_field_id_item__class_idx", + UITool.icon4Index()); + floatPos += Type_ushort.LENGTH; + + addNode(parentNode, + floatPos, + Type_ushort.LENGTH, + "type_idx", + String.format(FORMAT_STRING_STRING, this.type_idx, this.get_type_jls(dexFile)), + "msg_field_id_item__type_idx", + UITool.icon4Index()); + floatPos += Type_ushort.LENGTH; + + addNode(parentNode, + floatPos, + Type_uint.LENGTH, + "name_idx", + String.format(FORMAT_STRING_STRING, this.name_idx, this.get_name(dexFile)), + "msg_field_id_item__name_idx", + UITool.icon4Index()); + } } 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 f1fee6f..d7df164 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 @@ -28,6 +28,11 @@ @SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) public class header_item extends FileComponent implements GenerateTreeNode { + /** + * @see map_list.TypeCodes#TYPE_HEADER_ITEM + */ + public static final int ITEM_SIZE = 0x70; + /** * adler32 checksum of the rest of the file (everything but magic and this * field); used to detect file corruption. @@ -128,16 +133,16 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode) { "header_item")); parentNode.add(headerNode); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "checksum", this.checksum, "msg_header_item_checksum", UITool.icon4Checksum()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "checksum", this.checksum, "msg_header_item_checksum", UITool.icon4Checksum()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, this.signature.length, "signature", Type_ubyte.toString(this.signature), "msg_header_item_signature", UITool.icon4Signature()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, this.signature.length, "signature", Type_ubyte.toString(this.signature), "msg_header_item_signature", UITool.icon4Signature()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "file_size", this.file_size, "msg_header_item_file_size", UITool.icon4Size()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "file_size", this.file_size, "msg_header_item_file_size", UITool.icon4Size()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "header_size", this.header_size, "msg_header_item_header_size", UITool.icon4Size()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "header_size", this.header_size, "msg_header_item_header_size", UITool.icon4Size()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); headerNode.add(new DefaultMutableTreeNode(new JTreeNodeFileComponent( @@ -145,59 +150,59 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode) { Type_uint.LENGTH, "endian_tag: " + this.endian_tag.toString() + " / " + Endian.toString(this.endian_tag.intValue()), UITool.icon4Endian(), - TreeNodeGenerator.MESSAGES.getString("msg_header_item_endian_tag") + GenerateTreeNodeDexFile.MESSAGES.getString("msg_header_item_endian_tag") ))); floatPos += Type_uint.LENGTH; - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "link_size", this.link_size, "msg_header_item_link_size", UITool.icon4Size()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "link_size", this.link_size, "msg_header_item_link_size", UITool.icon4Size()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "link_off", this.link_off, "msg_header_item_link_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "link_off", this.link_off, "msg_header_item_link_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "map_off", this.map_off, "msg_header_item_map_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "map_off", this.map_off, "msg_header_item_map_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "string_ids_size", this.string_ids_size, "msg_header_item_string_ids_size", UITool.icon4Counter()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "string_ids_size", this.string_ids_size, "msg_header_item_string_ids_size", UITool.icon4Counter()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "string_ids_off", this.string_ids_off, "msg_header_item_string_ids_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "string_ids_off", this.string_ids_off, "msg_header_item_string_ids_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "type_ids_size", this.type_ids_size, "msg_header_item_type_ids_size", UITool.icon4Counter()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "type_ids_size", this.type_ids_size, "msg_header_item_type_ids_size", UITool.icon4Counter()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "type_ids_off", this.type_ids_off, "msg_header_item_type_ids_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "type_ids_off", this.type_ids_off, "msg_header_item_type_ids_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "proto_ids_size", this.proto_ids_size, "msg_header_item_proto_ids_size", UITool.icon4Counter()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "proto_ids_size", this.proto_ids_size, "msg_header_item_proto_ids_size", UITool.icon4Counter()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "proto_ids_off", this.proto_ids_off, "msg_header_item_proto_ids_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "proto_ids_off", this.proto_ids_off, "msg_header_item_proto_ids_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "field_ids_size", this.field_ids_size, "msg_header_item_field_ids_size", UITool.icon4Counter()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "field_ids_size", this.field_ids_size, "msg_header_item_field_ids_size", UITool.icon4Counter()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "field_ids_off", this.field_ids_off, "msg_header_item_field_ids_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "field_ids_off", this.field_ids_off, "msg_header_item_field_ids_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "method_ids_size", this.method_ids_size, "msg_header_item_method_ids_size", UITool.icon4Counter()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "method_ids_size", this.method_ids_size, "msg_header_item_method_ids_size", UITool.icon4Counter()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "method_ids_off", this.method_ids_off, "msg_header_item_method_ids_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "method_ids_off", this.method_ids_off, "msg_header_item_method_ids_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "class_defs_size", this.class_defs_size, "msg_header_item_class_defs_size", UITool.icon4Counter()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "class_defs_size", this.class_defs_size, "msg_header_item_class_defs_size", UITool.icon4Counter()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "class_defs_off", this.class_defs_off, "msg_header_item_class_defs_off", UITool.icon4Offset()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "class_defs_off", this.class_defs_off, "msg_header_item_class_defs_off", UITool.icon4Offset()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - nodeTemp = TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "data_size", this.data_size, "msg_header_item_data_size", UITool.icon4Counter()); + nodeTemp = JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "data_size", this.data_size, "msg_header_item_data_size", UITool.icon4Counter()); floatPos = ((JTreeNodeFileComponent)nodeTemp.getUserObject()).getLastPosPlus1(); - TreeNodeGenerator.addNode(headerNode, floatPos, Type_uint.LENGTH, "data_off", this.data_off, "msg_header_item_data_off", UITool.icon4Offset()); + JTreeDexFile.addNode(headerNode, floatPos, Type_uint.LENGTH, "data_off", this.data_off, "msg_header_item_data_off", UITool.icon4Offset()); } /** diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/map_list.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/map_list.java index 1f75f13..e266aad 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/map_list.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/map_list.java @@ -6,7 +6,11 @@ */ package org.freeinternals.format.dex; +import java.io.IOException; +import javax.swing.tree.DefaultMutableTreeNode; import org.freeinternals.commonlib.core.FileComponent; +import org.freeinternals.commonlib.core.FileFormatException; +import org.freeinternals.commonlib.ui.GenerateTreeNode; /** * @@ -19,6 +23,94 @@ * */ @SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) -public class map_list extends FileComponent{ - +public class map_list extends FileComponent implements GenerateTreeNode { + + public final Type_uint size; + public final map_item[] list; + + map_list(PosDataInputStreamDex stream) throws IOException, FileFormatException { + super.startPos = stream.getPos(); + + this.size = stream.Dex_uint(); + DexFile.check_uint("map_list.size", this.size, stream.getPos()); + + if (this.size.value > 0) { + this.list = new map_item[(int) this.size.value]; + for (int i = 0; i < this.size.value; i++) { + this.list[i] = new map_item(stream); + } + } else { + this.list = null; + } + + super.length = stream.getPos() - super.startPos; + } + + @Override + public void generateTreeNode(DefaultMutableTreeNode parentNode) { + throw new UnsupportedOperationException("Not supported yet."); + } + + public static class map_item extends FileComponent implements GenerateTreeNode { + + /** + * Item Size In Bytes. + * + * @see map_list.TypeCodes#TYPE_MAP_LIST + */ + public static final int ITEM_SIZE = 12; + + public final Type_ushort type; + public final Type_ushort unused; + public final Type_uint size; + public final Type_uint offset; + + map_item(PosDataInputStreamDex stream) throws IOException, FileFormatException { + super.startPos = stream.getPos(); + this.type = stream.Dex_ushort(); + this.unused = stream.Dex_ushort(); + this.size = stream.Dex_uint(); + this.offset = stream.Dex_uint(); + super.length = stream.getPos() - super.startPos; + } + + @Override + public void generateTreeNode(DefaultMutableTreeNode parentNode) { + throw new UnsupportedOperationException("Not supported yet."); + } + } + + public enum TypeCodes { + TYPE_HEADER_ITEM(header_item.class, 0x0000), + TYPE_STRING_ID_ITEM(string_id_item.class, 0x0001), + TYPE_TYPE_ID_ITEM(type_id_item.class, 0x0002), + TYPE_PROTO_ID_ITEM(proto_id_item.class, 0x0003), + TYPE_FIELD_ID_ITEM(field_id_item.class, 0x0004), + TYPE_METHOD_ID_ITEM(method_id_item.class, 0x0005), + TYPE_CLASS_DEF_ITEM(class_def_item.class, 0x0006), + TYPE_CALL_SITE_ID_ITEM(null, 0x0007), + TYPE_METHOD_HANDLE_ITEM(method_handle_item.class, 0x0008), + TYPE_MAP_LIST(map_list.class, 0x1000), + TYPE_TYPE_LIST(type_list.class, 0x1001), + TYPE_ANNOTATION_SET_REF_LIST(annotation_set_ref_list.class, 0x1002), + TYPE_ANNOTATION_SET_ITEM(annotation_set_item.class, 0x1003), + TYPE_CLASS_DATA_ITEM(class_data_item.class, 0x2000), + TYPE_CODE_ITEM(code_item.class, 0x2001), + TYPE_STRING_DATA_ITEM(string_data_item.class, 0x2002), + TYPE_DEBUG_INFO_ITEM(debug_info_item.class, 0x2003), + TYPE_ANNOTATION_ITEM(annotation_item.class, 0x2004), + TYPE_ENCODED_ARRAY_ITEM(encoded_array_item.class, 0x2005), + TYPE_ANNOTATIONS_DIRECTORY_ITEM(annotations_directory_item.class, 0x2006), + TYPE_HIDDENAPI_CLASS_DATA_ITEM(null, 0xF000); + + public final Type_ushort value; + final Class item_type; + + private TypeCodes(Class clazz, int value) { + this.value = new Type_ushort(value); + this.item_type = clazz; + } + + } + } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/method_handle_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/method_handle_item.java index d31a6aa..7cfc430 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/method_handle_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/method_handle_item.java @@ -11,7 +11,7 @@ import org.freeinternals.commonlib.core.FileComponent; import org.freeinternals.commonlib.ui.GenerateTreeNode; import org.freeinternals.commonlib.ui.UITool; -import static org.freeinternals.format.dex.TreeNodeGenerator.addNode; +import static org.freeinternals.format.dex.JTreeDexFile.addNode; /** * @@ -28,8 +28,10 @@ public class method_handle_item extends FileComponent implements GenerateTreeNod /** * Item Size In Bytes. + * + * @see map_list.TypeCodes#TYPE_METHOD_HANDLE_ITEM */ - public static final int LENGTH = Type_ushort.LENGTH * 4; + public static final int ITEM_SIZE = 0x08; /** * type of the method handle. diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/method_id_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/method_id_item.java index 2286583..94a15a9 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/method_id_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/method_id_item.java @@ -7,30 +7,39 @@ package org.freeinternals.format.dex; import java.io.IOException; +import javax.swing.tree.DefaultMutableTreeNode; import org.freeinternals.commonlib.core.FileComponent; +import org.freeinternals.commonlib.ui.UITool; +import static org.freeinternals.format.dex.JTreeDexFile.addNode; /** * * @author Amos Shi * *
+ * java:S100 - Method names should comply with a naming convention --- We respect the name from DEX spec instead
  * java:S101 - Class names should comply with a naming convention --- We respect the name from DEX Spec instead
  * java:S116 - Field names should comply with a naming convention --- We respect the DEX spec name instead
  * java:S1104 - Class variable fields should not have public accessibility --- No, we like the simplified final value manner
  * 
*/ -@SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) -public class method_id_item extends FileComponent{ +@SuppressWarnings({"java:S100", "java:S101", "java:S116", "java:S1104"}) +public class method_id_item extends FileComponent implements GenerateTreeNodeDexFile { + /** * Item Size In Bytes. + * + * @see map_list.TypeCodes#TYPE_METHOD_ID_ITEM */ - public static final int LENGTH = 8; + public static final int ITEM_SIZE = 0x08; /** * index into the type_ids list for the definer of this method. This must be * a class or array type, and not a primitive type. */ public final Type_ushort class_idx; + private String clazz = null; + private String clazz_jls = null; /** * index into the proto_ids list for the prototype of this method. @@ -42,6 +51,7 @@ public class method_id_item extends FileComponent{ * must conform to the syntax for MemberName, defined above. */ public final Type_uint name_idx; + private String name = null; method_id_item(PosDataInputStreamDex stream) throws IOException { super.startPos = stream.getPos(); @@ -50,4 +60,89 @@ public class method_id_item extends FileComponent{ this.name_idx = stream.Dex_uint(); super.length = stream.getPos() - super.startPos; } + + + /** + * Get {@link #class_idx} name. + * + * @param dexFile Current {@link DexFile} + * @return class name + * @see #class_idx + */ + public String get_class(DexFile dexFile) { + if (this.clazz == null) { + this.clazz = dexFile.get_type_ids_string(class_idx.value); + } + return this.clazz; + } + + /** + * Get {@link #class_idx} name in Java Language Specification format. + * + * @param dexFile Current {@link DexFile} + * @return class name in JLS format + * @see #class_idx + */ + public String get_class_jls(DexFile dexFile) { + if (this.clazz_jls == null) { + // The class string could be an array, so we use the TypeJLSName + this.clazz_jls = dexFile.type_ids[class_idx.value].get_descriptor_jls(dexFile).TypeJLSName; + } + return this.clazz_jls; + } + + /** + * Get {@link #name_idx} name. + * + * @param dexFile Current {@link DexFile} + * @return field name + * @see #name_idx + */ + public String get_name(DexFile dexFile) { + if (this.name == null) { + this.name = dexFile.get_string_ids_string(name_idx.intValue()); + } + return this.name; + } + + /** + * String format of current {@link method_id_item}. + * + * @param dexFile Current {@link DexFile} + * @return String format of a method + */ + public String toString(DexFile dexFile) { + return String.format("%s.%s() return %s", this.get_class_jls(dexFile), this.get_name(dexFile), "todo"); + } + + @Override + public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) { + int floatPos = super.startPos; + + addNode(parentNode, + floatPos, + Type_ushort.LENGTH, + "class_idx", + String.format(FORMAT_STRING_STRING, this.class_idx, this.get_class_jls(dexFile)), + "msg_method_id_item__class_idx", + UITool.icon4Index()); + floatPos += Type_ushort.LENGTH; + + addNode(parentNode, + floatPos, + Type_ushort.LENGTH, + "proto_idx", + this.proto_idx, + "msg_method_id_item__proto_idx", + UITool.icon4Index()); + floatPos += Type_ushort.LENGTH; + + addNode(parentNode, + floatPos, + Type_uint.LENGTH, + "name_idx", + String.format(FORMAT_STRING_STRING, this.name_idx, this.get_name(dexFile)), + "msg_method_id_item__name_idx", + UITool.icon4Index()); + } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/proto_id_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/proto_id_item.java index 8aa10fe..bc15f7c 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/proto_id_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/proto_id_item.java @@ -7,25 +7,31 @@ package org.freeinternals.format.dex; import java.io.IOException; +import javax.swing.tree.DefaultMutableTreeNode; import org.freeinternals.commonlib.core.FileComponent; +import org.freeinternals.commonlib.ui.UITool; +import static org.freeinternals.format.dex.JTreeDexFile.addNode; /** * * @author Amos Shi * *
+ * java:S100 - Method names should comply with a naming convention --- We respect the name from DEX spec instead
  * java:S101 - Class names should comply with a naming convention --- We respect the name from DEX Spec instead
  * java:S116 - Field names should comply with a naming convention --- We respect the DEX spec name instead
  * java:S1104 - Class variable fields should not have public accessibility --- No, we like the simplified final value manner
  * 
*/ -@SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) -public class proto_id_item extends FileComponent { +@SuppressWarnings({"java:S100", "java:S101", "java:S116", "java:S1104"}) +public class proto_id_item extends FileComponent implements GenerateTreeNodeDexFile { /** * Item Size In Bytes. + * + * @see map_list.TypeCodes#TYPE_PROTO_ID_ITEM */ - public static final int LENGTH = 12; + public static final int ITEM_SIZE = 0x0c; /** * index into the string_ids list for the short-form descriptor string of @@ -34,11 +40,14 @@ public class proto_id_item extends FileComponent { * and parameters of this item. */ public Type_uint shorty_idx; + private String shorty = null; /** * index into the type_ids list for the return type of this prototype. */ public Type_uint return_type_idx; + private String return_type = null; + private String return_type_jls = null; /** * offset from the start of the file to the list of parameter types for this @@ -56,4 +65,78 @@ public class proto_id_item extends FileComponent { this.parameters_off = stream.Dex_uint(); super.length = stream.getPos() - super.startPos; } + + /** + * Get {@link #shorty_idx} text. + * + * @param dexFile Current {@link DexFile} + * @return shorty text + * @see #shorty_idx + */ + public String get_shorty(DexFile dexFile) { + if (this.shorty == null) { + this.shorty = dexFile.get_string_ids_string(shorty_idx.intValue()); + } + return this.shorty; + } + + /** + * Get {@link #return_type_idx} text. + * + * @param dexFile Current {@link DexFile} + * @return {@link #return_type_idx} text + * @see #return_type_idx + */ + public String get_return_type(DexFile dexFile) { + if (this.return_type == null) { + this.return_type = dexFile.get_type_ids_string(return_type_idx.intValue()); + } + return this.return_type; + } + + /** + * Get {@link #return_type_idx} text in Java Language Specification format. + * + * @param dexFile Current {@link DexFile} + * @return {@link #return_type_idx} text in JSL format + * @see #return_type_idx + */ + public String get_return_type_jls(DexFile dexFile) { + if (this.return_type_jls == null) { + this.return_type_jls = dexFile.type_ids[return_type_idx.intValue()].get_descriptor_jls(dexFile).toString(); + } + return this.return_type_jls; + } + + @Override + public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) { + int floatPos = super.startPos; + + addNode(parentNode, + floatPos, + Type_uint.LENGTH, + "shorty_idx", + String.format(FORMAT_STRING_STRING, this.shorty_idx, this.get_shorty(dexFile)), + "msg_proto_id_item__shorty_idx", + UITool.icon4Index()); + floatPos += Type_uint.LENGTH; + + addNode(parentNode, + floatPos, + Type_uint.LENGTH, + "return_type_idx", + String.format(FORMAT_STRING_STRING, this.return_type_idx, this.get_return_type_jls(dexFile)), + "msg_proto_id_item__return_type_idx", + UITool.icon4Return()); + floatPos += Type_uint.LENGTH; + + String param = (this.parameters_off.value == 0L) ? "no paramter" : "TO LOAD"; + addNode(parentNode, + floatPos, + Type_uint.LENGTH, + "parameters_off", + String.format(FORMAT_STRING_STRING, this.parameters_off, param), + "msg_proto_id_item__parameters_off", + UITool.icon4Offset()); + } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/string_data_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/string_data_item.java index 7192572..f285e95 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/string_data_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/string_data_item.java @@ -14,7 +14,7 @@ import org.freeinternals.commonlib.ui.GenerateTreeNode; import org.freeinternals.commonlib.ui.JTreeNodeFileComponent; import org.freeinternals.commonlib.ui.UITool; -import static org.freeinternals.format.dex.TreeNodeGenerator.addNode; +import static org.freeinternals.format.dex.JTreeDexFile.addNode; /** * @@ -65,7 +65,7 @@ public class string_data_item extends FileComponent implements GenerateTreeNode * @return String for the content */ public String getString() { - return new String(this.data, StandardCharsets.UTF_8); + return (this.data == null) ? "" : new String(this.data, StandardCharsets.UTF_8); } @Override @@ -74,10 +74,10 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode) { int floatPos = this.getStartPos(); int utf16Size = this.utf16_size.value; - nodeTemp = addNode(parentNode, floatPos, this.utf16_size.length, "utf16_size", utf16Size, "msg_string_data_item__utf16_size", UITool.icon4Shortcut()); + nodeTemp = addNode(parentNode, floatPos, this.utf16_size.length, "utf16_size", utf16Size, "msg_string_data_item__utf16_size", UITool.icon4Size()); floatPos = ((JTreeNodeFileComponent) nodeTemp.getUserObject()).getLastPosPlus1(); if (utf16Size > 0) { - addNode(parentNode, floatPos, this.data.length, "data", this.getString(), "msg_string_data_item__data", UITool.icon4Shortcut()); + addNode(parentNode, floatPos, this.data.length, "data", this.getString(), "msg_string_data_item__data", UITool.icon4Data()); } } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/string_id_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/string_id_item.java index c9ea4e6..d77e598 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/string_id_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/string_id_item.java @@ -11,7 +11,7 @@ import org.freeinternals.commonlib.core.FileComponent; import org.freeinternals.commonlib.ui.GenerateTreeNode; import org.freeinternals.commonlib.ui.UITool; -import static org.freeinternals.format.dex.TreeNodeGenerator.addNode; +import static org.freeinternals.format.dex.JTreeDexFile.addNode; /** * @@ -26,6 +26,11 @@ @SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) public class string_id_item extends FileComponent implements GenerateTreeNode { + /** + * @see map_list.TypeCodes#TYPE_STRING_ID_ITEM + */ + public static final int ITEM_SIZE = 0x04; + /** * offset from the start of the file to the string data for this item. The * offset should be to a location in the data section, and the data should diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/type_id_item.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/type_id_item.java index 344077b..0e92a0e 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/type_id_item.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/type_id_item.java @@ -7,22 +7,38 @@ 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.ui.GenerateTreeNode; +import org.freeinternals.commonlib.core.FileFormatException; +import org.freeinternals.commonlib.ui.UITool; +import org.freeinternals.format.classfile.SignatureConvertor; +import static org.freeinternals.format.dex.JTreeDexFile.addNode; /** + * Type identifiers list item. * * @author Amos Shi * *
+ * java:S100 - Method names should comply with a naming convention --- We respect the name from DEX spec instead
  * java:S101 - Class names should comply with a naming convention --- We respect the name from DEX Spec instead
  * java:S116 - Field names should comply with a naming convention --- We respect the DEX spec name instead
  * java:S1104 - Class variable fields should not have public accessibility --- No, we like the simplified final value manner
  * 
*/ -@SuppressWarnings({"java:S101", "java:S116", "java:S1104"}) -public class type_id_item extends FileComponent implements GenerateTreeNode { +@SuppressWarnings({"java:S100", "java:S101", "java:S116", "java:S1104"}) +public class type_id_item extends FileComponent implements GenerateTreeNodeDexFile { + + private static final Logger LOGGER = Logger.getLogger(type_id_item.class.getName()); + + /** + * Item size. + * + * @see map_list.TypeCodes#TYPE_TYPE_ID_ITEM + */ + public static final int ITEM_SIZE = 0x04; /** * index into the string_ids list for the descriptor string of this type. @@ -30,13 +46,62 @@ public class type_id_item extends FileComponent implements GenerateTreeNode { */ public Type_uint descriptor_idx; + /** + * Local cache for the {@link #get_descriptor_jls(DexFile)}. + */ + private SignatureConvertor.SignatureResult descriptor_jls = null; + type_id_item(PosDataInputStreamDex stream) throws IOException { super.startPos = stream.getPos(); this.descriptor_idx = stream.Dex_uint(); super.length = Type_uint.LENGTH; } + + /** + * Get descriptor text. + * + * @param dexFile Current {@link DexFile} + * @return Descriptor text + */ + public String get_descriptor(DexFile dexFile) { + return dexFile.get_string_ids_string(descriptor_idx.intValue()); + } + + /** + * Get parsed descriptor name in Java Language Specification format. + * + * @param dexFile Current {@link DexFile} + * @return Parsed descriptor name + */ + public SignatureConvertor.SignatureResult get_descriptor_jls(DexFile dexFile) { + if (this.descriptor_jls == null) { + String text = this.get_descriptor(dexFile); + if (text == null) { + LOGGER.warning(String.format("The current item points to a null string: position = 0x%08X", this.startPos)); + this.descriptor_jls = null; + } else { + try { + this.descriptor_jls = SignatureConvertor.methodReturnTypeJLS(text); + } catch (FileFormatException ex) { + // This should never happen + this.descriptor_jls = null; + LOGGER.log(Level.SEVERE, "The current type_id_item points to an invalid signature string", ex); + } + } + } + + return this.descriptor_jls; + } @Override - public void generateTreeNode(DefaultMutableTreeNode parentNode) { + public void generateTreeNode(DefaultMutableTreeNode parentNode, DexFile dexFile) { + addNode(parentNode, + this.startPos, + Type_uint.LENGTH, + "descriptor_idx", + String.format("%s - %s", descriptor_idx, this.get_descriptor(dexFile)), + "msg_type_id_item__descriptor_idx", + UITool.icon4Offset() + ); } } diff --git a/FormatDEX/src/main/java/org/freeinternals/format/dex/type_list.java b/FormatDEX/src/main/java/org/freeinternals/format/dex/type_list.java index b5fe8e6..e7bedf7 100644 --- a/FormatDEX/src/main/java/org/freeinternals/format/dex/type_list.java +++ b/FormatDEX/src/main/java/org/freeinternals/format/dex/type_list.java @@ -32,8 +32,8 @@ public class type_list extends FileComponent implements GenerateTreeNode { super.startPos = stream.getPos(); this.size = stream.Dex_uint(); if (this.size.value > 0) { - DexFile.checkUint("type_list.size", this.size, stream.getPos()); - this.list = new type_item[(int)this.size.value]; + DexFile.check_uint("type_list.size", this.size, stream.getPos()); + this.list = new type_item[(int) this.size.value]; for (int i = 0; i < this.size.value; i++) { this.list[i] = new type_item(stream); } @@ -44,6 +44,11 @@ public class type_list extends FileComponent implements GenerateTreeNode { super.length = stream.getPos() - super.startPos; } + @Override + public String toString() { + return "TODO"; + } + @Override public void generateTreeNode(DefaultMutableTreeNode parentNode) { throw new UnsupportedOperationException("Not supported yet."); @@ -51,6 +56,13 @@ public void generateTreeNode(DefaultMutableTreeNode parentNode) { public static class type_item extends FileComponent implements GenerateTreeNode { + /** + * Item Size In Bytes. + * + * @see map_list.TypeCodes#TYPE_TYPE_LIST + */ + public static final int ITEM_SIZE = 2; + public final Type_ushort type_idx; type_item(PosDataInputStreamDex stream) throws IOException, FileFormatException { diff --git a/FormatDEX/src/main/resources/org/freeinternals/format/dex/MessagesBundle.properties b/FormatDEX/src/main/resources/org/freeinternals/format/dex/MessagesBundle.properties index 6308760..de7033e 100644 --- a/FormatDEX/src/main/resources/org/freeinternals/format/dex/MessagesBundle.properties +++ b/FormatDEX/src/main/resources/org/freeinternals/format/dex/MessagesBundle.properties @@ -40,6 +40,7 @@ msg_header_item_data_size = Size of data section in bytes. Must be an even multi msg_header_item_data_off = offset from the start of the file to the start of the data section. msg_string_id_item__string_data_off = offset from the start of the file to the string data for this item. The offset should be to a location in the data section, and the data should be in the format specified by "string_data_item" below. There is no alignment requirement for the offset. +msg_string_data_item = Appears in the data section of the ELF file. msg_string_data_item__utf16_size = size of this string, in UTF-16 code units (which is the "string length" in many systems). That is, this is the decoded length of the string. (The encoded length is implied by the position of the 0 byte.) msg_string_data_item__data = a series of MUTF-8 code units (a.k.a. octets, a.k.a. bytes) followed by a byte of value 0. See "MUTF-8 (Modified UTF-8) Encoding" above for details and discussion about the data format.