java.lang.Object
com.pnfsoftware.jeb.core.units.code.android.DexUtil

public class DexUtil extends Object
Dex utility routines.
  • Method Details

    • getVersion

      public static final int getVersion(IBinaryUnit unit) throws ParseException
      Extract the version number from an Android binary unit.
      Parameters:
      unit - an Android binary unit respecting the standard header (xxxxNNN0), such as dex, vdex, cdex, art, etc.
      Returns:
      the version number
      Throws:
      ParseException - on parsing error
    • bytearrayULEInt16ToInt

      public static int bytearrayULEInt16ToInt(byte[] data, int pos)
      Read a little-endian uint16 short.
      Parameters:
      data -
      pos -
      Returns:
    • bytearrayULEInt32ToInt

      public static int bytearrayULEInt32ToInt(byte[] data, int pos)
      Read a little-endian uint32 int.
      Parameters:
      data -
      pos -
      Returns:
    • bytearraySLEB128ToInt

      public static int bytearraySLEB128ToInt(byte[] data, int pos, int[] readsize)
      Read a signed LEB128-encoded int.
      Parameters:
      data -
      pos -
      readsize -
      Returns:
    • bytearrayULEB128ToInt

      public static int bytearrayULEB128ToInt(byte[] data, int pos, int[] readsize)
      Read an unsigned LEB128-encoded int.
      Parameters:
      data -
      pos -
      readsize -
      Returns:
    • bytearrayULEB128P1ToInt

      public static int bytearrayULEB128P1ToInt(byte[] data, int pos, int[] readsize)
      Read an unsigned LEB128-encoded int shifted by 1.
      Parameters:
      data -
      pos -
      readsize -
      Returns:
    • bytearrayMUTF8ToStringFast

      public static String bytearrayMUTF8ToStringFast(byte[] data, int pos, int[] readsize, int expectedLength)
      Decode a MUTF-8 encoded string whose length is known. The encoded string must be terminated by a null (0) byte, per the JVM MUTF-8 specifications.
      Parameters:
      data - bytes of the encoded string
      pos - start position in the bytes buffer
      readsize - optional one-element output array
      expectedLength - expected length of the constructed string (in chars); the method will throw if the constructed string's length exceeds the expected length
      Returns:
      the string
    • bytearrayMUTF8ToString

      public static String bytearrayMUTF8ToString(byte[] data, int pos, int[] readsize)
      Decode a MUTF-8 encoded string whose length is unknown. The encoded string must be terminated by a null (0) byte, per the JVM MUTF-8 specifications.

      If the length of the constructed string is known, it is recommended to use bytearrayMUTF8ToStringFast instead.

      Parameters:
      data - bytes of the encoded string
      pos - start position in the bytes buffer
      readsize - optional one-element output array
      Returns:
      the string
    • stringFromMUTF8

      public static String stringFromMUTF8(byte[] data)
      Decode a String encoded as MUTF-8.
      Parameters:
      data - MUTF-8 buffer (always zero-terminated)
      Returns:
      the string
    • stringToMUTF8

      public static byte[] stringToMUTF8(String str)
      Encode a String to MUTF-8.
      Parameters:
      str - a string
      Returns:
      a MUTF-8 byte buffer (always zero-terminated)
    • stringToMUTF8

      public static byte[] stringToMUTF8(String str, boolean appendZero)
      Encode a String to MUTF-8.
      Parameters:
      str - a string
      appendZero - if true, a zero-byte is appended to the resulting buffer
      Returns:
      a MUTF-8 byte buffer
    • convertDexFlagsToCodeFlags

      public static int convertDexFlagsToCodeFlags(int nativeFlags)
      Convert native Dalvik flags to generic ICodeItem flags.
      Parameters:
      nativeFlags -
      Returns:
    • validateFlags

      public static void validateFlags(int f)
      Validate Dalvik flags: this method throws if some flags are undefined Dalvik flags.
      Parameters:
      f -
    • validateClassFlags

      public static void validateClassFlags(int f)
      Validate Dalvik class item flags: this method throws if some flags are undefined or illegal for class items.
      Parameters:
      f -
    • validateFieldFlags

      public static void validateFieldFlags(int f)
      Validate Dalvik field item flags: this method throws if some flags are undefined or illegal for field items.
      Parameters:
      f -
    • validateMethodFlags

      public static void validateMethodFlags(int f)
      Validate Dalvik method item flags: this method throws if some flags are undefined or illegal for method items.
      Parameters:
      f -
    • formatAccessFlags

      public static String formatAccessFlags(int f, int add_final_space)
      Format Java access flags to an appropriate string.
      Parameters:
      f - Flags, as defined by the Dalvik specs
      add_final_space - if 1, append a trailing space; if -1, append a trailing space only if the access flags string is not empty
      Returns:
    • determineBestBase

      public static int determineBestBase(long value)
    • formatTypenames

      public static final String formatTypenames(IDexUnit dex, Collection<Integer> indices)
      Format a list of DEX types.
      Parameters:
      dex - unit
      indices - DEX type indices
      Returns:
    • formatFieldsigs

      public static final String formatFieldsigs(IDexUnit dex, Collection<Integer> indices)
      Format a list of DEX fields.
      Parameters:
      dex - unit
      indices - DEX method indices
      Returns:
    • formatMethodsigs

      public static final String formatMethodsigs(IDexUnit dex, Collection<Integer> indices)
      Format a list of DEX methods.
      Parameters:
      dex - unit
      indices - DEX method indices
      Returns:
    • getStaticFieldInitializer

      public static IDexValue getStaticFieldInitializer(IDexClass c, IDexFieldData fd)
      Retrieve the initial value of a static final class field.
      Parameters:
      c - a dex class object
      fd - field definition of an internal field
      Returns:
      the initial field value, null if none or on error
    • generateDefaultJniNames

      public static String[] generateDefaultJniNames(String msig)
      Generate default JNI method names used for auto-binding.
      Parameters:
      msig - java method signature (e.g. La/b/C;->foo(I)Ljava/lang/String;)
      Returns:
      an array of two routine names (with and without parameter signature), or null on error
    • getDebugParameterNames

      public static List<String> getDebugParameterNames(IDexUnit dex, IDexMethodData md)
      Retrieve the list of parameters names provided by the debug metadata of a dex method.
      Parameters:
      dex -
      md - non-abstract method body
      Returns:
      a list of names; null if no debug info is present; else, the list contains all parameter names in order, except for 'this' if the method is non-static; entries referring to invalid strings will hold null references; the list may be less than the actual number of method parameters
    • getAnnotatedParameterNames

      public static List<String> getAnnotatedParameterNames(IDexUnit dex, IDexMethodData md)
      Retrieve the list of parameters names provided by a MethodParameters annotation.
      Parameters:
      dex -
      md - method body
      Returns:
      a list of names; null if no MethodParameters annotation info is present; else, the list contains all parameter names in order, except for 'this' if the method is non-static; entries referring to invalid strings will hold null references; the list may be less than the actual number of method parameters
    • getMethodParametersInfo

      public static ParametersInfo getMethodParametersInfo(IDexUnit dex, IDexMethodData md)
      Generate method parameters' registers information.
      Parameters:
      dex -
      md -
      Returns:
    • getMethodParametersInfo

      public static ParametersInfo getMethodParametersInfo(String shorty, boolean isStaticMethod)
      Generate method parameters' registers information.
      Parameters:
      shorty -
      isStaticMethod -
      Returns:
    • getMethodSlotCount

      public static int getMethodSlotCount(String shorty, boolean isStaticMethod)
      Determine the number of slots required by a method to hold all of its parameters (including `this` if the method is not static).
      Parameters:
      shorty - method's shorty prototype, e.g. BILJ for byte foo(int, String, long), V for void bar()
      isStaticMethod -
      Returns:
    • getMethodParameterIndices

      public static int[] getMethodParameterIndices(IDexMethod m)
      Retrieve an array of register indices holding the method parameters. Unlike getMethodParametersInfo, the list returned by this method includes `this` (for non-static methods). Double-slot variables are represented by their first register in the pair.
      Parameters:
      m - an internal, non-abstract dex method
      Returns:
      an array of register indices
    • isSubtypeOf

      public static boolean isSubtypeOf(IDexUnit dex, int typeIndex, int candidateParentTypeIndex)
      Parameters:
      dex -
      typeIndex -
      candidateParentTypeIndex -
      Returns:
    • getMemberClasses

      public static List<IDexClass> getMemberClasses(IDexUnit dex, IDexClass c)
      Parameters:
      dex -
      c -
      Returns:
    • getMemberClasses

      public static List<IDexClass> getMemberClasses(IDexUnit dex, IDexMethod m)
      Parameters:
      dex -
      m -
      Returns:
    • getParentClass

      public static IDexClass getParentClass(IDexUnit dex, IDexClass c)
      Parameters:
      dex -
      c -
      Returns:
    • getSuperClass

      public static IDexClass getSuperClass(IDexUnit dex, IDexClass c)
    • isSimpleName

      public static boolean isSimpleName(String s, int dexVersion)
      Verify if the provided string is a valid dex SimpleName.

      Ref: https://source.android.com/docs/core/runtime/dex-format#simplename

      Parameters:
      s - a Dalvik simple name, such as a non-qualified class/method/field name
      dexVersion - optional dex version; 0 means latest
      Returns:
    • parseSimpleName

      public static int parseSimpleName(String s, int start, int dexVersion)
      Determine if the token at the provided index is the start of a SimpleName. The end offset is provided.

      Ref: https://source.android.com/docs/core/runtime/dex-format#simplename

      Parameters:
      s - a string
      start - simple name start offset
      dexVersion - optional dex version; 0 means latest
      Returns:
      token end offset, -1 on error
    • isInternalClassname

      public static boolean isInternalClassname(String s, boolean validate, List<String> elements, int dexVersion)
      Determine whether a string looks like a valid internal-form (jvm) class name. Arrays are not accepted.
      Parameters:
      s - the input string, e.g. Lcom/abc/Foo;
      validate - if true, verify the legality of the simple names of the class name
      elements - if non-null, an output sink used to collect the simple names of the input class name
      dexVersion - optional dex version (0 means latest)
      Returns:
    • isClassname

      public static boolean isClassname(String s, boolean validate, List<String> elements, int dexVersion)
      Determine whether a string looks like a valid binary-form (dot-separated) class name. Arrays are not accepted.
      Parameters:
      s - the input string, e.g. com.abc.Foo
      validate - if true, verify the legality of the simple names of the class name
      elements - if non-null, an output sink used to collect the simple names of the input class name
      dexVersion - optional dex version (0 means latest)
      Returns:
    • getStringSafe

      public static String getStringSafe(IDexUnit dex, int index, String defval)
    • findAnnotation

      public static IDexAnnotation findAnnotation(IDexUnit dex, Collection<IDexAnnotationItem> aicoll, String requestedType, Integer requestedVisibility)
      Find an annotation by type and optional visibility.
      Parameters:
      dex - owner dex unit
      aicoll - collection of annotation items
      requestedType - mandatory annotation type (internal signature)
      requestedVisibility - optional visibility (see IDexAnnotationItem)
      Returns:
      the annotation, or null
    • findAnnotationElement

      public static IDexValue findAnnotationElement(IDexUnit dex, IDexAnnotation annotation, String name)
      Find an annotation element by name.
      Parameters:
      dex - owner dex unit
      annotation - an annotation
      name - the element name
      Returns:
      the value associated with the element, or null
    • findParentApk

      public static IApkUnit findParentApk(IDexUnit dex)
      Attempt to retrieve the container APK unit of a Dex. The parent unit will be examined.
      Parameters:
      dex - dex unit
      Returns:
      the apk unit or null
    • findPackageName

      public static String findPackageName(IDexUnit dex)
      Attempt to retrieve the package name of a Dex. The parent unit will be examined. If it is an APK unit, the package name will be returned.
      Parameters:
      dex - dex unit
      Returns:
      the package name or null
    • findInternalVirtualMethodTarget

      public static IDexMethod findInternalVirtualMethodTarget(IDexUnit dex, IDexClass cl, String mname, String... parameterTypes)
      Check if a dex method is present in the provided class or if a super method is present in one of its super classes. For internal methods only.
      Parameters:
      dex - dex unit
      cl - a class
      mname - method name
      parameterTypes - list of parameter signatures
      Returns:
      the resolved internal dex method, or null