preliminary support for reading in odex files

git-svn-id: https://smali.googlecode.com/svn/trunk@431 55b6fa8a-2a1e-11de-a435-ffa8d773f76a
This commit is contained in:
JesusFreke@JesusFreke.com 2009-08-30 02:32:27 +00:00
parent 4a4fac96de
commit 73a63516fc
4 changed files with 149 additions and 6 deletions

View File

@ -34,6 +34,7 @@ import org.jf.dexlib.Item;
import org.jf.dexlib.StringDataItem;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -266,7 +267,40 @@ public class DexFile
public DexFile(File file, boolean preserveSignedRegisters) {
this(preserveSignedRegisters);
Input in = new ByteArrayInput(FileUtils.readFile(file));
byte[] magic = FileUtils.readFile(file, 0, 8);
byte[] dexMagic, odexMagic;
try {
dexMagic = HeaderItem.MAGIC.getBytes("US-ASCII");
odexMagic = OdexHeaderItem.MAGIC.getBytes("US-ASCII");
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
boolean isDex = true;
boolean isOdex = true;
for (int i=0; i<8; i++) {
if (magic[i] != dexMagic[i]) {
isDex = false;
}
if (magic[i] != odexMagic[i]) {
isOdex = false;
}
}
Input in;
if (isOdex) {
byte[] odexHeaderBytes = FileUtils.readFile(file, 0, 40);
Input odexHeaderIn = new ByteArrayInput(odexHeaderBytes);
OdexHeaderItem odexHeader = new OdexHeaderItem(odexHeaderIn);
in = new ByteArrayInput(FileUtils.readFile(file, odexHeader.dexOffset, odexHeader.dexLength));
} else if (isDex) {
in = new ByteArrayInput(FileUtils.readFile(file));
} else {
throw new RuntimeException("bad magic value");
}
ReadContext readContext = new ReadContext(this);

View File

@ -36,10 +36,10 @@ import java.io.UnsupportedEncodingException;
public class HeaderItem extends Item<HeaderItem> {
/**
* non-null; the file format magic number, represented as the
* the file format magic number, represented as the
* low-order bytes of a string
*/
private static final String MAGIC = "dex\n035" + '\0';
public static final String MAGIC = "dex\n035" + '\0';
/** size of this section, in bytes */
private static final int HEADER_SIZE = 0x70;

View File

@ -0,0 +1,78 @@
/*
* [The "BSD licence"]
* Copyright (c) 2009 Ben Gruver
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jf.dexlib;
import org.jf.dexlib.Util.Input;
import java.io.UnsupportedEncodingException;
public class OdexHeaderItem {
/**
* the file format magic number, represented as the
* low-order bytes of a string
*/
public static final String MAGIC = "dey\n035" + '\0';
public final byte[] magic;
public final int dexOffset;
public final int dexLength;
public final int depsOffset;
public final int depsLength;
public final int auxOffset;
public final int auxLength;
public final int flags;
public OdexHeaderItem(Input in) {
magic = in.readBytes(8);
byte[] expectedMagic;
try {
expectedMagic = MAGIC.getBytes("US-ASCII");
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
for (int i=0; i<8; i++) {
if (expectedMagic[i] != magic[i]) {
throw new RuntimeException("The magic value is not the expected value");
}
}
dexOffset = in.readInt();
dexLength = in.readInt();
depsOffset = in.readInt();
depsLength = in.readInt();
auxOffset = in.readInt();
auxLength = in.readInt();
flags = in.readInt();
in.readInt(); //padding
}
}

View File

@ -51,6 +51,20 @@ public final class FileUtils {
* @return non-null; contents of the file
*/
public static byte[] readFile(File file) {
return readFile(file, 0, -1);
}
/**
* Reads the specified block from the given file, translating
* {@link IOException} to a {@link RuntimeException} of some sort.
*
* @param file non-null; the file to read
* @param offset the offset to begin reading
* @param length the number of bytes to read, or -1 to read to the
* end of the file
* @return non-null; contents of the file
*/
public static byte[] readFile(File file, int offset, int length) {
if (!file.exists()) {
throw new RuntimeException(file + ": file not found");
}
@ -64,16 +78,33 @@ public final class FileUtils {
}
long longLength = file.length();
int length = (int) longLength;
if (length != longLength) {
int fileLength = (int) longLength;
if (fileLength != longLength) {
throw new RuntimeException(file + ": file too long");
}
if (length == -1) {
length = fileLength - offset;
}
if (offset + length > fileLength) {
throw new RuntimeException(file + ": file too short");
}
byte[] result = new byte[length];
try {
FileInputStream in = new FileInputStream(file);
int at = 0;
int at = offset;
while(at > 0) {
long amt = in.skip(at);
if (amt == -1) {
throw new RuntimeException(file + ": unexpected EOF");
}
at -= amt;
}
while (length > 0) {
int amt = in.read(result, at, length);
if (amt == -1) {