作者:郭嘉
邮箱:[email protected]
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWells
【Android SDK程序逆向分析与破解系列】章节索引
【Android SDK程序逆向分析与破解系列】之一:Android安装程序APK分析
【Android SDK程序逆向分析与破解系列】之二:Android可执行程序DEX分析(一)
【Android SDK程序逆向分析与破解系列】之三:Android可执行程序DEX分析(二)
【Android SDK程序逆向分析与破解系列】之四:Android可执行程序ODEX分析
【Android SDK程序逆向分析与破解系列】之五:Android APK的静态分析
一 DEX文件结构体分析
Dalvik虚拟机解析DEX文件的内容,最终将其映射成DexMapList数据结构,DexHeader结构中的mapOff字段指明了DexMapList结构在DEX文件中的偏移。
#ifndef LIBDEX_DEXFILE_H_
#define LIBDEX_DEXFILE_H_
#include "vm/Common.h" // basic type defs, e.g. u1/u2/u4/u8, and LOG
#include "libdex/SysUtil.h"
/*
* gcc-style inline management -- ensures we have a copy of all functions
* in the library, so code that links against us will work whether or not
* it was built with optimizations enabled.
*/
#ifndef _DEX_GEN_INLINES /* only defined by DexInlines.c */
# define DEX_INLINE extern __inline__
#else
# define DEX_INLINE
#endif
/* DEX file magic number */
#define DEX_MAGIC "dex\n"
/* current version, encoded in 4 bytes of ASCII */
#define DEX_MAGIC_VERS "036\0"
/*
* older but still-recognized version (corresponding to Android API
* levels 13 and earlier
*/
#define DEX_MAGIC_VERS_API_13 "035\0"
/* same, but for optimized DEX header */
#define DEX_OPT_MAGIC "dey\n"
#define DEX_OPT_MAGIC_VERS "036\0"
#define DEX_DEP_MAGIC "deps"
/*
* 160-bit SHA-1 digest.
*/
enum { kSHA1DigestLen = 20,
kSHA1DigestOutputLen = kSHA1DigestLen*2 +1 };
/* general constants */
enum {
kDexEndianConstant = 0x12345678, /* the endianness indicator */
kDexNoIndex = 0xffffffff, /* not a valid index value */
};
/*
* Enumeration of all the primitive types.
*/
enum PrimitiveType {
PRIM_NOT = 0, /* value is a reference type, not a primitive type */
PRIM_VOID = 1,
PRIM_BOOLEAN = 2,
PRIM_BYTE = 3,
PRIM_SHORT = 4,
PRIM_CHAR = 5,
PRIM_INT = 6,
PRIM_LONG = 7,
PRIM_FLOAT = 8,
PRIM_DOUBLE = 9,
};
/*
* access flags and masks; the "standard" ones are all <= 0x4000
*
* Note: There are related declarations in vm/oo/Object.h in the ClassFlags
* enum.
*/
enum {
ACC_PUBLIC = 0x00000001, // class, field, method, ic
ACC_PRIVATE = 0x00000002, // field, method, ic
ACC_PROTECTED = 0x00000004, // field, method, ic
ACC_STATIC = 0x00000008, // field, method, ic
ACC_FINAL = 0x00000010, // class, field, method, ic
ACC_SYNCHRONIZED = 0x00000020, // method (only allowed on natives)
ACC_SUPER = 0x00000020, // class (not used in Dalvik)
ACC_VOLATILE = 0x00000040, // field
ACC_BRIDGE = 0x00000040, // method (1.5)
ACC_TRANSIENT = 0x00000080, // field
ACC_VARARGS = 0x00000080, // method (1.5)
ACC_NATIVE = 0x00000100, // method
ACC_INTERFACE = 0x00000200, // class, ic
ACC_ABSTRACT = 0x00000400, // class, method, ic
ACC_STRICT = 0x00000800, // method
ACC_SYNTHETIC = 0x00001000, // field, method, ic
ACC_ANNOTATION = 0x00002000, // class, ic (1.5)
ACC_ENUM = 0x00004000, // class, field, ic (1.5)
ACC_CONSTRUCTOR = 0x00010000, // method (Dalvik only)
ACC_DECLARED_SYNCHRONIZED =
0x00020000, // method (Dalvik only)
ACC_CLASS_MASK =
(ACC_PUBLIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT
| ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM),
ACC_INNER_CLASS_MASK =
(ACC_CLASS_MASK | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC),
ACC_FIELD_MASK =
(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL
| ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC | ACC_ENUM),
ACC_METHOD_MASK =
(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL
| ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS | ACC_NATIVE
| ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC | ACC_CONSTRUCTOR
| ACC_DECLARED_SYNCHRONIZED),
};
/* annotation constants */
enum {
kDexVisibilityBuild = 0x00, /* annotation visibility */
kDexVisibilityRuntime = 0x01,
kDexVisibilitySystem = 0x02,
kDexAnnotationByte = 0x00,
kDexAnnotationShort = 0x02,
kDexAnnotationChar = 0x03,
kDexAnnotationInt = 0x04,
kDexAnnotationLong = 0x06,
kDexAnnotationFloat = 0x10,
kDexAnnotationDouble = 0x11,
kDexAnnotationString = 0x17,
kDexAnnotationType = 0x18,
kDexAnnotationField = 0x19,
kDexAnnotationMethod = 0x1a,
kDexAnnotationEnum = 0x1b,
kDexAnnotationArray = 0x1c,
kDexAnnotationAnnotation = 0x1d,
kDexAnnotationNull = 0x1e,
kDexAnnotationBoolean = 0x1f,
kDexAnnotationValueTypeMask = 0x1f, /* low 5 bits */
kDexAnnotationValueArgShift = 5,
};
/* map item type codes */
enum {
kDexTypeHeaderItem = 0x0000,
kDexTypeStringIdItem = 0x0001,
kDexTypeTypeIdItem = 0x0002,
kDexTypeProtoIdItem = 0x0003,
kDexTypeFieldIdItem = 0x0004,
kDexTypeMethodIdItem = 0x0005,
kDexTypeClassDefItem = 0x0006,
kDexTypeMapList = 0x1000,
kDexTypeTypeList = 0x1001,
kDexTypeAnnotationSetRefList = 0x1002,
kDexTypeAnn