mirror of
https://github.com/revanced/smali.git
synced 2025-05-23 18:16:23 +02:00
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:
parent
4a4fac96de
commit
73a63516fc
@ -34,6 +34,7 @@ import org.jf.dexlib.Item;
|
|||||||
import org.jf.dexlib.StringDataItem;
|
import org.jf.dexlib.StringDataItem;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.DigestException;
|
import java.security.DigestException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@ -266,7 +267,40 @@ public class DexFile
|
|||||||
public DexFile(File file, boolean preserveSignedRegisters) {
|
public DexFile(File file, boolean preserveSignedRegisters) {
|
||||||
this(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);
|
ReadContext readContext = new ReadContext(this);
|
||||||
|
|
||||||
|
@ -36,10 +36,10 @@ import java.io.UnsupportedEncodingException;
|
|||||||
|
|
||||||
public class HeaderItem extends Item<HeaderItem> {
|
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
|
* 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 */
|
/** size of this section, in bytes */
|
||||||
private static final int HEADER_SIZE = 0x70;
|
private static final int HEADER_SIZE = 0x70;
|
||||||
|
78
dexlib/src/main/java/org/jf/dexlib/OdexHeaderItem.java
Normal file
78
dexlib/src/main/java/org/jf/dexlib/OdexHeaderItem.java
Normal 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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -51,6 +51,20 @@ public final class FileUtils {
|
|||||||
* @return non-null; contents of the file
|
* @return non-null; contents of the file
|
||||||
*/
|
*/
|
||||||
public static byte[] readFile(File 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()) {
|
if (!file.exists()) {
|
||||||
throw new RuntimeException(file + ": file not found");
|
throw new RuntimeException(file + ": file not found");
|
||||||
}
|
}
|
||||||
@ -64,16 +78,33 @@ public final class FileUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
long longLength = file.length();
|
long longLength = file.length();
|
||||||
int length = (int) longLength;
|
int fileLength = (int) longLength;
|
||||||
if (length != longLength) {
|
if (fileLength != longLength) {
|
||||||
throw new RuntimeException(file + ": file too long");
|
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];
|
byte[] result = new byte[length];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileInputStream in = new FileInputStream(file);
|
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) {
|
while (length > 0) {
|
||||||
int amt = in.read(result, at, length);
|
int amt = in.read(result, at, length);
|
||||||
if (amt == -1) {
|
if (amt == -1) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user