mirror of
https://github.com/revanced/smali.git
synced 2025-05-02 15:44:30 +02:00
Add initial support for N preview odexes
This commit is contained in:
parent
bccdc809fa
commit
c4948a5c49
@ -21,4 +21,13 @@ fab6788358dfb64e5c370611ddbbbffab0ed0553 - 67
|
||||
6e2d5747d00697a25251d25dd33b953e54709507 - 68 (revert of 54b62480)
|
||||
0747466fca310eedea5fc49e37d54f240a0b3c0f - 69 (re-commit of 54b62480)
|
||||
501fd635a557645ab05f893c56e1f358e21bab82 - 70
|
||||
99170c636dfae4908b102347cfe9f92bad1881cc - 71
|
||||
99170c636dfae4908b102347cfe9f92bad1881cc - 71
|
||||
3cfa4d05afa76e19ca99ec964b535a15c73683f0 - 72
|
||||
d9786b0e5be23ea0258405165098b4216579209c - 73
|
||||
- fast class lookup table
|
||||
a4f1220c1518074db18ca1044e9201492975750b - 74
|
||||
- bootclasspath list was added
|
||||
625a64aad13905d8a2454bf3cc0e874487b110d5 - 75
|
||||
- class offsets moved out to a separate table
|
||||
919f5536182890d2e03f59b961acf8f7c836ff61 - 74 (revert of 625a64aa)
|
||||
9bdf108885a27ba05fae8501725649574d7c491b - 75 (re-commit of 625a64aa)
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
package org.jf.dexlib2.dexbacked;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import org.jf.dexlib2.Opcodes;
|
||||
import org.jf.dexlib2.dexbacked.OatFile.SymbolTable.Symbol;
|
||||
@ -38,11 +39,13 @@ import org.jf.dexlib2.dexbacked.raw.HeaderItem;
|
||||
import org.jf.util.AbstractForwardSequentialList;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.AbstractList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@ -54,7 +57,7 @@ public class OatFile extends BaseDexBuffer {
|
||||
// These are the "known working" versions that I have manually inspected the source for.
|
||||
// Later version may or may not work, depending on what changed.
|
||||
private static final int MIN_OAT_VERSION = 56;
|
||||
private static final int MAX_OAT_VERSION = 71;
|
||||
private static final int MAX_OAT_VERSION = 75;
|
||||
|
||||
public static final int UNSUPPORTED = 0;
|
||||
public static final int SUPPORTED = 1;
|
||||
@ -148,6 +151,18 @@ public class OatFile extends BaseDexBuffer {
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<String> getBootClassPath() {
|
||||
if (getOatVersion() < 75) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
String bcp = oatHeader.getKeyValue("bootclasspath");
|
||||
if (bcp == null) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
return Arrays.asList(bcp.split(":"));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<OatDexFile> getDexFiles() {
|
||||
return new AbstractForwardSequentialList<OatDexFile>() {
|
||||
@ -174,11 +189,21 @@ public class OatFile extends BaseDexBuffer {
|
||||
|
||||
offset += 4; // checksum
|
||||
|
||||
int dexOffset = readSmallUint(offset) + oatHeader.offset;
|
||||
int dexOffset = readSmallUint(offset) + oatHeader.headerOffset;
|
||||
offset += 4;
|
||||
|
||||
int classCount = readSmallUint(dexOffset + HeaderItem.CLASS_COUNT_OFFSET);
|
||||
offset += 4 * classCount;
|
||||
|
||||
if (getOatVersion() >= 75) {
|
||||
offset += 4; // offset to class offsets table
|
||||
}
|
||||
if (getOatVersion() >= 73) {
|
||||
offset += 4; // lookup table offset
|
||||
}
|
||||
if (getOatVersion() < 75) {
|
||||
// prior to 75, the class offsets are included here directly
|
||||
int classCount = readSmallUint(dexOffset + HeaderItem.CLASS_COUNT_OFFSET);
|
||||
offset += 4 * classCount;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
@ -205,63 +230,97 @@ public class OatFile extends BaseDexBuffer {
|
||||
return OatFile.this.getOatVersion();
|
||||
}
|
||||
|
||||
public OatFile getOatFile() {
|
||||
return OatFile.this;
|
||||
}
|
||||
|
||||
@Override public boolean hasOdexOpcodes() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class OatHeader {
|
||||
private final int offset;
|
||||
private final int headerOffset;
|
||||
|
||||
public OatHeader(int offset) {
|
||||
this.offset = offset;
|
||||
this.headerOffset = offset;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
for (int i=0; i<OAT_MAGIC.length; i++) {
|
||||
if (buf[offset + i] != OAT_MAGIC[i]) {
|
||||
if (buf[headerOffset + i] != OAT_MAGIC[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=4; i<7; i++) {
|
||||
if (buf[offset + i] < '0' || buf[offset + i] > '9') {
|
||||
if (buf[headerOffset + i] < '0' || buf[headerOffset + i] > '9') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return buf[offset + 7] == 0;
|
||||
return buf[headerOffset + 7] == 0;
|
||||
}
|
||||
|
||||
public int getVersion() {
|
||||
return Integer.valueOf(new String(buf, offset + 4, 3));
|
||||
return Integer.valueOf(new String(buf, headerOffset + 4, 3));
|
||||
}
|
||||
|
||||
public int getDexFileCount() {
|
||||
return readSmallUint(offset + 20);
|
||||
return readSmallUint(headerOffset + 20);
|
||||
}
|
||||
|
||||
public int getKeyValueStoreSize() {
|
||||
int version = getVersion();
|
||||
if (version < 56) {
|
||||
if (getVersion() < MIN_OAT_VERSION) {
|
||||
throw new IllegalStateException("Unsupported oat version");
|
||||
}
|
||||
int fieldOffset = 17 * 4;
|
||||
return readSmallUint(offset + fieldOffset);
|
||||
return readSmallUint(headerOffset + fieldOffset);
|
||||
}
|
||||
|
||||
public int getHeaderSize() {
|
||||
int version = getVersion();
|
||||
if (version >= 56) {
|
||||
return 18*4 + getKeyValueStoreSize();
|
||||
} else {
|
||||
if (getVersion() < MIN_OAT_VERSION) {
|
||||
throw new IllegalStateException("Unsupported oat version");
|
||||
}
|
||||
return 18*4 + getKeyValueStoreSize();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getKeyValue(@Nonnull String key) {
|
||||
int size = getKeyValueStoreSize();
|
||||
|
||||
int offset = headerOffset + 18 * 4;
|
||||
int endOffset = offset + size;
|
||||
|
||||
while (offset < endOffset) {
|
||||
int keyStartOffset = offset;
|
||||
while (offset < endOffset && buf[offset] != '\0') {
|
||||
offset++;
|
||||
}
|
||||
if (offset >= endOffset) {
|
||||
throw new InvalidOatFileException("Oat file contains truncated key value store");
|
||||
}
|
||||
int keyEndOffset = offset;
|
||||
|
||||
String k = new String(buf, keyStartOffset, keyEndOffset - keyStartOffset);
|
||||
if (k.equals(key)) {
|
||||
int valueStartOffset = ++offset;
|
||||
while (offset < endOffset && buf[offset] != '\0') {
|
||||
offset++;
|
||||
}
|
||||
if (offset >= endOffset) {
|
||||
throw new InvalidOatFileException("Oat file contains truncated key value store");
|
||||
}
|
||||
int valueEndOffset = offset;
|
||||
return new String(buf, valueStartOffset, valueEndOffset - valueStartOffset);
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getDexListStart() {
|
||||
return offset + getHeaderSize();
|
||||
return headerOffset + getHeaderSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user