aboutsummaryrefslogtreecommitdiff
path: root/dexlib2
diff options
context:
space:
mode:
authorBen Gruver <bgruv@google.com>2015-07-13 21:39:28 -0700
committerBen Gruver <bgruv@google.com>2015-09-30 20:36:12 -0700
commit8920228819d4cd1cb016ba577b9c65a0cd798fd4 (patch)
tree27bf52a82d3176f3301c0ac8e48fe4818a4c5dfc /dexlib2
parent3ff884b1c345dbd030430e3eecf37e4d409f18b0 (diff)
downloadsmali-8920228819d4cd1cb016ba577b9c65a0cd798fd4.tar.gz
Add oat support in DexFileFactory
Diffstat (limited to 'dexlib2')
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java110
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java20
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexBuffer.java19
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexReader.java39
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java8
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedOdexFile.java5
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java10
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/RawDexFile.java3
8 files changed, 167 insertions, 47 deletions
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
index fb433bb3..60488ba2 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
@@ -31,51 +31,56 @@
package org.jf.dexlib2;
+import com.google.common.base.MoreObjects;
import com.google.common.io.ByteStreams;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
+import org.jf.dexlib2.dexbacked.OatFile;
+import org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException;
+import org.jf.dexlib2.dexbacked.OatFile.OatDexFile;
import org.jf.dexlib2.iface.DexFile;
import org.jf.dexlib2.writer.pool.DexPool;
import org.jf.util.ExceptionWithContext;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import java.io.*;
+import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public final class DexFileFactory {
@Nonnull
- public static DexBackedDexFile loadDexFile(String path, int api)
- throws IOException {
+ public static DexBackedDexFile loadDexFile(@Nonnull String path, int api) throws IOException {
return loadDexFile(path, api, false);
}
@Nonnull
- public static DexBackedDexFile loadDexFile(String path, int api, boolean experimental)
+ public static DexBackedDexFile loadDexFile(@Nonnull String path, int api, boolean experimental)
throws IOException {
return loadDexFile(new File(path), "classes.dex", Opcodes.forApi(api, experimental));
}
@Nonnull
- public static DexBackedDexFile loadDexFile(File dexFile, int api) throws IOException {
+ public static DexBackedDexFile loadDexFile(@Nonnull File dexFile, int api) throws IOException {
return loadDexFile(dexFile, api, false);
}
@Nonnull
- public static DexBackedDexFile loadDexFile(File dexFile, int api, boolean experimental)
+ public static DexBackedDexFile loadDexFile(@Nonnull File dexFile, int api, boolean experimental)
throws IOException {
- return loadDexFile(dexFile, "classes.dex", Opcodes.forApi(api, experimental));
+ return loadDexFile(dexFile, null, Opcodes.forApi(api, experimental));
}
@Nonnull
- public static DexBackedDexFile loadDexFile(File dexFile, String dexEntry, int api,
+ public static DexBackedDexFile loadDexFile(@Nonnull File dexFile, @Nullable String dexEntry, int api,
boolean experimental) throws IOException {
return loadDexFile(dexFile, dexEntry, Opcodes.forApi(api, experimental));
}
@Nonnull
- public static DexBackedDexFile loadDexFile(File dexFile, String dexEntry,
- @Nonnull Opcodes opcodes) throws IOException {
+ public static DexBackedDexFile loadDexFile(@Nonnull File dexFile, @Nullable String dexEntry,
+ @Nonnull Opcodes opcodes) throws IOException {
ZipFile zipFile = null;
boolean isZipFile = false;
try {
@@ -83,16 +88,18 @@ public final class DexFileFactory {
// if we get here, it's safe to assume we have a zip file
isZipFile = true;
- ZipEntry zipEntry = zipFile.getEntry(dexEntry);
+ String zipEntryName = MoreObjects.firstNonNull(dexEntry, "classes.dex");
+ ZipEntry zipEntry = zipFile.getEntry(zipEntryName);
if (zipEntry == null) {
- throw new NoClassesDexException("zip file %s does not contain a classes.dex file", dexFile.getName());
+ throw new DexFileNotFound("zip file %s does not contain a %s file", dexFile.getName(), zipEntryName);
}
long fileLength = zipEntry.getSize();
if (fileLength < 40) {
- throw new ExceptionWithContext(
- "The " + dexEntry + " file in %s is too small to be a valid dex file", dexFile.getName());
+ throw new ExceptionWithContext("The %s file in %s is too small to be a valid dex file",
+ zipEntryName, dexFile.getName());
} else if (fileLength > Integer.MAX_VALUE) {
- throw new ExceptionWithContext("The " + dexEntry + " file in %s is too large to read in", dexFile.getName());
+ throw new ExceptionWithContext("The %s file in %s is too large to read in",
+ zipEntryName, dexFile.getName());
}
byte[] dexBytes = new byte[(int)fileLength];
ByteStreams.readFully(zipFile.getInputStream(zipEntry), dexBytes);
@@ -127,30 +134,93 @@ public final class DexFileFactory {
} catch (DexBackedOdexFile.NotAnOdexFile ex) {
// just eat it
}
+
+ OatFile oatFile = null;
+ try {
+ oatFile = OatFile.fromInputStream(inputStream);
+ } catch (NotAnOatFileException ex) {
+ // just eat it
+ }
+
+ if (oatFile != null) {
+ if (oatFile.isSupportedVersion() == OatFile.UNSUPPORTED) {
+ throw new UnsupportedOatVersionException(oatFile);
+ }
+
+ List<OatDexFile> oatDexFiles = oatFile.getDexFiles();
+
+ if (oatDexFiles.size() == 0) {
+ throw new DexFileNotFound("Oat file %s contains no dex files", dexFile.getName());
+ }
+
+ if (dexEntry == null) {
+ if (oatDexFiles.size() > 1) {
+ throw new MultipleDexFilesException(oatFile);
+ }
+ return oatDexFiles.get(0);
+ } else {
+ // first check for an exact match
+ for (OatDexFile oatDexFile : oatFile.getDexFiles()) {
+ if (oatDexFile.filename.equals(dexEntry)) {
+ return oatDexFile;
+ }
+ }
+
+ if (!dexEntry.contains("/")) {
+ for (OatDexFile oatDexFile : oatFile.getDexFiles()) {
+ File oatEntryFile = new File(oatDexFile.filename);
+ if (oatEntryFile.getName().equals(dexEntry)) {
+ return oatDexFile;
+ }
+ }
+ }
+
+ throw new DexFileNotFound("oat file %s does not contain a dex file named %s",
+ dexFile.getName(), dexEntry);
+ }
+ }
} finally {
inputStream.close();
}
- throw new ExceptionWithContext("%s is not an apk, dex file or odex file.", dexFile.getPath());
+ throw new ExceptionWithContext("%s is not an apk, dex, odex or oat file.", dexFile.getPath());
}
- public static void writeDexFile(String path, DexFile dexFile) throws IOException {
+ public static void writeDexFile(@Nonnull String path, @Nonnull DexFile dexFile) throws IOException {
DexPool.writeTo(path, dexFile);
}
private DexFileFactory() {}
- public static class NoClassesDexException extends ExceptionWithContext {
- public NoClassesDexException(Throwable cause) {
+ public static class DexFileNotFound extends ExceptionWithContext {
+ public DexFileNotFound(@Nullable Throwable cause) {
super(cause);
}
- public NoClassesDexException(Throwable cause, String message, Object... formatArgs) {
+ public DexFileNotFound(@Nullable Throwable cause, @Nullable String message, Object... formatArgs) {
super(cause, message, formatArgs);
}
- public NoClassesDexException(String message, Object... formatArgs) {
+ public DexFileNotFound(@Nullable String message, Object... formatArgs) {
super(message, formatArgs);
}
}
+
+ public static class MultipleDexFilesException extends ExceptionWithContext {
+ @Nonnull public final OatFile oatFile;
+
+ public MultipleDexFilesException(@Nonnull OatFile oatFile) {
+ super("Oat file has multiple dex files.");
+ this.oatFile = oatFile;
+ }
+ }
+
+ public static class UnsupportedOatVersionException extends ExceptionWithContext {
+ @Nonnull public final OatFile oatFile;
+
+ public UnsupportedOatVersionException(@Nonnull OatFile oatFile) {
+ super("Unsupported oat version: %d", oatFile.getOatVersion());
+ this.oatFile = oatFile;
+ }
+ }
}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java
index bd9cfb1b..4185da82 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/ClassPath.java
@@ -39,6 +39,7 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.jf.dexlib2.DexFileFactory;
+import org.jf.dexlib2.DexFileFactory.DexFileNotFound;
import org.jf.dexlib2.analysis.reflection.ReflectionClassDef;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.DexFile;
@@ -58,6 +59,7 @@ public class ClassPath {
@Nonnull private final TypeProto unknownClass;
@Nonnull private HashMap<String, ClassDef> availableClasses = Maps.newHashMap();
private boolean checkPackagePrivateAccess;
+ public boolean isArt;
/**
* Creates a new ClassPath instance that can load classes from the given dex files
@@ -82,15 +84,29 @@ public class ClassPath {
* Creates a new ClassPath instance that can load classes from the given dex files
*
* @param classPath An iterable of DexFile objects. When loading a class, these dex files will be searched in order
- * @param checkPackagePrivateAccess Whether checkPackagePrivateAccess is needed, enabled for ONLY early API 17 by default
+ * @param checkPackagePrivateAccess Whether checkPackagePrivateAccess is needed, enabled for ONLY early API 17 by
+ * default
*/
public ClassPath(@Nonnull Iterable<DexFile> classPath, boolean checkPackagePrivateAccess) {
+ this(classPath, checkPackagePrivateAccess, false);
+ }
+
+ /**
+ * Creates a new ClassPath instance that can load classes from the given dex files
+ *
+ * @param classPath An iterable of DexFile objects. When loading a class, these dex files will be searched in order
+ * @param checkPackagePrivateAccess Whether checkPackagePrivateAccess is needed, enabled for ONLY early API 17 by
+ * default
+ * @param isArt Whether this is ClassPath is for ART
+ */
+ public ClassPath(@Nonnull Iterable < DexFile > classPath, boolean checkPackagePrivateAccess, boolean isArt) {
// add fallbacks for certain special classes that must be present
Iterable<DexFile> dexFiles = Iterables.concat(classPath, Lists.newArrayList(getBasicClasses()));
unknownClass = new UnknownClassProto(this);
loadedClasses.put(unknownClass.getType(), unknownClass);
this.checkPackagePrivateAccess = checkPackagePrivateAccess;
+ this.isArt = isArt;
loadPrimitiveType("Z");
loadPrimitiveType("B");
@@ -223,7 +239,7 @@ public class ClassPath {
} else {
try {
return DexFileFactory.loadDexFile(file, api, experimental);
- } catch (DexFileFactory.NoClassesDexException ex) {
+ } catch (DexFileNotFound ex) {
// ignore and continue
} catch (Exception ex) {
throw ExceptionWithContext.withContext(ex,
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexBuffer.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexBuffer.java
index 7d06bff7..9cf49294 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexBuffer.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexBuffer.java
@@ -37,13 +37,19 @@ import javax.annotation.Nonnull;
public class BaseDexBuffer {
@Nonnull /* package private */ final byte[] buf;
+ /* package private */ final int baseOffset;
public BaseDexBuffer(@Nonnull byte[] buf) {
+ this(buf, 0);
+ }
+ public BaseDexBuffer(@Nonnull byte[] buf, int offset) {
this.buf = buf;
+ this.baseOffset = offset;
}
public int readSmallUint(int offset) {
byte[] buf = this.buf;
+ offset += baseOffset;
int result = (buf[offset] & 0xff) |
((buf[offset+1] & 0xff) << 8) |
((buf[offset+2] & 0xff) << 16) |
@@ -56,6 +62,7 @@ public class BaseDexBuffer {
public int readOptionalUint(int offset) {
byte[] buf = this.buf;
+ offset += baseOffset;
int result = (buf[offset] & 0xff) |
((buf[offset+1] & 0xff) << 8) |
((buf[offset+2] & 0xff) << 16) |
@@ -68,16 +75,18 @@ public class BaseDexBuffer {
public int readUshort(int offset) {
byte[] buf = this.buf;
+ offset += baseOffset;
return (buf[offset] & 0xff) |
((buf[offset+1] & 0xff) << 8);
}
public int readUbyte(int offset) {
- return buf[offset] & 0xff;
+ return buf[offset + baseOffset] & 0xff;
}
public long readLong(int offset) {
byte[] buf = this.buf;
+ offset += baseOffset;
return (buf[offset] & 0xff) |
((buf[offset+1] & 0xff) << 8) |
((buf[offset+2] & 0xff) << 16) |
@@ -90,6 +99,7 @@ public class BaseDexBuffer {
public int readInt(int offset) {
byte[] buf = this.buf;
+ offset += baseOffset;
return (buf[offset] & 0xff) |
((buf[offset+1] & 0xff) << 8) |
((buf[offset+2] & 0xff) << 16) |
@@ -98,12 +108,13 @@ public class BaseDexBuffer {
public int readShort(int offset) {
byte[] buf = this.buf;
+ offset += baseOffset;
return (buf[offset] & 0xff) |
(buf[offset+1] << 8);
}
public int readByte(int offset) {
- return buf[offset];
+ return buf[baseOffset + offset];
}
@Nonnull
@@ -115,4 +126,8 @@ public class BaseDexBuffer {
protected byte[] getBuf() {
return buf;
}
+
+ protected int getBaseOffset() {
+ return baseOffset;
+ }
}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexReader.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexReader.java
index 96645b8c..13c0a7b0 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexReader.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/BaseDexReader.java
@@ -49,7 +49,7 @@ public class BaseDexReader<T extends BaseDexBuffer> {
public void setOffset(int offset) { this.offset = offset; }
public int readSleb128() {
- int end = offset;
+ int end = dexBuf.baseOffset + offset;
int currentByteValue;
int result;
byte[] buf = dexBuf.buf;
@@ -84,7 +84,7 @@ public class BaseDexReader<T extends BaseDexBuffer> {
}
}
- offset = end;
+ offset = end - dexBuf.baseOffset;
return result;
}
@@ -93,7 +93,7 @@ public class BaseDexReader<T extends BaseDexBuffer> {
}
private int readUleb128(boolean allowLarge) {
- int end = offset;
+ int end = dexBuf.baseOffset + offset;
int currentByteValue;
int result;
byte[] buf = dexBuf.buf;
@@ -129,7 +129,7 @@ public class BaseDexReader<T extends BaseDexBuffer> {
}
}
- offset = end;
+ offset = end - dexBuf.baseOffset;
return result;
}
@@ -150,7 +150,7 @@ public class BaseDexReader<T extends BaseDexBuffer> {
* @return The unsigned value, reinterpreted as a signed int
*/
public int readBigUleb128() {
- int end = offset;
+ int end = dexBuf.baseOffset + offset;
int currentByteValue;
int result;
byte[] buf = dexBuf.buf;
@@ -179,12 +179,12 @@ public class BaseDexReader<T extends BaseDexBuffer> {
}
}
- offset = end;
+ offset = end - dexBuf.baseOffset;
return result;
}
public void skipUleb128() {
- int end = offset;
+ int end = dexBuf.baseOffset + offset;
byte currentByteValue;
byte[] buf = dexBuf.buf;
@@ -206,7 +206,7 @@ public class BaseDexReader<T extends BaseDexBuffer> {
}
}
- offset = end;
+ offset = end - dexBuf.baseOffset;
}
public int readSmallUint() {
@@ -285,7 +285,7 @@ public class BaseDexReader<T extends BaseDexBuffer> {
public int readByte(int offset) { return dexBuf.readByte(offset); }
public int readSizedInt(int bytes) {
- int o = offset;
+ int o = dexBuf.baseOffset + offset;
byte[] buf = dexBuf.buf;
int result;
@@ -311,12 +311,12 @@ public class BaseDexReader<T extends BaseDexBuffer> {
default:
throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
}
- offset = o + bytes;
+ offset = o + bytes - dexBuf.baseOffset;
return result;
}
public int readSizedSmallUint(int bytes) {
- int o = offset;
+ int o = dexBuf.baseOffset + offset;
byte[] buf = dexBuf.buf;
int result = 0;
@@ -341,12 +341,12 @@ public class BaseDexReader<T extends BaseDexBuffer> {
default:
throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
}
- offset = o + bytes;
+ offset = o + bytes - dexBuf.baseOffset;
return result;
}
public int readSizedRightExtendedInt(int bytes) {
- int o = offset;
+ int o = dexBuf.baseOffset + offset;
byte[] buf = dexBuf.buf;
int result;
@@ -373,12 +373,12 @@ public class BaseDexReader<T extends BaseDexBuffer> {
throw new ExceptionWithContext(
"Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
}
- offset = o + bytes;
+ offset = o + bytes - dexBuf.baseOffset;
return result;
}
public long readSizedRightExtendedLong(int bytes) {
- int o = offset;
+ int o = dexBuf.baseOffset + offset;
byte[] buf = dexBuf.buf;
long result;
@@ -439,12 +439,12 @@ public class BaseDexReader<T extends BaseDexBuffer> {
throw new ExceptionWithContext(
"Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
}
- offset = o + bytes;
+ offset = o + bytes - dexBuf.baseOffset;
return result;
}
public long readSizedLong(int bytes) {
- int o = offset;
+ int o = dexBuf.baseOffset + offset;
byte[] buf = dexBuf.buf;
long result;
@@ -505,13 +505,14 @@ public class BaseDexReader<T extends BaseDexBuffer> {
throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
}
- offset = o + bytes;
+ offset = o + bytes - dexBuf.baseOffset;
return result;
}
public String readString(int utf16Length) {
int[] ret = new int[1];
- String value = Utf8Utils.utf8BytesWithUtf16LengthToString(dexBuf.buf, offset, utf16Length, ret);
+ String value = Utf8Utils.utf8BytesWithUtf16LengthToString(
+ dexBuf.buf, dexBuf.baseOffset + offset, utf16Length, ret);
offset += ret[0];
return value;
}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java
index 1774096e..638fd855 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedDexFile.java
@@ -62,7 +62,7 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
private final int classStartOffset;
private DexBackedDexFile(Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) {
- super(buf);
+ super(buf, offset);
this.opcodes = opcodes;
@@ -121,10 +121,16 @@ public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
return opcodes;
}
+ // Will only be true for a dalvik-style odex file
public boolean isOdexFile() {
return false;
}
+ // Will be true for both a dalvik-style odex file, and an art-style odex file embedded in an oat file
+ public boolean hasOdexOpcodes() {
+ return false;
+ }
+
@Nonnull
@Override
public Set<? extends DexBackedClassDef> getClasses() {
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedOdexFile.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedOdexFile.java
index 1aa9c1eb..12f19db0 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedOdexFile.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/DexBackedOdexFile.java
@@ -33,7 +33,6 @@ package org.jf.dexlib2.dexbacked;
import com.google.common.io.ByteStreams;
import org.jf.dexlib2.Opcodes;
-import org.jf.dexlib2.dexbacked.raw.HeaderItem;
import org.jf.dexlib2.dexbacked.raw.OdexHeaderItem;
import org.jf.dexlib2.dexbacked.util.VariableSizeList;
@@ -61,6 +60,10 @@ public class DexBackedOdexFile extends DexBackedDexFile {
return true;
}
+ @Override public boolean hasOdexOpcodes() {
+ return true;
+ }
+
public List<String> getDependencies() {
final int dexOffset = OdexHeaderItem.getDexOffset(odexBuf);
final int dependencyOffset = OdexHeaderItem.getDependenciesOffset(odexBuf) - dexOffset;
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java
index 88ef08c7..b5250d0d 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/OatFile.java
@@ -124,8 +124,12 @@ public class OatFile extends BaseDexBuffer {
return new OatFile(buf);
}
+ public int getOatVersion() {
+ return oatHeader.getVersion();
+ }
+
public int isSupportedVersion() {
- int version = oatHeader.getVersion();
+ int version = getOatVersion();
if (version < MIN_OAT_VERSION) {
return UNSUPPORTED;
}
@@ -187,6 +191,10 @@ public class OatFile extends BaseDexBuffer {
super(opcodes, OatFile.this.buf, offset);
this.filename = filename;
}
+
+ @Override public boolean hasOdexOpcodes() {
+ return true;
+ }
}
private class OatHeader {
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/RawDexFile.java b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/RawDexFile.java
index 1fac80bb..204a29d8 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/RawDexFile.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/dexbacked/raw/RawDexFile.java
@@ -59,7 +59,7 @@ public class RawDexFile extends DexBackedDexFile {
@Nonnull
public byte[] readByteRange(int start, int length) {
- return Arrays.copyOfRange(getBuf(), start, start+length);
+ return Arrays.copyOfRange(getBuf(), getBaseOffset() + start, getBaseOffset() + start + length);
}
public int getMapOffset() {
@@ -94,6 +94,7 @@ public class RawDexFile extends DexBackedDexFile {
}
public void writeAnnotations(@Nonnull Writer out, @Nonnull AnnotatedBytes annotatedBytes) throws IOException {
+ // TODO: need to pass in the offset
annotatedBytes.writeAnnotations(out, getBuf());
}
}