mirror of
https://github.com/revanced/smali.git
synced 2025-06-13 04:27:38 +02:00
Add support for version 36 dex files
This commit is contained in:
@ -336,12 +336,19 @@ public class DexFile
|
|||||||
boolean isDex = false;
|
boolean isDex = false;
|
||||||
this.isOdex = false;
|
this.isOdex = false;
|
||||||
|
|
||||||
if (Arrays.equals(magic, HeaderItem.MAGIC)) {
|
for (int i=0; i<HeaderItem.MAGIC_VALUES.length; i++) {
|
||||||
isDex = true;
|
byte[] magic_value = HeaderItem.MAGIC_VALUES[i];
|
||||||
} else if (Arrays.equals(magic, OdexHeader.MAGIC_35)) {
|
if (Arrays.equals(magic, magic_value)) {
|
||||||
isOdex = true;
|
isDex = true;
|
||||||
} else if (Arrays.equals(magic, OdexHeader.MAGIC_36)) {
|
break;
|
||||||
isOdex = true;
|
}
|
||||||
|
}
|
||||||
|
if (!isDex) {
|
||||||
|
if (Arrays.equals(magic, OdexHeader.MAGIC_35)) {
|
||||||
|
isOdex = true;
|
||||||
|
} else if (Arrays.equals(magic, OdexHeader.MAGIC_36)) {
|
||||||
|
isOdex = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOdex) {
|
if (isOdex) {
|
||||||
|
@ -37,7 +37,9 @@ public class HeaderItem extends Item<HeaderItem> {
|
|||||||
* the file format magic number, represented as the
|
* the file format magic number, represented as the
|
||||||
* low-order bytes of a string
|
* 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 */
|
/** size of this section, in bytes */
|
||||||
@ -47,6 +49,9 @@ public class HeaderItem extends Item<HeaderItem> {
|
|||||||
private static final int LITTLE_ENDIAN = 0x12345678;
|
private static final int LITTLE_ENDIAN = 0x12345678;
|
||||||
private static final int BIG_ENDIAN = 0x78562312;
|
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 <code>HeaderItem</code>
|
* Create a new uninitialized <code>HeaderItem</code>
|
||||||
* @param dexFile The <code>DexFile</code> containing this <code>HeaderItem</code>
|
* @param dexFile The <code>DexFile</code> containing this <code>HeaderItem</code>
|
||||||
@ -59,10 +64,25 @@ public class HeaderItem extends Item<HeaderItem> {
|
|||||||
protected void readItem(Input in, ReadContext readContext) {
|
protected void readItem(Input in, ReadContext readContext) {
|
||||||
byte[] readMagic = in.readBytes(8);
|
byte[] readMagic = in.readBytes(8);
|
||||||
|
|
||||||
for (int i=0; i<8; i++) {
|
boolean success = false;
|
||||||
if (MAGIC[i] != readMagic[i]) {
|
for (int i=0; i<MAGIC_VALUES.length; i++) {
|
||||||
throw new RuntimeException("The magic value is not the expected value");
|
byte[] magic_value = MAGIC_VALUES[i];
|
||||||
|
boolean matched = true;
|
||||||
|
for (int j=0; j<8; i++) {
|
||||||
|
if (magic_value[j] != readMagic[j]) {
|
||||||
|
matched = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (matched) {
|
||||||
|
success = true;
|
||||||
|
magic_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
throw new RuntimeException("Unrecognized dex magic value");
|
||||||
}
|
}
|
||||||
|
|
||||||
in.readBytes(20); //checksum
|
in.readBytes(20); //checksum
|
||||||
@ -125,6 +145,26 @@ public class HeaderItem extends Item<HeaderItem> {
|
|||||||
in.readInt(); //data_off
|
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} */
|
/** {@inheritDoc} */
|
||||||
protected int placeItem(int offset) {
|
protected int placeItem(int offset) {
|
||||||
return HEADER_SIZE;
|
return HEADER_SIZE;
|
||||||
@ -134,11 +174,11 @@ public class HeaderItem extends Item<HeaderItem> {
|
|||||||
protected void writeItem(AnnotatedOutput out) {
|
protected void writeItem(AnnotatedOutput out) {
|
||||||
StringBuilder magicBuilder = new StringBuilder();
|
StringBuilder magicBuilder = new StringBuilder();
|
||||||
for (int i=0; i<8; i++) {
|
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.annotate("magic: " + Utf8Utils.escapeString(magicBuilder.toString()));
|
||||||
out.write(MAGIC);
|
out.write(MAGIC_VALUES[magic_index]);
|
||||||
|
|
||||||
out.annotate("checksum");
|
out.annotate("checksum");
|
||||||
out.writeInt(0);
|
out.writeInt(0);
|
||||||
|
@ -107,6 +107,7 @@ public class main {
|
|||||||
boolean oldLexer = false;
|
boolean oldLexer = false;
|
||||||
boolean printTokens = false;
|
boolean printTokens = false;
|
||||||
|
|
||||||
|
boolean apiSet = false;
|
||||||
int apiLevel = 14;
|
int apiLevel = 14;
|
||||||
|
|
||||||
String outputDexFile = "out.dex";
|
String outputDexFile = "out.dex";
|
||||||
@ -141,6 +142,7 @@ public class main {
|
|||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
||||||
|
apiSet = true;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
dumpFileName = commandLine.getOptionValue("D", outputDexFile + ".dump");
|
dumpFileName = commandLine.getOptionValue("D", outputDexFile + ".dump");
|
||||||
@ -194,6 +196,10 @@ public class main {
|
|||||||
|
|
||||||
DexFile dexFile = new DexFile();
|
DexFile dexFile = new DexFile();
|
||||||
|
|
||||||
|
if (apiSet && apiLevel >= 14) {
|
||||||
|
dexFile.HeaderItem.setVersion(36);
|
||||||
|
}
|
||||||
|
|
||||||
boolean errors = false;
|
boolean errors = false;
|
||||||
|
|
||||||
for (File file: filesToProcess) {
|
for (File file: filesToProcess) {
|
||||||
|
Reference in New Issue
Block a user