From 96b803c8821bac22418e48f976adf0132e3d9b24 Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Wed, 11 Jan 2012 21:42:08 -0800 Subject: [PATCH] Add support for version 36 dex files --- .../src/main/java/org/jf/dexlib/DexFile.java | 19 ++++--- .../main/java/org/jf/dexlib/HeaderItem.java | 52 ++++++++++++++++--- smali/src/main/java/org/jf/smali/main.java | 6 +++ 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/dexlib/src/main/java/org/jf/dexlib/DexFile.java b/dexlib/src/main/java/org/jf/dexlib/DexFile.java index df9fa1ae..24e92921 100644 --- a/dexlib/src/main/java/org/jf/dexlib/DexFile.java +++ b/dexlib/src/main/java/org/jf/dexlib/DexFile.java @@ -336,12 +336,19 @@ public class DexFile boolean isDex = false; this.isOdex = false; - if (Arrays.equals(magic, HeaderItem.MAGIC)) { - isDex = true; - } else if (Arrays.equals(magic, OdexHeader.MAGIC_35)) { - isOdex = true; - } else if (Arrays.equals(magic, OdexHeader.MAGIC_36)) { - isOdex = true; + for (int i=0; i { * the file format magic number, represented as the * low-order bytes of a string */ - public static final byte[] MAGIC = new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00};//"dex\n035" + '\0'; + public static final byte[][] MAGIC_VALUES = new byte[][] { + new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x35, 0x00}, //"dex\n035" + '\0'; + new byte[] {0x64, 0x65, 0x78, 0x0A, 0x30, 0x33, 0x36, 0x00}}; //"dex\n036" + '\0'; /** size of this section, in bytes */ @@ -47,6 +49,9 @@ public class HeaderItem extends Item { private static final int LITTLE_ENDIAN = 0x12345678; private static final int BIG_ENDIAN = 0x78562312; + /* Which magic value to use when writing out the header item */ + private int magic_index = 0; + /** * Create a new uninitialized HeaderItem * @param dexFile The DexFile containing this HeaderItem @@ -59,10 +64,25 @@ public class HeaderItem extends Item { protected void readItem(Input in, ReadContext readContext) { byte[] readMagic = in.readBytes(8); - for (int i=0; i<8; i++) { - if (MAGIC[i] != readMagic[i]) { - throw new RuntimeException("The magic value is not the expected value"); + boolean success = false; + for (int i=0; i { in.readInt(); //data_off } + /** + * Sets the dex version number. + * + * 35 is the default. + * 36 is for dex files that use extended opcodes (only works with ICS+) + * + * @param version - must be either 35 or 36 + */ + public void setVersion(int version) { + if (version == 35) { + magic_index = 0; + return; + } + if (version == 36) { + magic_index = 1; + return; + } + throw new RuntimeException("Invalid dex version number passed to setVersion"); + } + /** {@inheritDoc} */ protected int placeItem(int offset) { return HEADER_SIZE; @@ -134,11 +174,11 @@ public class HeaderItem extends Item { protected void writeItem(AnnotatedOutput out) { StringBuilder magicBuilder = new StringBuilder(); for (int i=0; i<8; i++) { - magicBuilder.append((char)MAGIC[i]); + magicBuilder.append((char)MAGIC_VALUES[magic_index][i]); } out.annotate("magic: " + Utf8Utils.escapeString(magicBuilder.toString())); - out.write(MAGIC); + out.write(MAGIC_VALUES[magic_index]); out.annotate("checksum"); out.writeInt(0); diff --git a/smali/src/main/java/org/jf/smali/main.java b/smali/src/main/java/org/jf/smali/main.java index e65f4e65..39a48f35 100644 --- a/smali/src/main/java/org/jf/smali/main.java +++ b/smali/src/main/java/org/jf/smali/main.java @@ -107,6 +107,7 @@ public class main { boolean oldLexer = false; boolean printTokens = false; + boolean apiSet = false; int apiLevel = 14; String outputDexFile = "out.dex"; @@ -141,6 +142,7 @@ public class main { break; case 'a': apiLevel = Integer.parseInt(commandLine.getOptionValue("a")); + apiSet = true; break; case 'D': dumpFileName = commandLine.getOptionValue("D", outputDexFile + ".dump"); @@ -194,6 +196,10 @@ public class main { DexFile dexFile = new DexFile(); + if (apiSet && apiLevel >= 14) { + dexFile.HeaderItem.setVersion(36); + } + boolean errors = false; for (File file: filesToProcess) {