mirror of
https://github.com/revanced/Apktool.git
synced 2025-06-12 21:27:36 +02:00
Update to smali 2b5
This commit is contained in:
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import junit.framework.Assert;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.DexFile;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.MethodImplementation;
|
||||
import org.jf.dexlib2.iface.instruction.Instruction;
|
||||
import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
import org.jf.dexlib2.util.SyntheticAccessorResolver;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class AccessorTest {
|
||||
private Pattern accessorMethodPattern = Pattern.compile("([a-zA-Z]*)_([a-zA-Z]*)");
|
||||
|
||||
private static final Map<String, Integer> operationTypes;
|
||||
|
||||
static {
|
||||
ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
|
||||
builder.put("postinc", SyntheticAccessorResolver.POSTFIX_INCREMENT);
|
||||
builder.put("preinc", SyntheticAccessorResolver.PREFIX_INCREMENT);
|
||||
builder.put("postdec", SyntheticAccessorResolver.POSTFIX_DECREMENT);
|
||||
builder.put("predec", SyntheticAccessorResolver.PREFIX_DECREMENT);
|
||||
builder.put("add", SyntheticAccessorResolver.ADD_ASSIGNMENT);
|
||||
builder.put("sub", SyntheticAccessorResolver.SUB_ASSIGNMENT);
|
||||
builder.put("mul", SyntheticAccessorResolver.MUL_ASSIGNMENT);
|
||||
builder.put("div", SyntheticAccessorResolver.DIV_ASSIGNMENT);
|
||||
builder.put("rem", SyntheticAccessorResolver.REM_ASSIGNMENT);
|
||||
builder.put("and", SyntheticAccessorResolver.AND_ASSIGNMENT);
|
||||
builder.put("or", SyntheticAccessorResolver.OR_ASSIGNMENT);
|
||||
builder.put("xor", SyntheticAccessorResolver.XOR_ASSIGNMENT);
|
||||
builder.put("shl", SyntheticAccessorResolver.SHL_ASSIGNMENT);
|
||||
builder.put("shr", SyntheticAccessorResolver.SHR_ASSIGNMENT);
|
||||
builder.put("ushr", SyntheticAccessorResolver.USHR_ASSIGNMENT);
|
||||
operationTypes = builder.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAccessors() throws IOException {
|
||||
URL url = AccessorTest.class.getClassLoader().getResource("accessorTest.dex");
|
||||
Assert.assertNotNull(url);
|
||||
DexFile f = DexFileFactory.loadDexFile(url.getFile(), 15);
|
||||
|
||||
SyntheticAccessorResolver sar = new SyntheticAccessorResolver(f.getClasses());
|
||||
|
||||
ClassDef accessorTypesClass = null;
|
||||
ClassDef accessorsClass = null;
|
||||
|
||||
for (ClassDef classDef: f.getClasses()) {
|
||||
String className = classDef.getType();
|
||||
|
||||
if (className.equals("Lorg/jf/dexlib2/AccessorTypes;")) {
|
||||
accessorTypesClass = classDef;
|
||||
} else if (className.equals("Lorg/jf/dexlib2/AccessorTypes$Accessors;")) {
|
||||
accessorsClass = classDef;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertNotNull(accessorTypesClass);
|
||||
Assert.assertNotNull(accessorsClass);
|
||||
|
||||
for (Method method: accessorsClass.getMethods()) {
|
||||
Matcher m = accessorMethodPattern.matcher(method.getName());
|
||||
if (!m.matches()) {
|
||||
continue;
|
||||
}
|
||||
String type = m.group(1);
|
||||
String operation = m.group(2);
|
||||
|
||||
MethodImplementation methodImpl = method.getImplementation();
|
||||
Assert.assertNotNull(methodImpl);
|
||||
|
||||
for (Instruction instruction: methodImpl.getInstructions()) {
|
||||
Opcode opcode = instruction.getOpcode();
|
||||
if (opcode == Opcode.INVOKE_STATIC || opcode == Opcode.INVOKE_STATIC_RANGE) {
|
||||
MethodReference accessorMethod =
|
||||
(MethodReference)((ReferenceInstruction) instruction).getReference();
|
||||
|
||||
SyntheticAccessorResolver.AccessedMember accessedMember = sar.getAccessedMember(accessorMethod);
|
||||
|
||||
Assert.assertNotNull(String.format("Could not resolve accessor for %s_%s", type, operation),
|
||||
accessedMember);
|
||||
|
||||
int operationType = operationTypes.get(operation);
|
||||
Assert.assertEquals(operationType, accessedMember.accessedMemberType);
|
||||
|
||||
Assert.assertEquals(String.format("%s_val", type),
|
||||
((FieldReference)accessedMember.accessedMember).getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public enum AccessFlags
|
||||
{
|
||||
PUBLIC(0x1, "public", true, true, true),
|
||||
PRIVATE(0x2, "private", true, true, true),
|
||||
PROTECTED(0x4, "protected", true, true, true),
|
||||
STATIC(0x8, "static", true, true, true),
|
||||
FINAL(0x10, "final", true, true, true),
|
||||
SYNCHRONIZED(0x20, "synchronized", false, true, false),
|
||||
VOLATILE(0x40, "volatile", false, false, true),
|
||||
BRIDGE(0x40, "bridge", false, true, false),
|
||||
TRANSIENT(0x80, "transient", false, false, true),
|
||||
VARARGS(0x80, "varargs", false, true, false),
|
||||
NATIVE(0x100, "native", false, true, false),
|
||||
INTERFACE(0x200, "interface", true, false, false),
|
||||
ABSTRACT(0x400, "abstract", true, true, false),
|
||||
STRICTFP(0x800, "strictfp", false, true, false),
|
||||
SYNTHETIC(0x1000, "synthetic", true, true, true),
|
||||
ANNOTATION(0x2000, "annotation", true, false, false),
|
||||
ENUM(0x4000, "enum", true, false, true),
|
||||
CONSTRUCTOR(0x10000, "constructor", false, true, false),
|
||||
DECLARED_SYNCHRONIZED(0x20000, "declared-synchronized", false, true, false);
|
||||
|
||||
private int value;
|
||||
private String accessFlagName;
|
||||
private boolean validForClass;
|
||||
private boolean validForMethod;
|
||||
private boolean validForField;
|
||||
|
||||
//cache the array of all AccessFlags, because .values() allocates a new array for every call
|
||||
private final static AccessFlags[] allFlags;
|
||||
|
||||
private static HashMap<String, AccessFlags> accessFlagsByName;
|
||||
|
||||
static {
|
||||
allFlags = AccessFlags.values();
|
||||
|
||||
accessFlagsByName = new HashMap<String, AccessFlags>();
|
||||
for (AccessFlags accessFlag: allFlags) {
|
||||
accessFlagsByName.put(accessFlag.accessFlagName, accessFlag);
|
||||
}
|
||||
}
|
||||
|
||||
private AccessFlags(int value, String accessFlagName, boolean validForClass, boolean validForMethod,
|
||||
boolean validForField) {
|
||||
this.value = value;
|
||||
this.accessFlagName = accessFlagName;
|
||||
this.validForClass = validForClass;
|
||||
this.validForMethod = validForMethod;
|
||||
this.validForField = validForField;
|
||||
}
|
||||
|
||||
public boolean isSet(int accessFlags) {
|
||||
return (this.value & accessFlags) != 0;
|
||||
}
|
||||
|
||||
public static AccessFlags[] getAccessFlagsForClass(int accessFlagValue) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: allFlags) {
|
||||
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
AccessFlags[] accessFlags = new AccessFlags[size];
|
||||
int accessFlagsPosition = 0;
|
||||
for (AccessFlags accessFlag: allFlags) {
|
||||
if (accessFlag.validForClass && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags[accessFlagsPosition++] = accessFlag;
|
||||
}
|
||||
}
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
private static String formatAccessFlags(AccessFlags[] accessFlags) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: accessFlags) {
|
||||
size += accessFlag.toString().length() + 1;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(size);
|
||||
for (AccessFlags accessFlag: accessFlags) {
|
||||
sb.append(accessFlag.toString());
|
||||
sb.append(" ");
|
||||
}
|
||||
if (accessFlags.length > 0) {
|
||||
sb.delete(sb.length() - 1, sb.length());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String formatAccessFlagsForClass(int accessFlagValue) {
|
||||
return formatAccessFlags(getAccessFlagsForClass(accessFlagValue));
|
||||
}
|
||||
|
||||
public static AccessFlags[] getAccessFlagsForMethod(int accessFlagValue) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: allFlags) {
|
||||
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
AccessFlags[] accessFlags = new AccessFlags[size];
|
||||
int accessFlagsPosition = 0;
|
||||
for (AccessFlags accessFlag: allFlags) {
|
||||
if (accessFlag.validForMethod && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags[accessFlagsPosition++] = accessFlag;
|
||||
}
|
||||
}
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
public static String formatAccessFlagsForMethod(int accessFlagValue) {
|
||||
return formatAccessFlags(getAccessFlagsForMethod(accessFlagValue));
|
||||
}
|
||||
|
||||
public static AccessFlags[] getAccessFlagsForField(int accessFlagValue) {
|
||||
int size = 0;
|
||||
for (AccessFlags accessFlag: allFlags) {
|
||||
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
AccessFlags[] accessFlags = new AccessFlags[size];
|
||||
int accessFlagsPosition = 0;
|
||||
for (AccessFlags accessFlag: allFlags) {
|
||||
if (accessFlag.validForField && (accessFlagValue & accessFlag.value) != 0) {
|
||||
accessFlags[accessFlagsPosition++] = accessFlag;
|
||||
}
|
||||
}
|
||||
return accessFlags;
|
||||
}
|
||||
|
||||
public static String formatAccessFlagsForField(int accessFlagValue) {
|
||||
return formatAccessFlags(getAccessFlagsForField(accessFlagValue));
|
||||
}
|
||||
|
||||
public static AccessFlags getAccessFlag(String accessFlag) {
|
||||
return accessFlagsByName.get(accessFlag);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return accessFlagName;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
public final class AnnotationVisibility {
|
||||
public static final int BUILD = 0;
|
||||
public static final int RUNTIME = 1;
|
||||
public static final int SYSTEM = 2;
|
||||
|
||||
private static String[] NAMES = new String[] {"build", "runtime", "system"};
|
||||
|
||||
public static String getVisibility(int visibility) {
|
||||
if (visibility < 0 || visibility >= NAMES.length) {
|
||||
throw new ExceptionWithContext("Invalid annotation visibility %d", visibility);
|
||||
}
|
||||
return NAMES[visibility];
|
||||
}
|
||||
|
||||
public static int getVisibility(String visibility) {
|
||||
visibility = visibility.toLowerCase();
|
||||
if (visibility.equals("build")) {
|
||||
return BUILD;
|
||||
}
|
||||
if (visibility.equals("runtime")) {
|
||||
return RUNTIME;
|
||||
}
|
||||
if (visibility.equals("system")) {
|
||||
return SYSTEM;
|
||||
}
|
||||
throw new ExceptionWithContext("Invalid annotation visibility: %s", visibility);
|
||||
}
|
||||
|
||||
private AnnotationVisibility() {}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
public final class DebugItemType {
|
||||
// The debug items that directly correspond with one of the dexlib2.iface.debug interfaces
|
||||
public static final int START_LOCAL = 0x03;
|
||||
public static final int END_LOCAL = 0x05;
|
||||
public static final int RESTART_LOCAL = 0x06;
|
||||
public static final int PROLOGUE_END = 0x07;
|
||||
public static final int EPILOGUE_BEGIN = 0x08;
|
||||
public static final int SET_SOURCE_FILE = 0x09;
|
||||
public static final int LINE_NUMBER = 0x0a;
|
||||
|
||||
// Other items, which are typically handled internally
|
||||
public static final int END_SEQUENCE = 0x00;
|
||||
public static final int ADVANCE_PC = 0x01;
|
||||
public static final int ADVANCE_LINE = 0x02;
|
||||
public static final int START_LOCAL_EXTENDED = 0x04;
|
||||
|
||||
private DebugItemType() {}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
|
||||
import org.jf.dexlib2.iface.DexFile;
|
||||
import org.jf.dexlib2.writer.pool.DexPool;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.*;
|
||||
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 {
|
||||
return loadDexFile(new File(path), new Opcodes(api));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static DexBackedDexFile loadDexFile(File dexFile, int api) throws IOException {
|
||||
return loadDexFile(dexFile, new Opcodes(api));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static DexBackedDexFile loadDexFile(File dexFile, @Nonnull Opcodes opcodes) throws IOException {
|
||||
ZipFile zipFile = null;
|
||||
boolean isZipFile = false;
|
||||
try {
|
||||
zipFile = new ZipFile(dexFile);
|
||||
// if we get here, it's safe to assume we have a zip file
|
||||
isZipFile = true;
|
||||
|
||||
ZipEntry zipEntry = zipFile.getEntry("classes.dex");
|
||||
if (zipEntry == null) {
|
||||
throw new NoClassesDexException("zip file %s does not contain a classes.dex file", dexFile.getName());
|
||||
}
|
||||
long fileLength = zipEntry.getSize();
|
||||
if (fileLength < 40) {
|
||||
throw new ExceptionWithContext(
|
||||
"The classes.dex file in %s is too small to be a valid dex file", dexFile.getName());
|
||||
} else if (fileLength > Integer.MAX_VALUE) {
|
||||
throw new ExceptionWithContext("The classes.dex file in %s is too large to read in", dexFile.getName());
|
||||
}
|
||||
byte[] dexBytes = new byte[(int)fileLength];
|
||||
ByteStreams.readFully(zipFile.getInputStream(zipEntry), dexBytes);
|
||||
return new DexBackedDexFile(opcodes, dexBytes);
|
||||
} catch (IOException ex) {
|
||||
// don't continue on if we know it's a zip file
|
||||
if (isZipFile) {
|
||||
throw ex;
|
||||
}
|
||||
} finally {
|
||||
if (zipFile != null) {
|
||||
try {
|
||||
zipFile.close();
|
||||
} catch (IOException ex) {
|
||||
// just eat it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InputStream inputStream = new BufferedInputStream(new FileInputStream(dexFile));
|
||||
|
||||
try {
|
||||
return DexBackedDexFile.fromInputStream(opcodes, inputStream);
|
||||
} catch (DexBackedDexFile.NotADexFile ex) {
|
||||
// just eat it
|
||||
}
|
||||
|
||||
// Note: DexBackedDexFile.fromInputStream will reset inputStream back to the same position, if it fails
|
||||
|
||||
try {
|
||||
return DexBackedOdexFile.fromInputStream(opcodes, inputStream);
|
||||
} catch (DexBackedOdexFile.NotAnOdexFile ex) {
|
||||
// just eat it
|
||||
}
|
||||
|
||||
throw new ExceptionWithContext("%s is not an apk, dex file or odex file.", dexFile.getPath());
|
||||
}
|
||||
|
||||
public static void writeDexFile(String path, DexFile dexFile) throws IOException {
|
||||
DexPool.writeTo(path, dexFile);
|
||||
}
|
||||
|
||||
private DexFileFactory() {}
|
||||
|
||||
public static class NoClassesDexException extends ExceptionWithContext {
|
||||
public NoClassesDexException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public NoClassesDexException(Throwable cause, String message, Object... formatArgs) {
|
||||
super(cause, message, formatArgs);
|
||||
}
|
||||
|
||||
public NoClassesDexException(String message, Object... formatArgs) {
|
||||
super(message, formatArgs);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
public enum Format {
|
||||
Format10t(2),
|
||||
Format10x(2),
|
||||
Format11n(2),
|
||||
Format11x(2),
|
||||
Format12x(2),
|
||||
Format20bc(4),
|
||||
Format20t(4),
|
||||
Format21c(4),
|
||||
Format21ih(4),
|
||||
Format21lh(4),
|
||||
Format21s(4),
|
||||
Format21t(4),
|
||||
Format22b(4),
|
||||
Format22c(4),
|
||||
Format22cs(4),
|
||||
Format22s(4),
|
||||
Format22t(4),
|
||||
Format22x(4),
|
||||
Format23x(4),
|
||||
Format30t(6),
|
||||
Format31c(6),
|
||||
Format31i(6),
|
||||
Format31t(6),
|
||||
Format32x(6),
|
||||
Format35c(6),
|
||||
Format35mi(6),
|
||||
Format35ms(6),
|
||||
Format3rc(6),
|
||||
Format3rmi(6),
|
||||
Format3rms(6),
|
||||
Format51l(10),
|
||||
ArrayPayload(-1, true),
|
||||
PackedSwitchPayload(-1, true),
|
||||
SparseSwitchPayload(-1, true),
|
||||
UnresolvedOdexInstruction(-1);
|
||||
|
||||
public final int size;
|
||||
public final boolean isPayloadFormat;
|
||||
|
||||
private Format(int size) {
|
||||
this(size, false);
|
||||
}
|
||||
|
||||
private Format(int size, boolean isPayloadFormat) {
|
||||
this.size = size;
|
||||
this.isPayloadFormat = isPayloadFormat;
|
||||
}
|
||||
}
|
@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
public enum Opcode
|
||||
{
|
||||
NOP((short)0x00, "nop", ReferenceType.NONE, Format.Format10x, Opcode.CAN_CONTINUE),
|
||||
MOVE((short)0x01, "move", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_FROM16((short)0x02, "move/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_16((short)0x03, "move/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_WIDE((short)0x04, "move-wide", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MOVE_WIDE_FROM16((short)0x05, "move-wide/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MOVE_WIDE_16((short)0x06, "move-wide/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MOVE_OBJECT((short)0x07, "move-object", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_OBJECT_FROM16((short)0x08, "move-object/from16", ReferenceType.NONE, Format.Format22x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_OBJECT_16((short)0x09, "move-object/16", ReferenceType.NONE, Format.Format32x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_RESULT((short)0x0a, "move-result", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_RESULT_WIDE((short)0x0b, "move-result-wide", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MOVE_RESULT_OBJECT((short)0x0c, "move-result-object", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MOVE_EXCEPTION((short)0x0d, "move-exception", ReferenceType.NONE, Format.Format11x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
RETURN_VOID((short)0x0e, "return-void", ReferenceType.NONE, Format.Format10x),
|
||||
RETURN((short)0x0f, "return", ReferenceType.NONE, Format.Format11x),
|
||||
RETURN_WIDE((short)0x10, "return-wide", ReferenceType.NONE, Format.Format11x),
|
||||
RETURN_OBJECT((short)0x11, "return-object", ReferenceType.NONE, Format.Format11x),
|
||||
CONST_4((short)0x12, "const/4", ReferenceType.NONE, Format.Format11n, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CONST_16((short)0x13, "const/16", ReferenceType.NONE, Format.Format21s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CONST((short)0x14, "const", ReferenceType.NONE, Format.Format31i, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CONST_HIGH16((short)0x15, "const/high16", ReferenceType.NONE, Format.Format21ih, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CONST_WIDE_16((short)0x16, "const-wide/16", ReferenceType.NONE, Format.Format21s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
CONST_WIDE_32((short)0x17, "const-wide/32", ReferenceType.NONE, Format.Format31i, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
CONST_WIDE((short)0x18, "const-wide", ReferenceType.NONE, Format.Format51l, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
CONST_WIDE_HIGH16((short)0x19, "const-wide/high16", ReferenceType.NONE, Format.Format21lh, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
CONST_STRING((short)0x1a, "const-string", ReferenceType.STRING, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER, (short)0x1b),
|
||||
CONST_STRING_JUMBO((short)0x1b, "const-string/jumbo", ReferenceType.STRING, Format.Format31c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CONST_CLASS((short)0x1c, "const-class", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MONITOR_ENTER((short)0x1d, "monitor-enter", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
MONITOR_EXIT((short)0x1e, "monitor-exit", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
CHECK_CAST((short)0x1f, "check-cast", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
INSTANCE_OF((short)0x20, "instance-of", ReferenceType.TYPE, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
ARRAY_LENGTH((short)0x21, "array-length", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
NEW_INSTANCE((short)0x22, "new-instance", ReferenceType.TYPE, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
NEW_ARRAY((short)0x23, "new-array", ReferenceType.TYPE, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
FILLED_NEW_ARRAY((short)0x24, "filled-new-array", ReferenceType.TYPE, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
FILLED_NEW_ARRAY_RANGE((short)0x25, "filled-new-array/range", ReferenceType.TYPE, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
FILL_ARRAY_DATA((short)0x26, "fill-array-data", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
|
||||
THROW((short)0x27, "throw", ReferenceType.NONE, Format.Format11x, Opcode.CAN_THROW),
|
||||
GOTO((short)0x28, "goto", ReferenceType.NONE, Format.Format10t),
|
||||
GOTO_16((short)0x29, "goto/16", ReferenceType.NONE, Format.Format20t),
|
||||
GOTO_32((short)0x2a, "goto/32", ReferenceType.NONE, Format.Format30t),
|
||||
PACKED_SWITCH((short)0x2b, "packed-switch", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
|
||||
SPARSE_SWITCH((short)0x2c, "sparse-switch", ReferenceType.NONE, Format.Format31t, Opcode.CAN_CONTINUE),
|
||||
CMPL_FLOAT((short)0x2d, "cmpl-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CMPG_FLOAT((short)0x2e, "cmpg-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CMPL_DOUBLE((short)0x2f, "cmpl-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CMPG_DOUBLE((short)0x30, "cmpg-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
CMP_LONG((short)0x31, "cmp-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IF_EQ((short)0x32, "if-eq", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
|
||||
IF_NE((short)0x33, "if-ne", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
|
||||
IF_LT((short)0x34, "if-lt", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
|
||||
IF_GE((short)0x35, "if-ge", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
|
||||
IF_GT((short)0x36, "if-gt", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
|
||||
IF_LE((short)0x37, "if-le", ReferenceType.NONE, Format.Format22t, Opcode.CAN_CONTINUE),
|
||||
IF_EQZ((short)0x38, "if-eqz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
|
||||
IF_NEZ((short)0x39, "if-nez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
|
||||
IF_LTZ((short)0x3a, "if-ltz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
|
||||
IF_GEZ((short)0x3b, "if-gez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
|
||||
IF_GTZ((short)0x3c, "if-gtz", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
|
||||
IF_LEZ((short)0x3d, "if-lez", ReferenceType.NONE, Format.Format21t, Opcode.CAN_CONTINUE),
|
||||
AGET((short)0x44, "aget", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AGET_WIDE((short)0x45, "aget-wide", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
AGET_OBJECT((short)0x46, "aget-object", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AGET_BOOLEAN((short)0x47, "aget-boolean", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AGET_BYTE((short)0x48, "aget-byte", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AGET_CHAR((short)0x49, "aget-char", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AGET_SHORT((short)0x4a, "aget-short", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
APUT((short)0x4b, "aput", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
APUT_WIDE((short)0x4c, "aput-wide", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
APUT_OBJECT((short)0x4d, "aput-object", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
APUT_BOOLEAN((short)0x4e, "aput-boolean", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
APUT_BYTE((short)0x4f, "aput-byte", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
APUT_CHAR((short)0x50, "aput-char", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
APUT_SHORT((short)0x51, "aput-short", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IGET((short)0x52, "iget", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IGET_WIDE((short)0x53, "iget-wide", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
IGET_OBJECT((short)0x54, "iget-object", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IGET_BOOLEAN((short)0x55, "iget-boolean", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IGET_BYTE((short)0x56, "iget-byte", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IGET_CHAR((short)0x57, "iget-char", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IGET_SHORT((short)0x58, "iget-short", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IPUT((short)0x59, "iput", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_WIDE((short)0x5a, "iput-wide", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_OBJECT((short)0x5b, "iput-object", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_BOOLEAN((short)0x5c, "iput-boolean", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_BYTE((short)0x5d, "iput-byte", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_CHAR((short)0x5e, "iput-char", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_SHORT((short)0x5f, "iput-short", ReferenceType.FIELD, Format.Format22c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SGET((short)0x60, "sget", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SGET_WIDE((short)0x61, "sget-wide", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SGET_OBJECT((short)0x62, "sget-object", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SGET_BOOLEAN((short)0x63, "sget-boolean", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SGET_BYTE((short)0x64, "sget-byte", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SGET_CHAR((short)0x65, "sget-char", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SGET_SHORT((short)0x66, "sget-short", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SPUT((short)0x67, "sput", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SPUT_WIDE((short)0x68, "sput-wide", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SPUT_OBJECT((short)0x69, "sput-object", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SPUT_BOOLEAN((short)0x6a, "sput-boolean", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SPUT_BYTE((short)0x6b, "sput-byte", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SPUT_CHAR((short)0x6c, "sput-char", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SPUT_SHORT((short)0x6d, "sput-short", ReferenceType.FIELD, Format.Format21c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
INVOKE_VIRTUAL((short)0x6e, "invoke-virtual", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_SUPER((short)0x6f, "invoke-super", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_DIRECT((short)0x70, "invoke-direct", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
|
||||
INVOKE_STATIC((short)0x71, "invoke-static", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_INTERFACE((short)0x72, "invoke-interface", ReferenceType.METHOD, Format.Format35c, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_VIRTUAL_RANGE((short)0x74, "invoke-virtual/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_SUPER_RANGE((short)0x75, "invoke-super/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_DIRECT_RANGE((short)0x76, "invoke-direct/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
|
||||
INVOKE_STATIC_RANGE((short)0x77, "invoke-static/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_INTERFACE_RANGE((short)0x78, "invoke-interface/range", ReferenceType.METHOD, Format.Format3rc, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
NEG_INT((short)0x7b, "neg-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
NOT_INT((short)0x7c, "not-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
NEG_LONG((short)0x7d, "neg-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
NOT_LONG((short)0x7e, "not-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
NEG_FLOAT((short)0x7f, "neg-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
NEG_DOUBLE((short)0x80, "neg-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
INT_TO_LONG((short)0x81, "int-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
INT_TO_FLOAT((short)0x82, "int-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
INT_TO_DOUBLE((short)0x83, "int-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
LONG_TO_INT((short)0x84, "long-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
LONG_TO_FLOAT((short)0x85, "long-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
LONG_TO_DOUBLE((short)0x86, "long-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
FLOAT_TO_INT((short)0x87, "float-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
FLOAT_TO_LONG((short)0x88, "float-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
FLOAT_TO_DOUBLE((short)0x89, "float-to-double", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
DOUBLE_TO_INT((short)0x8a, "double-to-int", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
DOUBLE_TO_LONG((short)0x8b, "double-to-long", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
DOUBLE_TO_FLOAT((short)0x8c, "double-to-float", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
INT_TO_BYTE((short)0x8d, "int-to-byte", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
INT_TO_CHAR((short)0x8e, "int-to-char", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
INT_TO_SHORT((short)0x8f, "int-to-short", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
ADD_INT((short)0x90, "add-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SUB_INT((short)0x91, "sub-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MUL_INT((short)0x92, "mul-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
DIV_INT((short)0x93, "div-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
REM_INT((short)0x94, "rem-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AND_INT((short)0x95, "and-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
OR_INT((short)0x96, "or-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
XOR_INT((short)0x97, "xor-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SHL_INT((short)0x98, "shl-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SHR_INT((short)0x99, "shr-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
USHR_INT((short)0x9a, "ushr-int", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
ADD_LONG((short)0x9b, "add-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SUB_LONG((short)0x9c, "sub-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MUL_LONG((short)0x9d, "mul-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
DIV_LONG((short)0x9e, "div-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
REM_LONG((short)0x9f, "rem-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
AND_LONG((short)0xa0, "and-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
OR_LONG((short)0xa1, "or-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
XOR_LONG((short)0xa2, "xor-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SHL_LONG((short)0xa3, "shl-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SHR_LONG((short)0xa4, "shr-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
USHR_LONG((short)0xa5, "ushr-long", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
ADD_FLOAT((short)0xa6, "add-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SUB_FLOAT((short)0xa7, "sub-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MUL_FLOAT((short)0xa8, "mul-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
DIV_FLOAT((short)0xa9, "div-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
REM_FLOAT((short)0xaa, "rem-float", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
ADD_DOUBLE((short)0xab, "add-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SUB_DOUBLE((short)0xac, "sub-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MUL_DOUBLE((short)0xad, "mul-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
DIV_DOUBLE((short)0xae, "div-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
REM_DOUBLE((short)0xaf, "rem-double", ReferenceType.NONE, Format.Format23x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
ADD_INT_2ADDR((short)0xb0, "add-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SUB_INT_2ADDR((short)0xb1, "sub-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MUL_INT_2ADDR((short)0xb2, "mul-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
DIV_INT_2ADDR((short)0xb3, "div-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
REM_INT_2ADDR((short)0xb4, "rem-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AND_INT_2ADDR((short)0xb5, "and-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
OR_INT_2ADDR((short)0xb6, "or-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
XOR_INT_2ADDR((short)0xb7, "xor-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SHL_INT_2ADDR((short)0xb8, "shl-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SHR_INT_2ADDR((short)0xb9, "shr-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
USHR_INT_2ADDR((short)0xba, "ushr-int/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
ADD_LONG_2ADDR((short)0xbb, "add-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SUB_LONG_2ADDR((short)0xbc, "sub-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MUL_LONG_2ADDR((short)0xbd, "mul-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
DIV_LONG_2ADDR((short)0xbe, "div-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
REM_LONG_2ADDR((short)0xbf, "rem-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
AND_LONG_2ADDR((short)0xc0, "and-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
OR_LONG_2ADDR((short)0xc1, "or-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
XOR_LONG_2ADDR((short)0xc2, "xor-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SHL_LONG_2ADDR((short)0xc3, "shl-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SHR_LONG_2ADDR((short)0xc4, "shr-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
USHR_LONG_2ADDR((short)0xc5, "ushr-long/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
ADD_FLOAT_2ADDR((short)0xc6, "add-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SUB_FLOAT_2ADDR((short)0xc7, "sub-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MUL_FLOAT_2ADDR((short)0xc8, "mul-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
DIV_FLOAT_2ADDR((short)0xc9, "div-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
REM_FLOAT_2ADDR((short)0xca, "rem-float/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
ADD_DOUBLE_2ADDR((short)0xcb, "add-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SUB_DOUBLE_2ADDR((short)0xcc, "sub-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
MUL_DOUBLE_2ADDR((short)0xcd, "mul-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
DIV_DOUBLE_2ADDR((short)0xce, "div-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
REM_DOUBLE_2ADDR((short)0xcf, "rem-double/2addr", ReferenceType.NONE, Format.Format12x, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
ADD_INT_LIT16((short)0xd0, "add-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
RSUB_INT((short)0xd1, "rsub-int", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MUL_INT_LIT16((short)0xd2, "mul-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
DIV_INT_LIT16((short)0xd3, "div-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
REM_INT_LIT16((short)0xd4, "rem-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AND_INT_LIT16((short)0xd5, "and-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
OR_INT_LIT16((short)0xd6, "or-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
XOR_INT_LIT16((short)0xd7, "xor-int/lit16", ReferenceType.NONE, Format.Format22s, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
ADD_INT_LIT8((short)0xd8, "add-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
RSUB_INT_LIT8((short)0xd9, "rsub-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
MUL_INT_LIT8((short)0xda, "mul-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
DIV_INT_LIT8((short)0xdb, "div-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
REM_INT_LIT8((short)0xdc, "rem-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
AND_INT_LIT8((short)0xdd, "and-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
OR_INT_LIT8((short)0xde, "or-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
XOR_INT_LIT8((short)0xdf, "xor-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SHL_INT_LIT8((short)0xe0, "shl-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SHR_INT_LIT8((short)0xe1, "shr-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
USHR_INT_LIT8((short)0xe2, "ushr-int/lit8", ReferenceType.NONE, Format.Format22b, Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
|
||||
IGET_VOLATILE((short)0xe3, "iget-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IPUT_VOLATILE((short)0xe4, "iput-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SGET_VOLATILE((short)0xe5, "sget-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SPUT_VOLATILE((short)0xe6, "sput-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IGET_OBJECT_VOLATILE((short)0xe7, "iget-object-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IGET_WIDE_VOLATILE((short)0xe8, "iget-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
IPUT_WIDE_VOLATILE((short)0xe9, "iput-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SGET_WIDE_VOLATILE((short)0xea, "sget-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
SPUT_WIDE_VOLATILE((short)0xeb, "sput-wide-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
|
||||
THROW_VERIFICATION_ERROR((short)0xed, "throw-verification-error", minApi(5), ReferenceType.NONE, Format.Format20bc, Opcode.ODEX_ONLY | Opcode.CAN_THROW),
|
||||
EXECUTE_INLINE((short)0xee, "execute-inline", ReferenceType.NONE, Format.Format35mi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
EXECUTE_INLINE_RANGE((short)0xef, "execute-inline/range", minApi(8), ReferenceType.NONE, Format.Format3rmi, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_DIRECT_EMPTY((short)0xf0, "invoke-direct-empty", maxApi(13), ReferenceType.METHOD, Format.Format35c, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
|
||||
INVOKE_OBJECT_INIT_RANGE((short)0xf0, "invoke-object-init/range", minApi(14), ReferenceType.METHOD, Format.Format3rc, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT | Opcode.CAN_INITIALIZE_REFERENCE),
|
||||
RETURN_VOID_BARRIER((short)0xf1, "return-void-barrier", minApi(11), ReferenceType.NONE, Format.Format10x, Opcode.ODEX_ONLY),
|
||||
IGET_QUICK((short)0xf2, "iget-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IGET_WIDE_QUICK((short)0xf3, "iget-wide-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER | Opcode.SETS_WIDE_REGISTER),
|
||||
IGET_OBJECT_QUICK((short)0xf4, "iget-object-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
IPUT_QUICK((short)0xf5, "iput-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_WIDE_QUICK((short)0xf6, "iput-wide-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
IPUT_OBJECT_QUICK((short)0xf7, "iput-object-quick", ReferenceType.NONE, Format.Format22cs, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_QUICK | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
INVOKE_VIRTUAL_QUICK((short)0xf8, "invoke-virtual-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_VIRTUAL_QUICK_RANGE((short)0xf9, "invoke-virtual-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_SUPER_QUICK((short)0xfa, "invoke-super-quick", ReferenceType.NONE, Format.Format35ms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
INVOKE_SUPER_QUICK_RANGE((short)0xfb, "invoke-super-quick/range", ReferenceType.NONE, Format.Format3rms, Opcode.ODEX_ONLY | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_RESULT),
|
||||
|
||||
IPUT_OBJECT_VOLATILE((short)0xfc, "iput-object-volatile", minApi(9), ReferenceType.FIELD, Format.Format22c, Opcode.ODEX_ONLY | Opcode.ODEXED_INSTANCE_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
SGET_OBJECT_VOLATILE((short)0xfd, "sget-object-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE | Opcode.SETS_REGISTER),
|
||||
SPUT_OBJECT_VOLATILE((short)0xfe, "sput-object-volatile", minApi(9), ReferenceType.FIELD, Format.Format21c, Opcode.ODEX_ONLY | Opcode.ODEXED_STATIC_VOLATILE | Opcode.CAN_THROW | Opcode.CAN_CONTINUE),
|
||||
|
||||
PACKED_SWITCH_PAYLOAD((short)0x100, "packed-switch-payload", ReferenceType.NONE, Format.PackedSwitchPayload, 0),
|
||||
SPARSE_SWITCH_PAYLOAD((short)0x200, "sparse-switch-payload", ReferenceType.NONE, Format.SparseSwitchPayload, 0),
|
||||
ARRAY_PAYLOAD((short)0x300, "array-payload", ReferenceType.NONE, Format.ArrayPayload, 0);
|
||||
|
||||
//if the instruction can throw an exception
|
||||
public static final int CAN_THROW = 0x1;
|
||||
//if the instruction is an odex only instruction
|
||||
public static final int ODEX_ONLY = 0x2;
|
||||
//if execution can continue to the next instruction
|
||||
public static final int CAN_CONTINUE = 0x4;
|
||||
//if the instruction sets the "hidden" result register
|
||||
public static final int SETS_RESULT = 0x8;
|
||||
//if the instruction sets the value of it's first register
|
||||
public static final int SETS_REGISTER = 0x10;
|
||||
//if the instruction sets the value of it's first register to a wide type
|
||||
public static final int SETS_WIDE_REGISTER = 0x20;
|
||||
//if the instruction is an odexed iget-quick/iput-quick instruction
|
||||
public static final int ODEXED_INSTANCE_QUICK = 0x40;
|
||||
//if the instruction is an odexed iget-volatile/iput-volatile instruction
|
||||
public static final int ODEXED_INSTANCE_VOLATILE = 0x80;
|
||||
//if the instruction is an odexed sget-volatile/sput-volatile instruction
|
||||
public static final int ODEXED_STATIC_VOLATILE = 0x100;
|
||||
//if the instruction is a jumbo instruction
|
||||
public static final int JUMBO_OPCODE = 0x200;
|
||||
//if the instruction can initialize an uninitialized object reference
|
||||
public static final int CAN_INITIALIZE_REFERENCE = 0x400;
|
||||
|
||||
private static final int ALL_APIS = 0xFFFF0000;
|
||||
|
||||
private static int minApi(int api) {
|
||||
return 0xFFFF0000 | (api & 0xFFFF);
|
||||
}
|
||||
|
||||
private static int maxApi(int api) {
|
||||
return api << 16;
|
||||
}
|
||||
|
||||
public final short value;
|
||||
public final String name;
|
||||
// high 16-bits is the max api, low 16-bits is the min api
|
||||
public final int apiConstraints;
|
||||
public final int referenceType;
|
||||
public final Format format;
|
||||
public final int flags;
|
||||
|
||||
Opcode(short opcodeValue, String opcodeName, int referenceType, Format format) {
|
||||
this(opcodeValue, opcodeName, ALL_APIS, referenceType, format, 0, (short)-1);
|
||||
}
|
||||
|
||||
Opcode(short opcodeValue, String opcodeName, int referenceType, Format format, int flags) {
|
||||
this(opcodeValue, opcodeName, ALL_APIS, referenceType, format, flags, (short)-1);
|
||||
}
|
||||
|
||||
Opcode(short opcodeValue, String opcodeName, int referenceType, Format format, int flags, short jumboOpcodeValue) {
|
||||
this(opcodeValue, opcodeName, ALL_APIS, referenceType, format, flags, jumboOpcodeValue);
|
||||
}
|
||||
|
||||
Opcode(short opcodeValue, String opcodeName, int apiConstraints, int referenceType, Format format) {
|
||||
this(opcodeValue, opcodeName, apiConstraints, referenceType, format, 0, (short)-1);
|
||||
}
|
||||
|
||||
Opcode(short opcodeValue, String opcodeName, int apiConstraints, int referenceType, Format format, int flags) {
|
||||
this(opcodeValue, opcodeName, apiConstraints, referenceType, format, flags, (short)-1);
|
||||
}
|
||||
|
||||
Opcode(short opcodeValue, String opcodeName, int apiConstraints, int referenceType, Format format, int flags,
|
||||
short jumboOpcodeValue) {
|
||||
this.value = opcodeValue;
|
||||
this.name = opcodeName;
|
||||
this.apiConstraints = apiConstraints;
|
||||
this.referenceType = referenceType;
|
||||
this.format = format;
|
||||
this.flags = flags;
|
||||
// TODO: implement jumbo opcodes for dexlib2 and uncomment
|
||||
// this.jumboOpcode = jumboOpcodeValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minimum api level that can use this opcode (inclusive)
|
||||
*/
|
||||
public int getMinApi() {
|
||||
return apiConstraints & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum api level that can to use this opcode (inclusive)
|
||||
*/
|
||||
public int getMaxApi() {
|
||||
return apiConstraints >>> 16;
|
||||
}
|
||||
|
||||
public final boolean canThrow() {
|
||||
return (flags & CAN_THROW) != 0;
|
||||
}
|
||||
|
||||
public final boolean odexOnly() {
|
||||
return (flags & ODEX_ONLY) != 0;
|
||||
}
|
||||
|
||||
public final boolean canContinue() {
|
||||
return (flags & CAN_CONTINUE) != 0;
|
||||
}
|
||||
|
||||
public final boolean setsResult() {
|
||||
return (flags & SETS_RESULT) != 0;
|
||||
}
|
||||
|
||||
public final boolean setsRegister() {
|
||||
return (flags & SETS_REGISTER) != 0;
|
||||
}
|
||||
|
||||
public final boolean setsWideRegister() {
|
||||
return (flags & SETS_WIDE_REGISTER) != 0;
|
||||
}
|
||||
|
||||
public final boolean isOdexedInstanceQuick() {
|
||||
return (flags & ODEXED_INSTANCE_QUICK) != 0;
|
||||
}
|
||||
|
||||
public final boolean isOdexedInstanceVolatile() {
|
||||
return (flags & ODEXED_INSTANCE_VOLATILE) != 0;
|
||||
}
|
||||
|
||||
public final boolean isOdexedStaticVolatile() {
|
||||
return (flags & ODEXED_STATIC_VOLATILE) != 0;
|
||||
}
|
||||
|
||||
public final boolean isJumboOpcode() {
|
||||
return (flags & JUMBO_OPCODE) != 0;
|
||||
}
|
||||
|
||||
public final boolean canInitializeReference() {
|
||||
return (flags & CAN_INITIALIZE_REFERENCE) != 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Opcodes {
|
||||
private final Opcode[] opcodesByValue;
|
||||
private final HashMap<String, Opcode> opcodesByName;
|
||||
|
||||
public Opcodes(int api) {
|
||||
opcodesByValue = new Opcode[256];
|
||||
opcodesByName = Maps.newHashMap();
|
||||
|
||||
for (Opcode opcode: Opcode.values()) {
|
||||
if (!opcode.format.isPayloadFormat) {
|
||||
if (api <= opcode.getMaxApi() && api >= opcode.getMinApi()) {
|
||||
opcodesByValue[opcode.value] = opcode;
|
||||
opcodesByName.put(opcode.name.toLowerCase(), opcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Opcode getOpcodeByName(String opcodeName) {
|
||||
return opcodesByName.get(opcodeName.toLowerCase());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Opcode getOpcodeByValue(int opcodeValue) {
|
||||
switch (opcodeValue) {
|
||||
case 0x100:
|
||||
return Opcode.PACKED_SWITCH_PAYLOAD;
|
||||
case 0x200:
|
||||
return Opcode.SPARSE_SWITCH_PAYLOAD;
|
||||
case 0x300:
|
||||
return Opcode.ARRAY_PAYLOAD;
|
||||
default:
|
||||
return opcodesByValue[opcodeValue];
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
public final class ReferenceType {
|
||||
public static final int STRING = 0;
|
||||
public static final int TYPE = 1;
|
||||
public static final int FIELD = 2;
|
||||
public static final int METHOD = 3;
|
||||
public static final int NONE = 4;
|
||||
|
||||
private ReferenceType() {}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
public final class ValueType {
|
||||
public static final int BYTE = 0x00;
|
||||
public static final int SHORT = 0x02;
|
||||
public static final int CHAR = 0x03;
|
||||
public static final int INT = 0x04;
|
||||
public static final int LONG = 0x06;
|
||||
public static final int FLOAT = 0x10;
|
||||
public static final int DOUBLE = 0x11;
|
||||
public static final int STRING = 0x17;
|
||||
public static final int TYPE = 0x18;
|
||||
public static final int FIELD = 0x19;
|
||||
public static final int METHOD = 0x1a;
|
||||
public static final int ENUM = 0x1b;
|
||||
public static final int ARRAY = 0x1c;
|
||||
public static final int ANNOTATION = 0x1d;
|
||||
public static final int NULL = 0x1e;
|
||||
public static final int BOOLEAN = 0x1f;
|
||||
|
||||
private ValueType() {}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class VerificationError {
|
||||
public static final int GENERIC = 1;
|
||||
public static final int NO_SUCH_CLASS = 2;
|
||||
public static final int NO_SUCH_FIELD = 3;
|
||||
public static final int NO_SUCH_METHOD = 4;
|
||||
public static final int ILLEGAL_CLASS_ACCESS = 5;
|
||||
public static final int ILLEGAL_FIELD_ACCESS = 6;
|
||||
public static final int ILLEGAL_METHOD_ACCESS = 7;
|
||||
public static final int CLASS_CHANGE_ERROR = 8;
|
||||
public static final int INSTANTIATION_ERROR = 9;
|
||||
|
||||
private static final HashMap<String, Integer> verificationErrorNames = Maps.newHashMap();
|
||||
|
||||
static {
|
||||
verificationErrorNames.put("generic-error", GENERIC);
|
||||
verificationErrorNames.put("no-such-class", NO_SUCH_CLASS);
|
||||
verificationErrorNames.put("no-such-field", NO_SUCH_FIELD);
|
||||
verificationErrorNames.put("no-such-method", NO_SUCH_METHOD);
|
||||
verificationErrorNames.put("illegal-class-access", ILLEGAL_CLASS_ACCESS);
|
||||
verificationErrorNames.put("illegal-field-access", ILLEGAL_FIELD_ACCESS);
|
||||
verificationErrorNames.put("illegal-method-access", ILLEGAL_METHOD_ACCESS);
|
||||
verificationErrorNames.put("class-change-error", CLASS_CHANGE_ERROR);
|
||||
verificationErrorNames.put("instantiation-error", INSTANTIATION_ERROR);
|
||||
}
|
||||
|
||||
public static String getVerificationErrorName(int verificationError) {
|
||||
switch (verificationError) {
|
||||
case GENERIC:
|
||||
return "generic-error";
|
||||
case NO_SUCH_CLASS:
|
||||
return "no-such-class";
|
||||
case NO_SUCH_FIELD:
|
||||
return "no-such-field";
|
||||
case NO_SUCH_METHOD:
|
||||
return "no-such-method";
|
||||
case ILLEGAL_CLASS_ACCESS:
|
||||
return "illegal-class-access";
|
||||
case ILLEGAL_FIELD_ACCESS:
|
||||
return "illegal-field-access";
|
||||
case ILLEGAL_METHOD_ACCESS:
|
||||
return "illegal-method-access";
|
||||
case CLASS_CHANGE_ERROR:
|
||||
return "class-change-error";
|
||||
case INSTANTIATION_ERROR:
|
||||
return "instantiation-error";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getVerificationError(String verificationError) {
|
||||
Integer ret = verificationErrorNames.get(verificationError);
|
||||
if (ret == null) {
|
||||
throw new ExceptionWithContext("Invalid verification error: %s", verificationError);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static boolean isValidVerificationError(int verificationError) {
|
||||
return verificationError > 0 && verificationError < 10;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
public class AnalysisException extends ExceptionWithContext {
|
||||
public int codeAddress;
|
||||
|
||||
public AnalysisException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public AnalysisException(Throwable cause, String message, Object... formatArgs) {
|
||||
super(cause, message, formatArgs);
|
||||
}
|
||||
|
||||
public AnalysisException(String message, Object... formatArgs) {
|
||||
super(message, formatArgs);
|
||||
}
|
||||
}
|
@ -0,0 +1,332 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.dexlib2.iface.instruction.*;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
import org.jf.dexlib2.iface.reference.Reference;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
|
||||
public class AnalyzedInstruction implements Comparable<AnalyzedInstruction> {
|
||||
/**
|
||||
* The actual instruction
|
||||
*/
|
||||
protected Instruction instruction;
|
||||
|
||||
/**
|
||||
* The index of the instruction, where the first instruction in the method is at index 0, and so on
|
||||
*/
|
||||
protected final int instructionIndex;
|
||||
|
||||
/**
|
||||
* Instructions that can pass on execution to this one during normal execution
|
||||
*/
|
||||
protected final TreeSet<AnalyzedInstruction> predecessors = new TreeSet<AnalyzedInstruction>();
|
||||
|
||||
/**
|
||||
* Instructions that can execution could pass on to next during normal execution
|
||||
*/
|
||||
protected final LinkedList<AnalyzedInstruction> successors = new LinkedList<AnalyzedInstruction>();
|
||||
|
||||
/**
|
||||
* This contains the register types *before* the instruction has executed
|
||||
*/
|
||||
protected final RegisterType[] preRegisterMap;
|
||||
|
||||
/**
|
||||
* This contains the register types *after* the instruction has executed
|
||||
*/
|
||||
protected final RegisterType[] postRegisterMap;
|
||||
|
||||
/**
|
||||
* When deodexing, we might need to deodex this instruction multiple times, when we merge in new register
|
||||
* information. When this happens, we need to restore the original (odexed) instruction, so we can deodex it again
|
||||
*/
|
||||
protected final Instruction originalInstruction;
|
||||
|
||||
public AnalyzedInstruction(Instruction instruction, int instructionIndex, int registerCount) {
|
||||
this.instruction = instruction;
|
||||
this.originalInstruction = instruction;
|
||||
this.instructionIndex = instructionIndex;
|
||||
this.postRegisterMap = new RegisterType[registerCount];
|
||||
this.preRegisterMap = new RegisterType[registerCount];
|
||||
RegisterType unknown = RegisterType.getRegisterType(RegisterType.UNKNOWN, null);
|
||||
for (int i=0; i<registerCount; i++) {
|
||||
preRegisterMap[i] = unknown;
|
||||
postRegisterMap[i] = unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public int getInstructionIndex() {
|
||||
return instructionIndex;
|
||||
}
|
||||
|
||||
public int getPredecessorCount() {
|
||||
return predecessors.size();
|
||||
}
|
||||
|
||||
public SortedSet<AnalyzedInstruction> getPredecessors() {
|
||||
return Collections.unmodifiableSortedSet(predecessors);
|
||||
}
|
||||
|
||||
protected boolean addPredecessor(AnalyzedInstruction predecessor) {
|
||||
return predecessors.add(predecessor);
|
||||
}
|
||||
|
||||
protected void addSuccessor(AnalyzedInstruction successor) {
|
||||
successors.add(successor);
|
||||
}
|
||||
|
||||
protected void setDeodexedInstruction(Instruction instruction) {
|
||||
assert originalInstruction.getOpcode().odexOnly();
|
||||
this.instruction = instruction;
|
||||
}
|
||||
|
||||
protected void restoreOdexedInstruction() {
|
||||
assert originalInstruction.getOpcode().odexOnly();
|
||||
instruction = originalInstruction;
|
||||
}
|
||||
|
||||
public int getSuccessorCount() {
|
||||
return successors.size();
|
||||
}
|
||||
|
||||
public List<AnalyzedInstruction> getSuccesors() {
|
||||
return Collections.unmodifiableList(successors);
|
||||
}
|
||||
|
||||
public Instruction getInstruction() {
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public Instruction getOriginalInstruction() {
|
||||
return originalInstruction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this instruction a "beginning instruction". A beginning instruction is defined to be an instruction
|
||||
* that can be the first successfully executed instruction in the method. The first instruction is always a
|
||||
* beginning instruction. If the first instruction can throw an exception, and is covered by a try block, then
|
||||
* the first instruction of any exception handler for that try block is also a beginning instruction. And likewise,
|
||||
* if any of those instructions can throw an exception and are covered by try blocks, the first instruction of the
|
||||
* corresponding exception handler is a beginning instruction, etc.
|
||||
*
|
||||
* To determine this, we simply check if the first predecessor is the fake "StartOfMethod" instruction, which has
|
||||
* an instruction index of -1.
|
||||
* @return a boolean value indicating whether this instruction is a beginning instruction
|
||||
*/
|
||||
public boolean isBeginningInstruction() {
|
||||
//if this instruction has no predecessors, it is either the fake "StartOfMethod" instruction or it is an
|
||||
//unreachable instruction.
|
||||
if (predecessors.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (predecessors.first().instructionIndex == -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merges the given register type into the specified pre-instruction register, and also sets the post-instruction
|
||||
* register type accordingly if it isn't a destination register for this instruction
|
||||
* @param registerNumber Which register to set
|
||||
* @param registerType The register type
|
||||
* @returns true If the post-instruction register type was changed. This might be false if either the specified
|
||||
* register is a destination register for this instruction, or if the pre-instruction register type didn't change
|
||||
* after merging in the given register type
|
||||
*/
|
||||
protected boolean mergeRegister(int registerNumber, RegisterType registerType, BitSet verifiedInstructions) {
|
||||
assert registerNumber >= 0 && registerNumber < postRegisterMap.length;
|
||||
assert registerType != null;
|
||||
|
||||
RegisterType oldRegisterType = preRegisterMap[registerNumber];
|
||||
RegisterType mergedRegisterType = oldRegisterType.merge(registerType);
|
||||
|
||||
if (mergedRegisterType.equals(oldRegisterType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
preRegisterMap[registerNumber] = mergedRegisterType;
|
||||
verifiedInstructions.clear(instructionIndex);
|
||||
|
||||
if (!setsRegister(registerNumber)) {
|
||||
postRegisterMap[registerNumber] = mergedRegisterType;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over the predecessors of this instruction, and merges all the post-instruction register types for the
|
||||
* given register. Any dead, unreachable, or odexed predecessor is ignored
|
||||
* @param registerNumber the register number
|
||||
* @return The register type resulting from merging the post-instruction register types from all predecessors
|
||||
*/
|
||||
protected RegisterType mergePreRegisterTypeFromPredecessors(int registerNumber) {
|
||||
RegisterType mergedRegisterType = null;
|
||||
for (AnalyzedInstruction predecessor: predecessors) {
|
||||
RegisterType predecessorRegisterType = predecessor.postRegisterMap[registerNumber];
|
||||
assert predecessorRegisterType != null;
|
||||
mergedRegisterType = predecessorRegisterType.merge(mergedRegisterType);
|
||||
}
|
||||
return mergedRegisterType;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the "post-instruction" register type as indicated.
|
||||
* @param registerNumber Which register to set
|
||||
* @param registerType The "post-instruction" register type
|
||||
* @returns true if the given register type is different than the existing post-instruction register type
|
||||
*/
|
||||
protected boolean setPostRegisterType(int registerNumber, RegisterType registerType) {
|
||||
assert registerNumber >= 0 && registerNumber < postRegisterMap.length;
|
||||
assert registerType != null;
|
||||
|
||||
RegisterType oldRegisterType = postRegisterMap[registerNumber];
|
||||
if (oldRegisterType.equals(registerType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
postRegisterMap[registerNumber] = registerType;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
protected boolean isInvokeInit() {
|
||||
if (instruction == null || !instruction.getOpcode().canInitializeReference()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReferenceInstruction instruction = (ReferenceInstruction)this.instruction;
|
||||
|
||||
Reference reference = instruction.getReference();
|
||||
if (reference instanceof MethodReference) {
|
||||
return ((MethodReference)reference).getName().equals("<init>");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean setsRegister() {
|
||||
return instruction.getOpcode().setsRegister();
|
||||
}
|
||||
|
||||
public boolean setsWideRegister() {
|
||||
return instruction.getOpcode().setsWideRegister();
|
||||
}
|
||||
|
||||
public boolean setsRegister(int registerNumber) {
|
||||
//When constructing a new object, the register type will be an uninitialized reference after the new-instance
|
||||
//instruction, but becomes an initialized reference once the <init> method is called. So even though invoke
|
||||
//instructions don't normally change any registers, calling an <init> method will change the type of its
|
||||
//object register. If the uninitialized reference has been copied to other registers, they will be initialized
|
||||
//as well, so we need to check for that too
|
||||
if (isInvokeInit()) {
|
||||
int destinationRegister;
|
||||
if (instruction instanceof FiveRegisterInstruction) {
|
||||
destinationRegister = ((FiveRegisterInstruction)instruction).getRegisterC();
|
||||
} else {
|
||||
assert instruction instanceof RegisterRangeInstruction;
|
||||
RegisterRangeInstruction rangeInstruction = (RegisterRangeInstruction)instruction;
|
||||
assert rangeInstruction.getRegisterCount() > 0;
|
||||
destinationRegister = rangeInstruction.getStartRegister();
|
||||
}
|
||||
|
||||
if (registerNumber == destinationRegister) {
|
||||
return true;
|
||||
}
|
||||
RegisterType preInstructionDestRegisterType = getPreInstructionRegisterType(registerNumber);
|
||||
if (preInstructionDestRegisterType.category != RegisterType.UNINIT_REF &&
|
||||
preInstructionDestRegisterType.category != RegisterType.UNINIT_THIS) {
|
||||
|
||||
return false;
|
||||
}
|
||||
//check if the uninit ref has been copied to another register
|
||||
if (getPreInstructionRegisterType(registerNumber).equals(preInstructionDestRegisterType)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!setsRegister()) {
|
||||
return false;
|
||||
}
|
||||
int destinationRegister = getDestinationRegister();
|
||||
|
||||
if (registerNumber == destinationRegister) {
|
||||
return true;
|
||||
}
|
||||
if (setsWideRegister() && registerNumber == (destinationRegister + 1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getDestinationRegister() {
|
||||
if (!this.instruction.getOpcode().setsRegister()) {
|
||||
throw new ExceptionWithContext("Cannot call getDestinationRegister() for an instruction that doesn't " +
|
||||
"store a value");
|
||||
}
|
||||
return ((OneRegisterInstruction)instruction).getRegisterA();
|
||||
}
|
||||
|
||||
public int getRegisterCount() {
|
||||
return postRegisterMap.length;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public RegisterType getPostInstructionRegisterType(int registerNumber) {
|
||||
return postRegisterMap[registerNumber];
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public RegisterType getPreInstructionRegisterType(int registerNumber) {
|
||||
return preRegisterMap[registerNumber];
|
||||
}
|
||||
|
||||
public int compareTo(AnalyzedInstruction analyzedInstruction) {
|
||||
if (instructionIndex < analyzedInstruction.instructionIndex) {
|
||||
return -1;
|
||||
} else if (instructionIndex == analyzedInstruction.instructionIndex) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
import org.jf.dexlib2.immutable.reference.ImmutableFieldReference;
|
||||
import org.jf.dexlib2.util.TypeUtils;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ArrayProto implements TypeProto {
|
||||
protected final ClassPath classPath;
|
||||
protected final int dimensions;
|
||||
protected final String elementType;
|
||||
|
||||
public ArrayProto(@Nonnull ClassPath classPath, @Nonnull String type) {
|
||||
this.classPath = classPath;
|
||||
int i=0;
|
||||
while (type.charAt(i) == '[') {
|
||||
i++;
|
||||
if (i == type.length()) {
|
||||
throw new ExceptionWithContext("Invalid array type: %s", type);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
throw new ExceptionWithContext("Invalid array type: %s", type);
|
||||
}
|
||||
|
||||
dimensions = i;
|
||||
elementType = type.substring(i);
|
||||
}
|
||||
|
||||
@Override public String toString() { return getType(); }
|
||||
@Nonnull @Override public ClassPath getClassPath() { return classPath; }
|
||||
@Nonnull @Override public String getType() { return makeArrayType(elementType, dimensions); }
|
||||
public int getDimensions() { return dimensions; }
|
||||
@Override public boolean isInterface() { return false; }
|
||||
|
||||
/**
|
||||
* @return The base element type of this array. E.g. This would return Ljava/lang/String; for [[Ljava/lang/String;
|
||||
*/
|
||||
@Nonnull public String getElementType() { return elementType; }
|
||||
|
||||
/**
|
||||
* @return The immediate element type of this array. E.g. This would return [Ljava/lang/String; for
|
||||
* [[Ljava/lang/String;
|
||||
*/
|
||||
@Nonnull public String getImmediateElementType() {
|
||||
if (dimensions > 1) {
|
||||
return makeArrayType(elementType, dimensions-1);
|
||||
}
|
||||
return elementType;
|
||||
}
|
||||
|
||||
@Override public boolean implementsInterface(@Nonnull String iface) {
|
||||
return iface.equals("Ljava/lang/Cloneable;") || iface.equals("Ljava/io/Serializable;");
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
public String getSuperclass() {
|
||||
return "Ljava/lang/Object;";
|
||||
}
|
||||
|
||||
@Nonnull @Override
|
||||
public TypeProto getCommonSuperclass(@Nonnull TypeProto other) {
|
||||
if (other instanceof ArrayProto) {
|
||||
if (TypeUtils.isPrimitiveType(getElementType()) ||
|
||||
TypeUtils.isPrimitiveType(((ArrayProto)other).getElementType())) {
|
||||
if (dimensions == ((ArrayProto)other).dimensions &&
|
||||
getElementType().equals(((ArrayProto)other).getElementType())) {
|
||||
return this;
|
||||
}
|
||||
return classPath.getClass("Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
if (dimensions == ((ArrayProto)other).dimensions) {
|
||||
TypeProto thisClass = classPath.getClass(elementType);
|
||||
TypeProto otherClass = classPath.getClass(((ArrayProto)other).elementType);
|
||||
TypeProto mergedClass = thisClass.getCommonSuperclass(otherClass);
|
||||
if (thisClass == mergedClass) {
|
||||
return this;
|
||||
}
|
||||
if (otherClass == mergedClass) {
|
||||
return other;
|
||||
}
|
||||
return classPath.getClass(makeArrayType(mergedClass.getType(), dimensions));
|
||||
}
|
||||
|
||||
int dimensions = Math.min(this.dimensions, ((ArrayProto)other).dimensions);
|
||||
return classPath.getClass(makeArrayType("Ljava/lang/Object;", dimensions));
|
||||
}
|
||||
|
||||
if (other instanceof ClassProto) {
|
||||
try {
|
||||
if (other.isInterface()) {
|
||||
if (implementsInterface(other.getType())) {
|
||||
return other;
|
||||
}
|
||||
}
|
||||
} catch (UnresolvedClassException ex) {
|
||||
// ignore
|
||||
}
|
||||
return classPath.getClass("Ljava/lang/Object;");
|
||||
}
|
||||
|
||||
// otherwise, defer to the other class' getCommonSuperclass
|
||||
return other.getCommonSuperclass(this);
|
||||
}
|
||||
|
||||
private static final String BRACKETS = Strings.repeat("[", 256);
|
||||
|
||||
@Nonnull
|
||||
private static String makeArrayType(@Nonnull String elementType, int dimensions) {
|
||||
return BRACKETS.substring(0, dimensions) + elementType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FieldReference getFieldByOffset(int fieldOffset) {
|
||||
if (fieldOffset==8) {
|
||||
return new ImmutableFieldReference(getType(), "length", "int");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MethodReference getMethodByVtableIndex(int vtableIndex) {
|
||||
return classPath.getClass("Ljava/lang/Object;").getMethodByVtableIndex(vtableIndex);
|
||||
}
|
||||
}
|
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
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.analysis.reflection.ReflectionClassDef;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.DexFile;
|
||||
import org.jf.dexlib2.immutable.ImmutableDexFile;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ClassPath {
|
||||
@Nonnull private final TypeProto unknownClass;
|
||||
@Nonnull private HashMap<String, ClassDef> availableClasses = Maps.newHashMap();
|
||||
private int api;
|
||||
|
||||
/**
|
||||
* Creates a new ClassPath instance that can load classes from the given dex files
|
||||
*
|
||||
* @param classPath An array of DexFile objects. When loading a class, these dex files will be searched in order
|
||||
*/
|
||||
public ClassPath(DexFile... classPath) throws IOException {
|
||||
this(Lists.newArrayList(classPath), 15);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 api API level
|
||||
*/
|
||||
public ClassPath(@Nonnull Iterable<DexFile> classPath, int api) {
|
||||
// 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.api = api;
|
||||
|
||||
loadPrimitiveType("Z");
|
||||
loadPrimitiveType("B");
|
||||
loadPrimitiveType("S");
|
||||
loadPrimitiveType("C");
|
||||
loadPrimitiveType("I");
|
||||
loadPrimitiveType("J");
|
||||
loadPrimitiveType("F");
|
||||
loadPrimitiveType("D");
|
||||
loadPrimitiveType("L");
|
||||
|
||||
for (DexFile dexFile: dexFiles) {
|
||||
for (ClassDef classDef: dexFile.getClasses()) {
|
||||
ClassDef prev = availableClasses.get(classDef.getType());
|
||||
if (prev == null) {
|
||||
availableClasses.put(classDef.getType(), classDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadPrimitiveType(String type) {
|
||||
loadedClasses.put(type, new PrimitiveProto(this, type));
|
||||
}
|
||||
|
||||
private static DexFile getBasicClasses() {
|
||||
// fallbacks for some special classes that we assume are present
|
||||
return new ImmutableDexFile(ImmutableSet.of(
|
||||
new ReflectionClassDef(Class.class),
|
||||
new ReflectionClassDef(Cloneable.class),
|
||||
new ReflectionClassDef(Object.class),
|
||||
new ReflectionClassDef(Serializable.class),
|
||||
new ReflectionClassDef(String.class),
|
||||
new ReflectionClassDef(Throwable.class)));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public TypeProto getClass(CharSequence type) {
|
||||
return loadedClasses.getUnchecked(type.toString());
|
||||
}
|
||||
|
||||
private final CacheLoader<String, TypeProto> classLoader = new CacheLoader<String, TypeProto>() {
|
||||
@Override public TypeProto load(String type) throws Exception {
|
||||
if (type.charAt(0) == '[') {
|
||||
return new ArrayProto(ClassPath.this, type);
|
||||
} else {
|
||||
return new ClassProto(ClassPath.this, type);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Nonnull private LoadingCache<String, TypeProto> loadedClasses = CacheBuilder.newBuilder().build(classLoader);
|
||||
|
||||
@Nonnull
|
||||
public ClassDef getClassDef(String type) {
|
||||
ClassDef ret = availableClasses.get(type);
|
||||
if (ret == null) {
|
||||
throw new UnresolvedClassException("Could not resolve class %s", type);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public TypeProto getUnknownClass() {
|
||||
return unknownClass;
|
||||
}
|
||||
|
||||
public int getApi() {
|
||||
return api;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static ClassPath fromClassPath(Iterable<String> classPathDirs, Iterable<String> classPath, DexFile dexFile,
|
||||
int api) {
|
||||
ArrayList<DexFile> dexFiles = Lists.newArrayList();
|
||||
|
||||
for (String classPathEntry: classPath) {
|
||||
dexFiles.add(loadClassPathEntry(classPathDirs, classPathEntry, api));
|
||||
}
|
||||
dexFiles.add(dexFile);
|
||||
return new ClassPath(dexFiles, api);
|
||||
}
|
||||
|
||||
private static final Pattern dalvikCacheOdexPattern = Pattern.compile("@([^@]+)@classes.dex$");
|
||||
|
||||
@Nonnull
|
||||
private static DexFile loadClassPathEntry(@Nonnull Iterable<String> classPathDirs,
|
||||
@Nonnull String bootClassPathEntry, int api) {
|
||||
File rawEntry = new File(bootClassPathEntry);
|
||||
// strip off the path - we only care about the filename
|
||||
String entryName = rawEntry.getName();
|
||||
|
||||
// if it's a dalvik-cache entry, grab the name of the jar/apk
|
||||
if (entryName.endsWith("@classes.dex")) {
|
||||
Matcher m = dalvikCacheOdexPattern.matcher(entryName);
|
||||
|
||||
if (!m.find()) {
|
||||
throw new ExceptionWithContext(String.format("Cannot parse dependency value %s", bootClassPathEntry));
|
||||
}
|
||||
|
||||
entryName = m.group(1);
|
||||
}
|
||||
|
||||
int extIndex = entryName.lastIndexOf(".");
|
||||
|
||||
String baseEntryName;
|
||||
if (extIndex == -1) {
|
||||
baseEntryName = entryName;
|
||||
} else {
|
||||
baseEntryName = entryName.substring(0, extIndex);
|
||||
}
|
||||
|
||||
for (String classPathDir: classPathDirs) {
|
||||
for (String ext: new String[]{"", ".odex", ".jar", ".apk", ".zip"}) {
|
||||
File file = new File(classPathDir, baseEntryName + ext);
|
||||
|
||||
if (file.exists() && file.isFile()) {
|
||||
if (!file.canRead()) {
|
||||
System.err.println(String.format(
|
||||
"warning: cannot open %s for reading. Will continue looking.", file.getPath()));
|
||||
} else {
|
||||
try {
|
||||
return DexFileFactory.loadDexFile(file, api);
|
||||
} catch (DexFileFactory.NoClassesDexException ex) {
|
||||
// ignore and continue
|
||||
} catch (Exception ex) {
|
||||
throw ExceptionWithContext.withContext(ex,
|
||||
"Error while reading boot class path entry \"%s\"", bootClassPathEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new ExceptionWithContext("Cannot locate boot class path file %s", bootClassPathEntry);
|
||||
}
|
||||
}
|
@ -0,0 +1,675 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jf.dexlib2.AccessFlags;
|
||||
import org.jf.dexlib2.analysis.util.TypeProtoUtils;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.Field;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
import org.jf.dexlib2.immutable.ImmutableMethod;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
import org.jf.util.SparseArray;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A class "prototype". This contains things like the interfaces, the superclass, the vtable and the instance fields
|
||||
* and their offsets.
|
||||
*/
|
||||
public class ClassProto implements TypeProto {
|
||||
@Nonnull protected final ClassPath classPath;
|
||||
@Nonnull protected final String type;
|
||||
|
||||
protected boolean vtableFullyResolved = true;
|
||||
protected boolean interfacesFullyResolved = true;
|
||||
|
||||
public ClassProto(@Nonnull ClassPath classPath, @Nonnull String type) {
|
||||
if (type.charAt(0) != 'L') {
|
||||
throw new ExceptionWithContext("Cannot construct ClassProto for non reference type: %s", type);
|
||||
}
|
||||
this.classPath = classPath;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override public String toString() { return type; }
|
||||
@Nonnull @Override public ClassPath getClassPath() { return classPath; }
|
||||
@Nonnull @Override public String getType() { return type; }
|
||||
|
||||
@Nonnull
|
||||
public ClassDef getClassDef() {
|
||||
return classDefSupplier.get();
|
||||
}
|
||||
|
||||
|
||||
@Nonnull private final Supplier<ClassDef> classDefSupplier = Suppliers.memoize(new Supplier<ClassDef>() {
|
||||
@Override public ClassDef get() {
|
||||
return classPath.getClassDef(type);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns true if this class is an interface.
|
||||
*
|
||||
* If this class is not defined, then this will throw an UnresolvedClassException
|
||||
*
|
||||
* @return True if this class is an interface
|
||||
*/
|
||||
public boolean isInterface() {
|
||||
ClassDef classDef = getClassDef();
|
||||
return (classDef.getAccessFlags() & AccessFlags.INTERFACE.getValue()) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of interfaces that this class implements as a Map<String, ClassDef>.
|
||||
*
|
||||
* The ClassDef value will be present only for the interfaces that this class directly implements (including any
|
||||
* interfaces transitively implemented), but not for any interfaces that are only implemented by a superclass of
|
||||
* this class
|
||||
*
|
||||
* For any interfaces that are only implemented by a superclass (or the class itself, if the class is an interface),
|
||||
* the value will be null.
|
||||
*
|
||||
* If any interface couldn't be resolved, then the interfacesFullyResolved field will be set to false upon return.
|
||||
*
|
||||
* @return the set of interfaces that this class implements as a Map<String, ClassDef>.
|
||||
*/
|
||||
@Nonnull
|
||||
protected LinkedHashMap<String, ClassDef> getInterfaces() {
|
||||
return interfacesSupplier.get();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private final Supplier<LinkedHashMap<String, ClassDef>> interfacesSupplier =
|
||||
Suppliers.memoize(new Supplier<LinkedHashMap<String, ClassDef>>() {
|
||||
@Override public LinkedHashMap<String, ClassDef> get() {
|
||||
LinkedHashMap<String, ClassDef> interfaces = Maps.newLinkedHashMap();
|
||||
|
||||
try {
|
||||
for (String interfaceType: getClassDef().getInterfaces()) {
|
||||
if (!interfaces.containsKey(interfaceType)) {
|
||||
ClassDef interfaceDef;
|
||||
try {
|
||||
interfaceDef = classPath.getClassDef(interfaceType);
|
||||
interfaces.put(interfaceType, interfaceDef);
|
||||
} catch (UnresolvedClassException ex) {
|
||||
interfaces.put(interfaceType, null);
|
||||
interfacesFullyResolved = false;
|
||||
}
|
||||
|
||||
ClassProto interfaceProto = (ClassProto) classPath.getClass(interfaceType);
|
||||
for (String superInterface: interfaceProto.getInterfaces().keySet()) {
|
||||
if (!interfaces.containsKey(superInterface)) {
|
||||
interfaces.put(superInterface, interfaceProto.getInterfaces().get(superInterface));
|
||||
}
|
||||
}
|
||||
if (!interfaceProto.interfacesFullyResolved) {
|
||||
interfacesFullyResolved = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UnresolvedClassException ex) {
|
||||
interfacesFullyResolved = false;
|
||||
}
|
||||
|
||||
// now add self and super class interfaces, required for common super class lookup
|
||||
// we don't really need ClassDef's for that, so let's just use null
|
||||
|
||||
if (isInterface() && !interfaces.containsKey(getType())) {
|
||||
interfaces.put(getType(), null);
|
||||
}
|
||||
|
||||
try {
|
||||
String superclass = getSuperclass();
|
||||
if (superclass != null) {
|
||||
ClassProto superclassProto = (ClassProto) classPath.getClass(superclass);
|
||||
for (String superclassInterface: superclassProto.getInterfaces().keySet()) {
|
||||
if (!interfaces.containsKey(superclassInterface)) {
|
||||
interfaces.put(superclassInterface, null);
|
||||
}
|
||||
}
|
||||
if (!superclassProto.interfacesFullyResolved) {
|
||||
interfacesFullyResolved = false;
|
||||
}
|
||||
}
|
||||
} catch (UnresolvedClassException ex) {
|
||||
interfacesFullyResolved = false;
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets the interfaces directly implemented by this class, or the interfaces they transitively implement.
|
||||
*
|
||||
* This does not include any interfaces that are only implemented by a superclass
|
||||
*
|
||||
* @return An iterables of ClassDefs representing the directly or transitively implemented interfaces
|
||||
* @throws UnresolvedClassException if interfaces could not be fully resolved
|
||||
*/
|
||||
@Nonnull
|
||||
protected Iterable<ClassDef> getDirectInterfaces() {
|
||||
Iterable<ClassDef> directInterfaces =
|
||||
FluentIterable.from(getInterfaces().values()).filter(Predicates.notNull());
|
||||
|
||||
if (!interfacesFullyResolved) {
|
||||
throw new UnresolvedClassException("Interfaces for class %s not fully resolved", getType());
|
||||
}
|
||||
|
||||
return directInterfaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this class implements the given interface.
|
||||
*
|
||||
* If the interfaces of this class cannot be fully resolved then this
|
||||
* method will either return true or throw an UnresolvedClassException
|
||||
*
|
||||
* @param iface The interface to check for
|
||||
* @return true if this class implements the given interface, otherwise false
|
||||
* @throws UnresolvedClassException if the interfaces for this class could not be fully resolved, and the interface
|
||||
* is not one of the interfaces that were successfully resolved
|
||||
*/
|
||||
@Override
|
||||
public boolean implementsInterface(@Nonnull String iface) {
|
||||
if (getInterfaces().containsKey(iface)) {
|
||||
return true;
|
||||
}
|
||||
if (!interfacesFullyResolved) {
|
||||
throw new UnresolvedClassException("Interfaces for class %s not fully resolved", getType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable @Override
|
||||
public String getSuperclass() {
|
||||
return getClassDef().getSuperclass();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a helper method for getCommonSuperclass
|
||||
*
|
||||
* It checks if this class is an interface, and if so, if other implements it.
|
||||
*
|
||||
* If this class is undefined, we go ahead and check if it is listed in other's interfaces. If not, we throw an
|
||||
* UndefinedClassException
|
||||
*
|
||||
* If the interfaces of other cannot be fully resolved, we check the interfaces that can be resolved. If not found,
|
||||
* we throw an UndefinedClassException
|
||||
*
|
||||
* @param other The class to check the interfaces of
|
||||
* @return true if this class is an interface (or is undefined) other implements this class
|
||||
*
|
||||
*/
|
||||
private boolean checkInterface(@Nonnull ClassProto other) {
|
||||
boolean isResolved = true;
|
||||
boolean isInterface = true;
|
||||
try {
|
||||
isInterface = isInterface();
|
||||
} catch (UnresolvedClassException ex) {
|
||||
isResolved = false;
|
||||
// if we don't know if this class is an interface or not,
|
||||
// we can still try to call other.implementsInterface(this)
|
||||
}
|
||||
if (isInterface) {
|
||||
try {
|
||||
if (other.implementsInterface(getType())) {
|
||||
return true;
|
||||
}
|
||||
} catch (UnresolvedClassException ex) {
|
||||
// There are 2 possibilities here, depending on whether we were able to resolve this class.
|
||||
// 1. If this class is resolved, then we know it is an interface class. The other class either
|
||||
// isn't defined, or its interfaces couldn't be fully resolved.
|
||||
// In this case, we throw an UnresolvedClassException
|
||||
// 2. If this class is not resolved, we had tried to call implementsInterface anyway. We don't
|
||||
// know for sure if this class is an interface or not. We return false, and let processing
|
||||
// continue in getCommonSuperclass
|
||||
if (isResolved) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override @Nonnull
|
||||
public TypeProto getCommonSuperclass(@Nonnull TypeProto other) {
|
||||
// use the other type's more specific implementation
|
||||
if (!(other instanceof ClassProto)) {
|
||||
return other.getCommonSuperclass(this);
|
||||
}
|
||||
|
||||
if (this == other || getType().equals(other.getType())) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (this.getType().equals("Ljava/lang/Object;")) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (other.getType().equals("Ljava/lang/Object;")) {
|
||||
return other;
|
||||
}
|
||||
|
||||
boolean gotException = false;
|
||||
try {
|
||||
if (checkInterface((ClassProto)other)) {
|
||||
return this;
|
||||
}
|
||||
} catch (UnresolvedClassException ex) {
|
||||
gotException = true;
|
||||
}
|
||||
|
||||
try {
|
||||
if (((ClassProto)other).checkInterface(this)) {
|
||||
return other;
|
||||
}
|
||||
} catch (UnresolvedClassException ex) {
|
||||
gotException = true;
|
||||
}
|
||||
if (gotException) {
|
||||
return classPath.getUnknownClass();
|
||||
}
|
||||
|
||||
List<TypeProto> thisChain = Lists.<TypeProto>newArrayList(this);
|
||||
Iterables.addAll(thisChain, TypeProtoUtils.getSuperclassChain(this));
|
||||
|
||||
List<TypeProto> otherChain = Lists.newArrayList(other);
|
||||
Iterables.addAll(otherChain, TypeProtoUtils.getSuperclassChain(other));
|
||||
|
||||
// reverse them, so that the first entry is either Ljava/lang/Object; or Ujava/lang/Object;
|
||||
thisChain = Lists.reverse(thisChain);
|
||||
otherChain = Lists.reverse(otherChain);
|
||||
|
||||
for (int i=Math.min(thisChain.size(), otherChain.size())-1; i>=0; i--) {
|
||||
TypeProto typeProto = thisChain.get(i);
|
||||
if (typeProto.getType().equals(otherChain.get(i).getType())) {
|
||||
return typeProto;
|
||||
}
|
||||
}
|
||||
|
||||
return classPath.getUnknownClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FieldReference getFieldByOffset(int fieldOffset) {
|
||||
if (getInstanceFields().size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return getInstanceFields().get(fieldOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MethodReference getMethodByVtableIndex(int vtableIndex) {
|
||||
List<Method> vtable = getVtable();
|
||||
if (vtableIndex < 0 || vtableIndex >= vtable.size()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return vtable.get(vtableIndex);
|
||||
}
|
||||
|
||||
@Nonnull SparseArray<FieldReference> getInstanceFields() {
|
||||
return instanceFieldsSupplier.get();
|
||||
}
|
||||
|
||||
@Nonnull private final Supplier<SparseArray<FieldReference>> instanceFieldsSupplier =
|
||||
Suppliers.memoize(new Supplier<SparseArray<FieldReference>>() {
|
||||
@Override public SparseArray<FieldReference> get() {
|
||||
//This is a bit of an "involved" operation. We need to follow the same algorithm that dalvik uses to
|
||||
//arrange fields, so that we end up with the same field offsets (which is needed for deodexing).
|
||||
//See mydroid/dalvik/vm/oo/Class.c - computeFieldOffsets()
|
||||
|
||||
final byte REFERENCE = 0;
|
||||
final byte WIDE = 1;
|
||||
final byte OTHER = 2;
|
||||
|
||||
ArrayList<Field> fields = getSortedInstanceFields(getClassDef());
|
||||
final int fieldCount = fields.size();
|
||||
//the "type" for each field in fields. 0=reference,1=wide,2=other
|
||||
byte[] fieldTypes = new byte[fields.size()];
|
||||
for (int i=0; i<fieldCount; i++) {
|
||||
fieldTypes[i] = getFieldType(fields.get(i));
|
||||
}
|
||||
|
||||
//The first operation is to move all of the reference fields to the front. To do this, find the first
|
||||
//non-reference field, then find the last reference field, swap them and repeat
|
||||
int back = fields.size() - 1;
|
||||
int front;
|
||||
for (front = 0; front<fieldCount; front++) {
|
||||
if (fieldTypes[front] != REFERENCE) {
|
||||
while (back > front) {
|
||||
if (fieldTypes[back] == REFERENCE) {
|
||||
swap(fieldTypes, fields, front, back--);
|
||||
break;
|
||||
}
|
||||
back--;
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldTypes[front] != REFERENCE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int startFieldOffset = 8;
|
||||
String superclassType = getSuperclass();
|
||||
ClassProto superclass = null;
|
||||
if (superclassType != null) {
|
||||
superclass = (ClassProto) classPath.getClass(superclassType);
|
||||
if (superclass != null) {
|
||||
startFieldOffset = superclass.getNextFieldOffset();
|
||||
}
|
||||
}
|
||||
|
||||
int fieldIndexMod;
|
||||
if ((startFieldOffset % 8) == 0) {
|
||||
fieldIndexMod = 0;
|
||||
} else {
|
||||
fieldIndexMod = 1;
|
||||
}
|
||||
|
||||
//next, we need to group all the wide fields after the reference fields. But the wide fields have to be
|
||||
//8-byte aligned. If we're on an odd field index, we need to insert a 32-bit field. If the next field
|
||||
//is already a 32-bit field, use that. Otherwise, find the first 32-bit field from the end and swap it in.
|
||||
//If there are no 32-bit fields, do nothing for now. We'll add padding when calculating the field offsets
|
||||
if (front < fieldCount && (front % 2) != fieldIndexMod) {
|
||||
if (fieldTypes[front] == WIDE) {
|
||||
//we need to swap in a 32-bit field, so the wide fields will be correctly aligned
|
||||
back = fieldCount - 1;
|
||||
while (back > front) {
|
||||
if (fieldTypes[back] == OTHER) {
|
||||
swap(fieldTypes, fields, front++, back);
|
||||
break;
|
||||
}
|
||||
back--;
|
||||
}
|
||||
} else {
|
||||
//there's already a 32-bit field here that we can use
|
||||
front++;
|
||||
}
|
||||
}
|
||||
|
||||
//do the swap thing for wide fields
|
||||
back = fieldCount - 1;
|
||||
for (; front<fieldCount; front++) {
|
||||
if (fieldTypes[front] != WIDE) {
|
||||
while (back > front) {
|
||||
if (fieldTypes[back] == WIDE) {
|
||||
swap(fieldTypes, fields, front, back--);
|
||||
break;
|
||||
}
|
||||
back--;
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldTypes[front] != WIDE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SparseArray<FieldReference> superFields;
|
||||
if (superclass != null) {
|
||||
superFields = superclass.getInstanceFields();
|
||||
} else {
|
||||
superFields = new SparseArray<FieldReference>();
|
||||
}
|
||||
int superFieldCount = superFields.size();
|
||||
|
||||
//now the fields are in the correct order. Add them to the SparseArray and lookup, and calculate the offsets
|
||||
int totalFieldCount = superFieldCount + fieldCount;
|
||||
SparseArray<FieldReference> instanceFields = new SparseArray<FieldReference>(totalFieldCount);
|
||||
|
||||
int fieldOffset;
|
||||
|
||||
if (superclass != null && superFieldCount > 0) {
|
||||
for (int i=0; i<superFieldCount; i++) {
|
||||
instanceFields.append(superFields.keyAt(i), superFields.valueAt(i));
|
||||
}
|
||||
|
||||
fieldOffset = instanceFields.keyAt(superFieldCount-1);
|
||||
|
||||
FieldReference lastSuperField = superFields.valueAt(superFieldCount-1);
|
||||
char fieldType = lastSuperField.getType().charAt(0);
|
||||
if (fieldType == 'J' || fieldType == 'D') {
|
||||
fieldOffset += 8;
|
||||
} else {
|
||||
fieldOffset += 4;
|
||||
}
|
||||
} else {
|
||||
//the field values start at 8 bytes into the DataObject dalvik structure
|
||||
fieldOffset = 8;
|
||||
}
|
||||
|
||||
boolean gotDouble = false;
|
||||
for (int i=0; i<fieldCount; i++) {
|
||||
FieldReference field = fields.get(i);
|
||||
|
||||
//add padding to align the wide fields, if needed
|
||||
if (fieldTypes[i] == WIDE && !gotDouble) {
|
||||
if (!gotDouble) {
|
||||
if (fieldOffset % 8 != 0) {
|
||||
assert fieldOffset % 8 == 4;
|
||||
fieldOffset += 4;
|
||||
}
|
||||
gotDouble = true;
|
||||
}
|
||||
}
|
||||
|
||||
instanceFields.append(fieldOffset, field);
|
||||
if (fieldTypes[i] == WIDE) {
|
||||
fieldOffset += 8;
|
||||
} else {
|
||||
fieldOffset += 4;
|
||||
}
|
||||
}
|
||||
|
||||
return instanceFields;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private ArrayList<Field> getSortedInstanceFields(@Nonnull ClassDef classDef) {
|
||||
ArrayList<Field> fields = Lists.newArrayList(classDef.getInstanceFields());
|
||||
Collections.sort(fields);
|
||||
return fields;
|
||||
}
|
||||
|
||||
private byte getFieldType(@Nonnull FieldReference field) {
|
||||
switch (field.getType().charAt(0)) {
|
||||
case '[':
|
||||
case 'L':
|
||||
return 0; //REFERENCE
|
||||
case 'J':
|
||||
case 'D':
|
||||
return 1; //WIDE
|
||||
default:
|
||||
return 2; //OTHER
|
||||
}
|
||||
}
|
||||
|
||||
private void swap(byte[] fieldTypes, List<Field> fields, int position1, int position2) {
|
||||
byte tempType = fieldTypes[position1];
|
||||
fieldTypes[position1] = fieldTypes[position2];
|
||||
fieldTypes[position2] = tempType;
|
||||
|
||||
Field tempField = fields.set(position1, fields.get(position2));
|
||||
fields.set(position2, tempField);
|
||||
}
|
||||
});
|
||||
|
||||
private int getNextFieldOffset() {
|
||||
SparseArray<FieldReference> instanceFields = getInstanceFields();
|
||||
if (instanceFields.size() == 0) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
int lastItemIndex = instanceFields.size()-1;
|
||||
int fieldOffset = instanceFields.keyAt(lastItemIndex);
|
||||
FieldReference lastField = instanceFields.valueAt(lastItemIndex);
|
||||
|
||||
switch (lastField.getType().charAt(0)) {
|
||||
case 'J':
|
||||
case 'D':
|
||||
return fieldOffset + 8;
|
||||
default:
|
||||
return fieldOffset + 4;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull List<Method> getVtable() {
|
||||
return vtableSupplier.get();
|
||||
}
|
||||
|
||||
//TODO: check the case when we have a package private method that overrides an interface method
|
||||
@Nonnull private final Supplier<List<Method>> vtableSupplier = Suppliers.memoize(new Supplier<List<Method>>() {
|
||||
@Override public List<Method> get() {
|
||||
List<Method> vtable = Lists.newArrayList();
|
||||
|
||||
//copy the virtual methods from the superclass
|
||||
String superclassType;
|
||||
try {
|
||||
superclassType = getSuperclass();
|
||||
} catch (UnresolvedClassException ex) {
|
||||
vtable.addAll(((ClassProto)classPath.getClass("Ljava/lang/Object;")).getVtable());
|
||||
vtableFullyResolved = false;
|
||||
return vtable;
|
||||
}
|
||||
|
||||
if (superclassType != null) {
|
||||
ClassProto superclass = (ClassProto) classPath.getClass(superclassType);
|
||||
vtable.addAll(superclass.getVtable());
|
||||
|
||||
// if the superclass's vtable wasn't fully resolved, then we can't know where the new methods added by this
|
||||
// class should start, so we just propagate what we can from the parent and hope for the best.
|
||||
if (!superclass.vtableFullyResolved) {
|
||||
vtableFullyResolved = false;
|
||||
return vtable;
|
||||
}
|
||||
}
|
||||
|
||||
//iterate over the virtual methods in the current class, and only add them when we don't already have the
|
||||
//method (i.e. if it was implemented by the superclass)
|
||||
if (!isInterface()) {
|
||||
addToVtable(getClassDef().getVirtualMethods(), vtable, true);
|
||||
|
||||
// assume that interface method is implemented in the current class, when adding it to vtable
|
||||
// otherwise it looks like that method is invoked on an interface, which fails Dalvik's optimization checks
|
||||
for (ClassDef interfaceDef: getDirectInterfaces()) {
|
||||
List<Method> interfaceMethods = Lists.newArrayList();
|
||||
for (Method interfaceMethod: interfaceDef.getVirtualMethods()) {
|
||||
ImmutableMethod method = new ImmutableMethod(
|
||||
type,
|
||||
interfaceMethod.getName(),
|
||||
interfaceMethod.getParameters(),
|
||||
interfaceMethod.getReturnType(),
|
||||
interfaceMethod.getAccessFlags(),
|
||||
interfaceMethod.getAnnotations(),
|
||||
interfaceMethod.getImplementation());
|
||||
interfaceMethods.add(method);
|
||||
}
|
||||
addToVtable(interfaceMethods, vtable, false);
|
||||
}
|
||||
}
|
||||
return vtable;
|
||||
}
|
||||
|
||||
private void addToVtable(@Nonnull Iterable<? extends Method> localMethods,
|
||||
@Nonnull List<Method> vtable, boolean replaceExisting) {
|
||||
List<? extends Method> methods = Lists.newArrayList(localMethods);
|
||||
Collections.sort(methods);
|
||||
|
||||
outer: for (Method virtualMethod: methods) {
|
||||
for (int i=0; i<vtable.size(); i++) {
|
||||
Method superMethod = vtable.get(i);
|
||||
if (methodSignaturesMatch(superMethod, virtualMethod)) {
|
||||
if (classPath.getApi() < 17 || canAccess(superMethod)) {
|
||||
if (replaceExisting) {
|
||||
vtable.set(i, virtualMethod);
|
||||
}
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
// we didn't find an equivalent method, so add it as a new entry
|
||||
vtable.add(virtualMethod);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean methodSignaturesMatch(@Nonnull Method a, @Nonnull Method b) {
|
||||
return (a.getName().equals(b.getName()) &&
|
||||
a.getReturnType().equals(b.getReturnType()) &&
|
||||
a.getParameters().equals(b.getParameters()));
|
||||
}
|
||||
|
||||
private boolean canAccess(@Nonnull Method virtualMethod) {
|
||||
if (!methodIsPackagePrivate(virtualMethod.getAccessFlags())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String otherPackage = getPackage(virtualMethod.getDefiningClass());
|
||||
String ourPackage = getPackage(getClassDef().getType());
|
||||
return otherPackage.equals(ourPackage);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private String getPackage(@Nonnull String classType) {
|
||||
int lastSlash = classType.lastIndexOf('/');
|
||||
if (lastSlash < 0) {
|
||||
return "";
|
||||
}
|
||||
return classType.substring(1, lastSlash);
|
||||
}
|
||||
|
||||
private boolean methodIsPackagePrivate(int accessFlags) {
|
||||
return (accessFlags & (AccessFlags.PRIVATE.getValue() |
|
||||
AccessFlags.PROTECTED.getValue() |
|
||||
AccessFlags.PUBLIC.getValue())) == 0;
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.instruction.InlineIndexInstruction;
|
||||
import org.jf.dexlib2.immutable.ImmutableMethod;
|
||||
import org.jf.dexlib2.immutable.ImmutableMethodParameter;
|
||||
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference;
|
||||
import org.jf.dexlib2.immutable.util.ParamUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CustomInlineMethodResolver extends InlineMethodResolver {
|
||||
@Nonnull private final ClassPath classPath;
|
||||
@Nonnull private final Method[] inlineMethods;
|
||||
|
||||
public CustomInlineMethodResolver(@Nonnull ClassPath classPath, @Nonnull String inlineTable) {
|
||||
this.classPath = classPath;
|
||||
|
||||
StringReader reader = new StringReader(inlineTable);
|
||||
List<String> lines = new ArrayList<String>();
|
||||
|
||||
BufferedReader br = new BufferedReader(reader);
|
||||
|
||||
try {
|
||||
String line = br.readLine();
|
||||
|
||||
while (line != null) {
|
||||
if (line.length() > 0) {
|
||||
lines.add(line);
|
||||
}
|
||||
|
||||
line = br.readLine();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException("Error while parsing inline table", ex);
|
||||
}
|
||||
|
||||
inlineMethods = new Method[lines.size()];
|
||||
|
||||
for (int i=0; i<inlineMethods.length; i++) {
|
||||
inlineMethods[i] = parseAndResolveInlineMethod(lines.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
public CustomInlineMethodResolver(@Nonnull ClassPath classPath, @Nonnull File inlineTable) throws IOException {
|
||||
this(classPath, Files.toString(inlineTable, Charset.forName("UTF-8")));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Method resolveExecuteInline(@Nonnull AnalyzedInstruction analyzedInstruction) {
|
||||
InlineIndexInstruction instruction = (InlineIndexInstruction)analyzedInstruction.instruction;
|
||||
int methodIndex = instruction.getInlineIndex();
|
||||
|
||||
if (methodIndex < 0 || methodIndex >= inlineMethods.length) {
|
||||
throw new RuntimeException("Invalid method index: " + methodIndex);
|
||||
}
|
||||
return inlineMethods[methodIndex];
|
||||
}
|
||||
|
||||
private static final Pattern longMethodPattern = Pattern.compile("(L[^;]+;)->([^(]+)\\(([^)]*)\\)(.+)");
|
||||
|
||||
@Nonnull
|
||||
private Method parseAndResolveInlineMethod(@Nonnull String inlineMethod) {
|
||||
Matcher m = longMethodPattern.matcher(inlineMethod);
|
||||
if (!m.matches()) {
|
||||
assert false;
|
||||
throw new RuntimeException("Invalid method descriptor: " + inlineMethod);
|
||||
}
|
||||
|
||||
String className = m.group(1);
|
||||
String methodName = m.group(2);
|
||||
Iterable<ImmutableMethodParameter> methodParams = ParamUtil.parseParamString(m.group(3));
|
||||
String methodRet = m.group(4);
|
||||
ImmutableMethodReference methodRef = new ImmutableMethodReference(className, methodName, methodParams,
|
||||
methodRet);
|
||||
|
||||
int accessFlags = 0;
|
||||
|
||||
boolean resolved = false;
|
||||
TypeProto typeProto = classPath.getClass(className);
|
||||
if (typeProto instanceof ClassProto) {
|
||||
ClassDef classDef = ((ClassProto)typeProto).getClassDef();
|
||||
for (Method method: classDef.getMethods()) {
|
||||
if (method.equals(methodRef)) {
|
||||
resolved = true;
|
||||
accessFlags = method.getAccessFlags();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!resolved) {
|
||||
throw new RuntimeException("Cannot resolve inline method: " + inlineMethod);
|
||||
}
|
||||
|
||||
return new ImmutableMethod(className, methodName, methodParams, methodRet, accessFlags, null, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.cli.*;
|
||||
import org.jf.dexlib2.DexFileFactory;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.Field;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.util.ConsoleUtil;
|
||||
import org.jf.util.SparseArray;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class DumpFields {
|
||||
private static final Options options;
|
||||
|
||||
static {
|
||||
options = new Options();
|
||||
buildOptions();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CommandLineParser parser = new PosixParser();
|
||||
CommandLine commandLine;
|
||||
|
||||
try {
|
||||
commandLine = parser.parse(options, args);
|
||||
} catch (ParseException ex) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
String[] remainingArgs = commandLine.getArgs();
|
||||
|
||||
Option[] parsedOptions = commandLine.getOptions();
|
||||
ArrayList<String> bootClassPathDirs = Lists.newArrayList();
|
||||
String outFile = "fields.txt";
|
||||
int apiLevel = 15;
|
||||
|
||||
for (int i=0; i<parsedOptions.length; i++) {
|
||||
Option option = parsedOptions[i];
|
||||
String opt = option.getOpt();
|
||||
|
||||
switch (opt.charAt(0)) {
|
||||
case 'd':
|
||||
bootClassPathDirs.add(option.getValue());
|
||||
break;
|
||||
case 'o':
|
||||
outFile = option.getValue();
|
||||
break;
|
||||
case 'a':
|
||||
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
||||
break;
|
||||
default:
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
|
||||
if (remainingArgs.length != 1) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
String inputDexFileName = remainingArgs[0];
|
||||
|
||||
File dexFileFile = new File(inputDexFileName);
|
||||
if (!dexFileFile.exists()) {
|
||||
System.err.println("Can't find the file " + inputDexFileName);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
DexBackedDexFile dexFile = DexFileFactory.loadDexFile(dexFileFile, apiLevel);
|
||||
Iterable<String> bootClassPaths = Splitter.on(":").split("core.jar:ext.jar:framework.jar:android.policy.jar:services.jar");
|
||||
ClassPath classPath = ClassPath.fromClassPath(bootClassPathDirs, bootClassPaths, dexFile, apiLevel);
|
||||
FileOutputStream outStream = new FileOutputStream(outFile);
|
||||
|
||||
for (ClassDef classDef: dexFile.getClasses()) {
|
||||
ClassProto classProto = (ClassProto) classPath.getClass(classDef);
|
||||
SparseArray<FieldReference> fields = classProto.getInstanceFields();
|
||||
String className = "Class " + classDef.getType() + " : " + fields.size() + " instance fields\n";
|
||||
outStream.write(className.getBytes());
|
||||
for (int i=0;i<fields.size();i++) {
|
||||
String field = fields.keyAt(i) + ":" + fields.valueAt(i).getType() + " " + fields.valueAt(i).getName() + "\n";
|
||||
outStream.write(field.getBytes());
|
||||
}
|
||||
outStream.write("\n".getBytes());
|
||||
}
|
||||
outStream.close();
|
||||
} catch (IOException ex) {
|
||||
System.out.println("IOException thrown when trying to open a dex file or write out vtables: " + ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the usage message.
|
||||
*/
|
||||
private static void usage() {
|
||||
int consoleWidth = ConsoleUtil.getConsoleWidth();
|
||||
if (consoleWidth <= 0) {
|
||||
consoleWidth = 80;
|
||||
}
|
||||
|
||||
System.out.println("java -cp baksmali.jar org.jf.dexlib2.analysis.DumpFields -d path/to/framework/jar/files <dex-file>");
|
||||
}
|
||||
|
||||
private static void buildOptions() {
|
||||
Option classPathDirOption = OptionBuilder.withLongOpt("bootclasspath-dir")
|
||||
.withDescription("the base folder to look for the bootclasspath files in. Defaults to the current " +
|
||||
"directory")
|
||||
.hasArg()
|
||||
.withArgName("DIR")
|
||||
.create("d");
|
||||
|
||||
Option outputFileOption = OptionBuilder.withLongOpt("out-file")
|
||||
.withDescription("output file")
|
||||
.hasArg()
|
||||
.withArgName("FILE")
|
||||
.create("o");
|
||||
|
||||
Option apiLevelOption = OptionBuilder.withLongOpt("api-level")
|
||||
.withDescription("The numeric api-level of the file being disassembled. If not " +
|
||||
"specified, it defaults to 15 (ICS).")
|
||||
.hasArg()
|
||||
.withArgName("API_LEVEL")
|
||||
.create("a");
|
||||
|
||||
options.addOption(classPathDirOption);
|
||||
options.addOption(outputFileOption);
|
||||
options.addOption(apiLevelOption);
|
||||
}
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.cli.*;
|
||||
import org.jf.dexlib2.DexFileFactory;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.util.ConsoleUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DumpVtables {
|
||||
private static final Options options;
|
||||
|
||||
static {
|
||||
options = new Options();
|
||||
buildOptions();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CommandLineParser parser = new PosixParser();
|
||||
CommandLine commandLine;
|
||||
|
||||
try {
|
||||
commandLine = parser.parse(options, args);
|
||||
} catch (ParseException ex) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
String[] remainingArgs = commandLine.getArgs();
|
||||
|
||||
Option[] parsedOptions = commandLine.getOptions();
|
||||
ArrayList<String> bootClassPathDirs = Lists.newArrayList();
|
||||
String outFile = "vtables.txt";
|
||||
int apiLevel = 15;
|
||||
|
||||
for (int i=0; i<parsedOptions.length; i++) {
|
||||
Option option = parsedOptions[i];
|
||||
String opt = option.getOpt();
|
||||
|
||||
switch (opt.charAt(0)) {
|
||||
case 'd':
|
||||
bootClassPathDirs.add(option.getValue());
|
||||
break;
|
||||
case 'o':
|
||||
outFile = option.getValue();
|
||||
break;
|
||||
case 'a':
|
||||
apiLevel = Integer.parseInt(commandLine.getOptionValue("a"));
|
||||
break;
|
||||
default:
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
|
||||
if (remainingArgs.length != 1) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
String inputDexFileName = remainingArgs[0];
|
||||
|
||||
File dexFileFile = new File(inputDexFileName);
|
||||
if (!dexFileFile.exists()) {
|
||||
System.err.println("Can't find the file " + inputDexFileName);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
DexBackedDexFile dexFile = DexFileFactory.loadDexFile(dexFileFile, apiLevel);
|
||||
Iterable<String> bootClassPaths = Splitter.on(":").split("core.jar:ext.jar:framework.jar:android.policy.jar:services.jar");
|
||||
ClassPath classPath = ClassPath.fromClassPath(bootClassPathDirs, bootClassPaths, dexFile, apiLevel);
|
||||
FileOutputStream outStream = new FileOutputStream(outFile);
|
||||
|
||||
for (ClassDef classDef: dexFile.getClasses()) {
|
||||
ClassProto classProto = (ClassProto) classPath.getClass(classDef);
|
||||
List<Method> methods = classProto.getVtable();
|
||||
String className = "Class " + classDef.getType() + " extends " + classDef.getSuperclass() + " : " + methods.size() + " methods\n";
|
||||
outStream.write(className.getBytes());
|
||||
for (int i=0;i<methods.size();i++) {
|
||||
Method method = methods.get(i);
|
||||
|
||||
String methodString = i + ":" + method.getDefiningClass() + "->" + method.getName() + "(";
|
||||
for (CharSequence parameter: method.getParameterTypes()) {
|
||||
methodString += parameter;
|
||||
}
|
||||
methodString += ")" + method.getReturnType() + "\n";
|
||||
outStream.write(methodString.getBytes());
|
||||
}
|
||||
outStream.write("\n".getBytes());
|
||||
}
|
||||
outStream.close();
|
||||
} catch (IOException ex) {
|
||||
System.out.println("IOException thrown when trying to open a dex file or write out vtables: " + ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the usage message.
|
||||
*/
|
||||
private static void usage() {
|
||||
int consoleWidth = ConsoleUtil.getConsoleWidth();
|
||||
if (consoleWidth <= 0) {
|
||||
consoleWidth = 80;
|
||||
}
|
||||
|
||||
System.out.println("java -cp baksmali.jar org.jf.dexlib2.analysis.DumpVtables -d path/to/framework/jar/files <dex-file>");
|
||||
}
|
||||
|
||||
private static void buildOptions() {
|
||||
Option classPathDirOption = OptionBuilder.withLongOpt("bootclasspath-dir")
|
||||
.withDescription("the base folder to look for the bootclasspath files in. Defaults to the current " +
|
||||
"directory")
|
||||
.hasArg()
|
||||
.withArgName("DIR")
|
||||
.create("d");
|
||||
|
||||
Option outputFileOption = OptionBuilder.withLongOpt("out-file")
|
||||
.withDescription("output file")
|
||||
.hasArg()
|
||||
.withArgName("FILE")
|
||||
.create("o");
|
||||
|
||||
Option apiLevelOption = OptionBuilder.withLongOpt("api-level")
|
||||
.withDescription("The numeric api-level of the file being disassembled. If not " +
|
||||
"specified, it defaults to 15 (ICS).")
|
||||
.hasArg()
|
||||
.withArgName("API_LEVEL")
|
||||
.create("a");
|
||||
|
||||
options.addOption(classPathDirOption);
|
||||
options.addOption(outputFileOption);
|
||||
options.addOption(apiLevelOption);
|
||||
}
|
||||
}
|
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.instruction.InlineIndexInstruction;
|
||||
import org.jf.dexlib2.iface.instruction.VariableRegisterInstruction;
|
||||
import org.jf.dexlib2.immutable.ImmutableMethod;
|
||||
import org.jf.dexlib2.immutable.ImmutableMethodParameter;
|
||||
import org.jf.dexlib2.immutable.util.ParamUtil;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public abstract class InlineMethodResolver {
|
||||
// These are the possible values for the accessFlag field on a resolved inline method
|
||||
// We can't use, e.g. AccessFlags.STATIC.value, because we need them to be a constant in order to use them as cases
|
||||
// in switch statements
|
||||
public static final int STATIC = 0x8; // AccessFlags.STATIC.value;
|
||||
public static final int VIRTUAL = 0x1; // AccessFlags.PUBLIC.value;
|
||||
public static final int DIRECT = 0x2; // AccessFlags.PRIVATE.value;
|
||||
|
||||
@Nonnull
|
||||
public static InlineMethodResolver createInlineMethodResolver(int odexVersion) {
|
||||
if (odexVersion == 35) {
|
||||
return new InlineMethodResolver_version35();
|
||||
} else if (odexVersion == 36) {
|
||||
return new InlineMethodResolver_version36();
|
||||
} else {
|
||||
throw new RuntimeException(String.format("odex version %d is not supported yet", odexVersion));
|
||||
}
|
||||
}
|
||||
|
||||
protected InlineMethodResolver() {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private static Method inlineMethod(int accessFlags, @Nonnull String cls, @Nonnull String name,
|
||||
@Nonnull String params, @Nonnull String returnType) {
|
||||
ImmutableList<ImmutableMethodParameter> paramList = ImmutableList.copyOf(ParamUtil.parseParamString(params));
|
||||
return new ImmutableMethod(cls, name, paramList, returnType, accessFlags, null, null);
|
||||
}
|
||||
|
||||
@Nonnull public abstract Method resolveExecuteInline(@Nonnull AnalyzedInstruction instruction);
|
||||
|
||||
private static class InlineMethodResolver_version35 extends InlineMethodResolver
|
||||
{
|
||||
private final Method[] inlineMethods;
|
||||
|
||||
public InlineMethodResolver_version35() {
|
||||
inlineMethods = new Method[] {
|
||||
inlineMethod(STATIC, "Lorg/apache/harmony/dalvik/NativeTestTarget;", "emptyInlineMethod", "", "V"),
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "charAt", "I", "C"),
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "compareTo", "Ljava/lang/String;", "I"),
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "equals", "Ljava/lang/Object;", "Z"),
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "length", "", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "I", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "J", "J"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "F", "F"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "min", "II", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "max", "II", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "sqrt", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "cos", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "sin", "D", "D")
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Method resolveExecuteInline(@Nonnull AnalyzedInstruction analyzedInstruction) {
|
||||
InlineIndexInstruction instruction = (InlineIndexInstruction)analyzedInstruction.instruction;
|
||||
int inlineIndex = instruction.getInlineIndex();
|
||||
|
||||
if (inlineIndex < 0 || inlineIndex >= inlineMethods.length) {
|
||||
throw new RuntimeException("Invalid inline index: " + inlineIndex);
|
||||
}
|
||||
return inlineMethods[inlineIndex];
|
||||
}
|
||||
}
|
||||
|
||||
private static class InlineMethodResolver_version36 extends InlineMethodResolver
|
||||
{
|
||||
private final Method[] inlineMethods;
|
||||
private final Method indexOfIMethod;
|
||||
private final Method indexOfIIMethod;
|
||||
private final Method fastIndexOfMethod;
|
||||
private final Method isEmptyMethod;
|
||||
|
||||
public InlineMethodResolver_version36() {
|
||||
//The 5th and 6th entries differ between froyo and gingerbread. We have to look at the parameters being
|
||||
//passed to distinguish between them.
|
||||
|
||||
//froyo
|
||||
indexOfIMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;", "indexOf", "I", "I");
|
||||
indexOfIIMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;", "indexOf", "II", "I");
|
||||
|
||||
//gingerbread
|
||||
fastIndexOfMethod = inlineMethod(DIRECT, "Ljava/lang/String;", "fastIndexOf", "II", "I");
|
||||
isEmptyMethod = inlineMethod(VIRTUAL, "Ljava/lang/String;", "isEmpty", "", "Z");
|
||||
|
||||
inlineMethods = new Method[] {
|
||||
inlineMethod(STATIC, "Lorg/apache/harmony/dalvik/NativeTestTarget;", "emptyInlineMethod", "", "V"),
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "charAt", "I", "C"),
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "compareTo", "Ljava/lang/String;", "I"),
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "equals", "Ljava/lang/Object;", "Z"),
|
||||
//froyo: deodexUtil.new InlineMethod(VIRTUAL, "Ljava/lang/String;", "indexOf", "I", "I"),
|
||||
//gingerbread: deodexUtil.new InlineMethod(VIRTUAL, "Ljava/lang/String;", "fastIndexOf", "II", "I"),
|
||||
null,
|
||||
//froyo: deodexUtil.new InlineMethod(VIRTUAL, "Ljava/lang/String;", "indexOf", "II", "I"),
|
||||
//gingerbread: deodexUtil.new InlineMethod(VIRTUAL, "Ljava/lang/String;", "isEmpty", "", "Z"),
|
||||
null,
|
||||
inlineMethod(VIRTUAL, "Ljava/lang/String;", "length", "", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "I", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "J", "J"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "F", "F"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "abs", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "min", "II", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "max", "II", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "sqrt", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "cos", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Math;", "sin", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Float;", "floatToIntBits", "F", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Float;", "floatToRawIntBits", "F", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Float;", "intBitsToFloat", "I", "F"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Double;", "doubleToLongBits", "D", "J"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Double;", "doubleToRawLongBits", "D", "J"),
|
||||
inlineMethod(STATIC, "Ljava/lang/Double;", "longBitsToDouble", "J", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/StrictMath;", "abs", "I", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/StrictMath;", "abs", "J", "J"),
|
||||
inlineMethod(STATIC, "Ljava/lang/StrictMath;", "abs", "F", "F"),
|
||||
inlineMethod(STATIC, "Ljava/lang/StrictMath;", "abs", "D", "D"),
|
||||
inlineMethod(STATIC, "Ljava/lang/StrictMath;", "min", "II", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/StrictMath;", "max", "II", "I"),
|
||||
inlineMethod(STATIC, "Ljava/lang/StrictMath;", "sqrt", "D", "D"),
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Method resolveExecuteInline(@Nonnull AnalyzedInstruction analyzedInstruction) {
|
||||
InlineIndexInstruction instruction = (InlineIndexInstruction)analyzedInstruction.instruction;
|
||||
int inlineIndex = instruction.getInlineIndex();
|
||||
|
||||
if (inlineIndex < 0 || inlineIndex >= inlineMethods.length) {
|
||||
throw new RuntimeException("Invalid method index: " + inlineIndex);
|
||||
}
|
||||
|
||||
if (inlineIndex == 4) {
|
||||
int parameterCount = ((VariableRegisterInstruction)instruction).getRegisterCount();
|
||||
if (parameterCount == 2) {
|
||||
return indexOfIMethod;
|
||||
} else if (parameterCount == 3) {
|
||||
return fastIndexOfMethod;
|
||||
} else {
|
||||
throw new RuntimeException("Could not determine the correct inline method to use");
|
||||
}
|
||||
} else if (inlineIndex == 5) {
|
||||
int parameterCount = ((VariableRegisterInstruction)instruction).getRegisterCount();
|
||||
if (parameterCount == 3) {
|
||||
return indexOfIIMethod;
|
||||
} else if (parameterCount == 1) {
|
||||
return isEmptyMethod;
|
||||
} else {
|
||||
throw new RuntimeException("Could not determine the correct inline method to use");
|
||||
}
|
||||
}
|
||||
|
||||
return inlineMethods[inlineIndex];
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class OdexedFieldInstructionMapper {
|
||||
private static Opcode[][][][] opcodeMap = new Opcode[][][][] {
|
||||
//get opcodes
|
||||
new Opcode[][][] {
|
||||
//iget quick
|
||||
new Opcode[][] {
|
||||
//odexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IGET_QUICK,
|
||||
/*B*/ Opcode.IGET_QUICK,
|
||||
/*S*/ Opcode.IGET_QUICK,
|
||||
/*C*/ Opcode.IGET_QUICK,
|
||||
/*I,F*/ Opcode.IGET_QUICK,
|
||||
/*J,D*/ Opcode.IGET_WIDE_QUICK,
|
||||
/*L,[*/ Opcode.IGET_OBJECT_QUICK
|
||||
},
|
||||
//deodexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IGET_BOOLEAN,
|
||||
/*B*/ Opcode.IGET_BYTE,
|
||||
/*S*/ Opcode.IGET_SHORT,
|
||||
/*C*/ Opcode.IGET_CHAR,
|
||||
/*I,F*/ Opcode.IGET,
|
||||
/*J,D*/ Opcode.IGET_WIDE,
|
||||
/*L,[*/ Opcode.IGET_OBJECT
|
||||
}
|
||||
},
|
||||
//iget volatile
|
||||
new Opcode[][] {
|
||||
//odexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IGET_VOLATILE,
|
||||
/*B*/ Opcode.IGET_VOLATILE,
|
||||
/*S*/ Opcode.IGET_VOLATILE,
|
||||
/*C*/ Opcode.IGET_VOLATILE,
|
||||
/*I,F*/ Opcode.IGET_VOLATILE,
|
||||
/*J,D*/ Opcode.IGET_WIDE_VOLATILE,
|
||||
/*L,[*/ Opcode.IGET_OBJECT_VOLATILE
|
||||
},
|
||||
//deodexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IGET_BOOLEAN,
|
||||
/*B*/ Opcode.IGET_BYTE,
|
||||
/*S*/ Opcode.IGET_SHORT,
|
||||
/*C*/ Opcode.IGET_CHAR,
|
||||
/*I,F*/ Opcode.IGET,
|
||||
/*J,D*/ Opcode.IGET_WIDE,
|
||||
/*L,[*/ Opcode.IGET_OBJECT
|
||||
}
|
||||
},
|
||||
//sget volatile
|
||||
new Opcode[][] {
|
||||
//odexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.SGET_VOLATILE,
|
||||
/*B*/ Opcode.SGET_VOLATILE,
|
||||
/*S*/ Opcode.SGET_VOLATILE,
|
||||
/*C*/ Opcode.SGET_VOLATILE,
|
||||
/*I,F*/ Opcode.SGET_VOLATILE,
|
||||
/*J,D*/ Opcode.SGET_WIDE_VOLATILE,
|
||||
/*L,[*/ Opcode.SGET_OBJECT_VOLATILE
|
||||
},
|
||||
//deodexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.SGET_BOOLEAN,
|
||||
/*B*/ Opcode.SGET_BYTE,
|
||||
/*S*/ Opcode.SGET_SHORT,
|
||||
/*C*/ Opcode.SGET_CHAR,
|
||||
/*I,F*/ Opcode.SGET,
|
||||
/*J,D*/ Opcode.SGET_WIDE,
|
||||
/*L,[*/ Opcode.SGET_OBJECT
|
||||
}
|
||||
}
|
||||
},
|
||||
//put opcodes
|
||||
new Opcode[][][] {
|
||||
//iput quick
|
||||
new Opcode[][] {
|
||||
//odexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IPUT_QUICK,
|
||||
/*B*/ Opcode.IPUT_QUICK,
|
||||
/*S*/ Opcode.IPUT_QUICK,
|
||||
/*C*/ Opcode.IPUT_QUICK,
|
||||
/*I,F*/ Opcode.IPUT_QUICK,
|
||||
/*J,D*/ Opcode.IPUT_WIDE_QUICK,
|
||||
/*L,[*/ Opcode.IPUT_OBJECT_QUICK
|
||||
},
|
||||
//deodexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IPUT_BOOLEAN,
|
||||
/*B*/ Opcode.IPUT_BYTE,
|
||||
/*S*/ Opcode.IPUT_SHORT,
|
||||
/*C*/ Opcode.IPUT_CHAR,
|
||||
/*I,F*/ Opcode.IPUT,
|
||||
/*J,D*/ Opcode.IPUT_WIDE,
|
||||
/*L,[*/ Opcode.IPUT_OBJECT
|
||||
}
|
||||
},
|
||||
//iput volatile
|
||||
new Opcode[][] {
|
||||
//odexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IPUT_VOLATILE,
|
||||
/*B*/ Opcode.IPUT_VOLATILE,
|
||||
/*S*/ Opcode.IPUT_VOLATILE,
|
||||
/*C*/ Opcode.IPUT_VOLATILE,
|
||||
/*I,F*/ Opcode.IPUT_VOLATILE,
|
||||
/*J,D*/ Opcode.IPUT_WIDE_VOLATILE,
|
||||
/*L,[*/ Opcode.IPUT_OBJECT_VOLATILE
|
||||
},
|
||||
//deodexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.IPUT_BOOLEAN,
|
||||
/*B*/ Opcode.IPUT_BYTE,
|
||||
/*S*/ Opcode.IPUT_SHORT,
|
||||
/*C*/ Opcode.IPUT_CHAR,
|
||||
/*I,F*/ Opcode.IPUT,
|
||||
/*J,D*/ Opcode.IPUT_WIDE,
|
||||
/*L,[*/ Opcode.IPUT_OBJECT
|
||||
}
|
||||
},
|
||||
//sput volatile
|
||||
new Opcode[][] {
|
||||
//odexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.SPUT_VOLATILE,
|
||||
/*B*/ Opcode.SPUT_VOLATILE,
|
||||
/*S*/ Opcode.SPUT_VOLATILE,
|
||||
/*C*/ Opcode.SPUT_VOLATILE,
|
||||
/*I,F*/ Opcode.SPUT_VOLATILE,
|
||||
/*J,D*/ Opcode.SPUT_WIDE_VOLATILE,
|
||||
/*L,[*/ Opcode.SPUT_OBJECT_VOLATILE
|
||||
},
|
||||
//deodexed
|
||||
new Opcode[] {
|
||||
/*Z*/ Opcode.SPUT_BOOLEAN,
|
||||
/*B*/ Opcode.SPUT_BYTE,
|
||||
/*S*/ Opcode.SPUT_SHORT,
|
||||
/*C*/ Opcode.SPUT_CHAR,
|
||||
/*I,F*/ Opcode.SPUT,
|
||||
/*J,D*/ Opcode.SPUT_WIDE,
|
||||
/*L,[*/ Opcode.SPUT_OBJECT
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static int getTypeIndex(char type) {
|
||||
switch (type) {
|
||||
case 'Z':
|
||||
return 0;
|
||||
case 'B':
|
||||
return 1;
|
||||
case 'S':
|
||||
return 2;
|
||||
case 'C':
|
||||
return 3;
|
||||
case 'I':
|
||||
case 'F':
|
||||
return 4;
|
||||
case 'J':
|
||||
case 'D':
|
||||
return 5;
|
||||
case 'L':
|
||||
case '[':
|
||||
return 6;
|
||||
default:
|
||||
}
|
||||
throw new RuntimeException(String.format("Unknown type %s: ", type));
|
||||
}
|
||||
|
||||
private static int getOpcodeSubtype(@Nonnull Opcode opcode) {
|
||||
if (opcode.isOdexedInstanceQuick()) {
|
||||
return 0;
|
||||
} else if (opcode.isOdexedInstanceVolatile()) {
|
||||
return 1;
|
||||
} else if (opcode.isOdexedStaticVolatile()) {
|
||||
return 2;
|
||||
}
|
||||
throw new RuntimeException(String.format("Not an odexed field access opcode: %s", opcode.name));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
static Opcode getAndCheckDeodexedOpcodeForOdexedOpcode(@Nonnull String fieldType, @Nonnull Opcode odexedOpcode) {
|
||||
int opcodeType = odexedOpcode.setsRegister()?0:1;
|
||||
int opcodeSubType = getOpcodeSubtype(odexedOpcode);
|
||||
int typeIndex = getTypeIndex(fieldType.charAt(0));
|
||||
|
||||
Opcode correctOdexedOpcode, deodexedOpcode;
|
||||
|
||||
correctOdexedOpcode = opcodeMap[opcodeType][opcodeSubType][0][typeIndex];
|
||||
deodexedOpcode = opcodeMap[opcodeType][opcodeSubType][1][typeIndex];
|
||||
|
||||
if (correctOdexedOpcode != odexedOpcode) {
|
||||
throw new AnalysisException(String.format("Incorrect field type \"%s\" for %s", fieldType,
|
||||
odexedOpcode.name));
|
||||
}
|
||||
|
||||
return deodexedOpcode;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PrimitiveProto implements TypeProto {
|
||||
protected final ClassPath classPath;
|
||||
protected final String type;
|
||||
|
||||
public PrimitiveProto(@Nonnull ClassPath classPath, @Nonnull String type) {
|
||||
this.classPath = classPath;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override public String toString() { return type; }
|
||||
@Nonnull @Override public ClassPath getClassPath() { return classPath; }
|
||||
@Nonnull @Override public String getType() { return type; }
|
||||
@Override public boolean isInterface() { return false; }
|
||||
@Override public boolean implementsInterface(@Nonnull String iface) { return false; }
|
||||
@Nullable @Override public String getSuperclass() { return null; }
|
||||
@Nonnull @Override public TypeProto getCommonSuperclass(@Nonnull TypeProto other) {
|
||||
throw new ExceptionWithContext("Cannot call getCommonSuperclass on PrimitiveProto");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FieldReference getFieldByOffset(int fieldOffset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MethodReference getMethodByVtableIndex(int vtableIndex) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
|
||||
public class RegisterType {
|
||||
public final byte category;
|
||||
@Nullable public final TypeProto type;
|
||||
|
||||
private RegisterType(byte category, @Nullable TypeProto type) {
|
||||
assert ((category == REFERENCE || category == UNINIT_REF || category == UNINIT_THIS) && type != null) ||
|
||||
((category != REFERENCE && category != UNINIT_REF && category != UNINIT_THIS) && type == null);
|
||||
|
||||
this.category = category;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + CATEGORY_NAMES[category] + (type==null?"":("," + type)) + ")";
|
||||
}
|
||||
|
||||
public void writeTo(Writer writer) throws IOException {
|
||||
writer.write('(');
|
||||
writer.write(CATEGORY_NAMES[category]);
|
||||
if (type != null) {
|
||||
writer.write(',');
|
||||
writer.write(type.getType());
|
||||
}
|
||||
writer.write(')');
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
RegisterType that = (RegisterType) o;
|
||||
|
||||
if (category != that.category) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// These require strict reference equality. Every instance represents a unique
|
||||
// reference that can't be merged with a different one, even if they have the same type.
|
||||
if (category == UNINIT_REF || category == UNINIT_THIS) {
|
||||
return false;
|
||||
}
|
||||
return (type != null ? type.equals(that.type) : that.type == null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = category;
|
||||
result = 31 * result + (type != null ? type.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
// The Unknown category denotes a register type that hasn't been determined yet
|
||||
public static final byte UNKNOWN = 0;
|
||||
// The Uninit category is for registers that haven't been set yet. e.g. the non-parameter registers in a method
|
||||
// start out as unint
|
||||
public static final byte UNINIT = 1;
|
||||
public static final byte NULL = 2;
|
||||
public static final byte ONE = 3;
|
||||
public static final byte BOOLEAN = 4;
|
||||
public static final byte BYTE = 5;
|
||||
public static final byte POS_BYTE = 6;
|
||||
public static final byte SHORT = 7;
|
||||
public static final byte POS_SHORT = 8;
|
||||
public static final byte CHAR = 9;
|
||||
public static final byte INTEGER = 10;
|
||||
public static final byte FLOAT = 11;
|
||||
public static final byte LONG_LO = 12;
|
||||
public static final byte LONG_HI = 13;
|
||||
public static final byte DOUBLE_LO = 14;
|
||||
public static final byte DOUBLE_HI = 15;
|
||||
// The UninitRef category is used after a new-instance operation, and before the corresponding <init> is called
|
||||
public static final byte UNINIT_REF = 16;
|
||||
// The UninitThis category is used the "this" register inside an <init> method, before the superclass' <init>
|
||||
// method is called
|
||||
public static final byte UNINIT_THIS = 17;
|
||||
public static final byte REFERENCE = 18;
|
||||
// This is used when there are multiple incoming execution paths that have incompatible register types. For
|
||||
// example if the register's type is an Integer on one incoming code path, but is a Reference type on another
|
||||
// incomming code path. There is no register type that can hold either an Integer or a Reference.
|
||||
public static final byte CONFLICTED = 19;
|
||||
|
||||
public static final String[] CATEGORY_NAMES = new String[] {
|
||||
"Unknown",
|
||||
"Uninit",
|
||||
"Null",
|
||||
"One",
|
||||
"Boolean",
|
||||
"Byte",
|
||||
"PosByte",
|
||||
"Short",
|
||||
"PosShort",
|
||||
"Char",
|
||||
"Integer",
|
||||
"Float",
|
||||
"LongLo",
|
||||
"LongHi",
|
||||
"DoubleLo",
|
||||
"DoubleHi",
|
||||
"UninitRef",
|
||||
"UninitThis",
|
||||
"Reference",
|
||||
"Conflicted"
|
||||
};
|
||||
|
||||
//this table is used when merging register types. For example, if a particular register can be either a BYTE
|
||||
//or a Char, then the "merged" type of that register would be Integer, because it is the "smallest" type can
|
||||
//could hold either type of value.
|
||||
protected static byte[][] mergeTable =
|
||||
{
|
||||
/* UNKNOWN UNINIT NULL ONE, BOOLEAN BYTE POS_BYTE SHORT POS_SHORT CHAR INTEGER, FLOAT, LONG_LO LONG_HI DOUBLE_LO DOUBLE_HI UNINIT_REF UNINIT_THIS REFERENCE CONFLICTED*/
|
||||
/*UNKNOWN*/ {UNKNOWN, UNINIT, NULL, ONE, BOOLEAN, BYTE, POS_BYTE, SHORT, POS_SHORT, CHAR, INTEGER, FLOAT, LONG_LO, LONG_HI, DOUBLE_LO, DOUBLE_HI, UNINIT_REF, UNINIT_THIS,REFERENCE, CONFLICTED},
|
||||
/*UNINIT*/ {UNINIT, UNINIT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*NULL*/ {NULL, CONFLICTED, NULL, BOOLEAN, BOOLEAN, BYTE, POS_BYTE, SHORT, POS_SHORT, CHAR, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, REFERENCE, CONFLICTED},
|
||||
/*ONE*/ {ONE, CONFLICTED, BOOLEAN, ONE, BOOLEAN, BYTE, POS_BYTE, SHORT, POS_SHORT, CHAR, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*BOOLEAN*/ {BOOLEAN, CONFLICTED, BOOLEAN, BOOLEAN, BOOLEAN, BYTE, POS_BYTE, SHORT, POS_SHORT, CHAR, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*BYTE*/ {BYTE, CONFLICTED, BYTE, BYTE, BYTE, BYTE, BYTE, SHORT, SHORT, INTEGER, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*POS_BYTE*/ {POS_BYTE, CONFLICTED, POS_BYTE, POS_BYTE, POS_BYTE, BYTE, POS_BYTE, SHORT, POS_SHORT, CHAR, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*SHORT*/ {SHORT, CONFLICTED, SHORT, SHORT, SHORT, SHORT, SHORT, SHORT, SHORT, INTEGER, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*POS_SHORT*/ {POS_SHORT, CONFLICTED, POS_SHORT, POS_SHORT, POS_SHORT, SHORT, POS_SHORT, SHORT, POS_SHORT, CHAR, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*CHAR*/ {CHAR, CONFLICTED, CHAR, CHAR, CHAR, INTEGER, CHAR, INTEGER, CHAR, CHAR, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*INTEGER*/ {INTEGER, CONFLICTED, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, INTEGER, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*FLOAT*/ {FLOAT, CONFLICTED, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, INTEGER, FLOAT, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*LONG_LO*/ {LONG_LO, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_LO, CONFLICTED, LONG_LO, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*LONG_HI*/ {LONG_HI, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_HI, CONFLICTED, LONG_HI, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*DOUBLE_LO*/ {DOUBLE_LO, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_LO, CONFLICTED, DOUBLE_LO, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*DOUBLE_HI*/ {DOUBLE_HI, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, LONG_HI, CONFLICTED, DOUBLE_HI, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*UNINIT_REF*/ {UNINIT_REF, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED},
|
||||
/*UNINIT_THIS*/{UNINIT_THIS, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, UNINIT_THIS,CONFLICTED, CONFLICTED},
|
||||
/*REFERENCE*/ {REFERENCE, CONFLICTED, REFERENCE, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, REFERENCE, CONFLICTED},
|
||||
/*CONFLICTED*/ {CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED, CONFLICTED}
|
||||
};
|
||||
|
||||
|
||||
public static final RegisterType UNKNOWN_TYPE = new RegisterType(UNKNOWN, null);
|
||||
public static final RegisterType UNINIT_TYPE = new RegisterType(UNINIT, null);
|
||||
public static final RegisterType NULL_TYPE = new RegisterType(NULL, null);
|
||||
public static final RegisterType ONE_TYPE = new RegisterType(ONE, null);
|
||||
public static final RegisterType BOOLEAN_TYPE = new RegisterType(BOOLEAN, null);
|
||||
public static final RegisterType BYTE_TYPE = new RegisterType(BYTE, null);
|
||||
public static final RegisterType POS_BYTE_TYPE = new RegisterType(POS_BYTE, null);
|
||||
public static final RegisterType SHORT_TYPE = new RegisterType(SHORT, null);
|
||||
public static final RegisterType POS_SHORT_TYPE = new RegisterType(POS_SHORT, null);
|
||||
public static final RegisterType CHAR_TYPE = new RegisterType(CHAR, null);
|
||||
public static final RegisterType INTEGER_TYPE = new RegisterType(INTEGER, null);
|
||||
public static final RegisterType FLOAT_TYPE = new RegisterType(FLOAT, null);
|
||||
public static final RegisterType LONG_LO_TYPE = new RegisterType(LONG_LO, null);
|
||||
public static final RegisterType LONG_HI_TYPE = new RegisterType(LONG_HI, null);
|
||||
public static final RegisterType DOUBLE_LO_TYPE = new RegisterType(DOUBLE_LO, null);
|
||||
public static final RegisterType DOUBLE_HI_TYPE = new RegisterType(DOUBLE_HI, null);
|
||||
public static final RegisterType CONFLICTED_TYPE = new RegisterType(CONFLICTED, null);
|
||||
|
||||
@Nonnull
|
||||
public static RegisterType getWideRegisterType(@Nonnull CharSequence type, boolean firstRegister) {
|
||||
switch (type.charAt(0)) {
|
||||
case 'J':
|
||||
if (firstRegister) {
|
||||
return getRegisterType(LONG_LO, null);
|
||||
} else {
|
||||
return getRegisterType(LONG_HI, null);
|
||||
}
|
||||
case 'D':
|
||||
if (firstRegister) {
|
||||
return getRegisterType(DOUBLE_LO, null);
|
||||
} else {
|
||||
return getRegisterType(DOUBLE_HI, null);
|
||||
}
|
||||
default:
|
||||
throw new ExceptionWithContext("Cannot use this method for narrow register type: %s", type);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static RegisterType getRegisterType(@Nonnull ClassPath classPath, @Nonnull CharSequence type) {
|
||||
switch (type.charAt(0)) {
|
||||
case 'Z':
|
||||
return BOOLEAN_TYPE;
|
||||
case 'B':
|
||||
return BYTE_TYPE;
|
||||
case 'S':
|
||||
return SHORT_TYPE;
|
||||
case 'C':
|
||||
return CHAR_TYPE;
|
||||
case 'I':
|
||||
return INTEGER_TYPE;
|
||||
case 'F':
|
||||
return FLOAT_TYPE;
|
||||
case 'J':
|
||||
return LONG_LO_TYPE;
|
||||
case 'D':
|
||||
return DOUBLE_LO_TYPE;
|
||||
case 'L':
|
||||
case '[':
|
||||
return getRegisterType(REFERENCE, classPath.getClass(type));
|
||||
default:
|
||||
throw new ExceptionWithContext("Invalid type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static RegisterType getRegisterTypeForLiteral(int literalValue) {
|
||||
if (literalValue < -32768) {
|
||||
return INTEGER_TYPE;
|
||||
}
|
||||
if (literalValue < -128) {
|
||||
return SHORT_TYPE;
|
||||
}
|
||||
if (literalValue < 0) {
|
||||
return BYTE_TYPE;
|
||||
}
|
||||
if (literalValue == 0) {
|
||||
return NULL_TYPE;
|
||||
}
|
||||
if (literalValue == 1) {
|
||||
return ONE_TYPE;
|
||||
}
|
||||
if (literalValue < 128) {
|
||||
return POS_BYTE_TYPE;
|
||||
}
|
||||
if (literalValue < 32768) {
|
||||
return POS_SHORT_TYPE;
|
||||
}
|
||||
if (literalValue < 65536) {
|
||||
return CHAR_TYPE;
|
||||
}
|
||||
return INTEGER_TYPE;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public RegisterType merge(@Nonnull RegisterType other) {
|
||||
if (other.equals(this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
byte mergedCategory = mergeTable[this.category][other.category];
|
||||
|
||||
TypeProto mergedType = null;
|
||||
if (mergedCategory == REFERENCE) {
|
||||
TypeProto type = this.type;
|
||||
if (type != null) {
|
||||
if (other.type != null) {
|
||||
mergedType = type.getCommonSuperclass(other.type);
|
||||
} else {
|
||||
mergedType = type;
|
||||
}
|
||||
} else {
|
||||
mergedType = other.type;
|
||||
}
|
||||
} else if (mergedCategory == UNINIT_REF || mergedCategory == UNINIT_THIS) {
|
||||
if (this.category == UNKNOWN) {
|
||||
return other;
|
||||
}
|
||||
assert other.category == UNKNOWN;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (mergedType != null) {
|
||||
if (mergedType.equals(this.type)) {
|
||||
return this;
|
||||
}
|
||||
if (mergedType.equals(other.type)) {
|
||||
return other;
|
||||
}
|
||||
}
|
||||
return RegisterType.getRegisterType(mergedCategory, mergedType);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static RegisterType getRegisterType(byte category, @Nullable TypeProto typeProto) {
|
||||
switch (category) {
|
||||
case UNKNOWN:
|
||||
return UNKNOWN_TYPE;
|
||||
case UNINIT:
|
||||
return UNINIT_TYPE;
|
||||
case NULL:
|
||||
return NULL_TYPE;
|
||||
case ONE:
|
||||
return ONE_TYPE;
|
||||
case BOOLEAN:
|
||||
return BOOLEAN_TYPE;
|
||||
case BYTE:
|
||||
return BYTE_TYPE;
|
||||
case POS_BYTE:
|
||||
return POS_BYTE_TYPE;
|
||||
case SHORT:
|
||||
return SHORT_TYPE;
|
||||
case POS_SHORT:
|
||||
return POS_SHORT_TYPE;
|
||||
case CHAR:
|
||||
return CHAR_TYPE;
|
||||
case INTEGER:
|
||||
return INTEGER_TYPE;
|
||||
case FLOAT:
|
||||
return FLOAT_TYPE;
|
||||
case LONG_LO:
|
||||
return LONG_LO_TYPE;
|
||||
case LONG_HI:
|
||||
return LONG_HI_TYPE;
|
||||
case DOUBLE_LO:
|
||||
return DOUBLE_LO_TYPE;
|
||||
case DOUBLE_HI:
|
||||
return DOUBLE_HI_TYPE;
|
||||
case CONFLICTED:
|
||||
return CONFLICTED_TYPE;
|
||||
}
|
||||
|
||||
return new RegisterType(category, typeProto);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface TypeProto {
|
||||
@Nonnull ClassPath getClassPath();
|
||||
@Nonnull String getType();
|
||||
boolean isInterface();
|
||||
boolean implementsInterface(@Nonnull String iface);
|
||||
@Nullable String getSuperclass();
|
||||
@Nonnull TypeProto getCommonSuperclass(@Nonnull TypeProto other);
|
||||
@Nullable FieldReference getFieldByOffset(int fieldOffset);
|
||||
@Nullable MethodReference getMethodByVtableIndex(int vtableIndex);
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class UnknownClassProto implements TypeProto {
|
||||
@Nonnull protected final ClassPath classPath;
|
||||
|
||||
public UnknownClassProto(@Nonnull ClassPath classPath) {
|
||||
this.classPath = classPath;
|
||||
}
|
||||
|
||||
@Override public String toString() { return "Ujava/lang/Object;"; }
|
||||
@Nonnull @Override public ClassPath getClassPath() { return classPath; }
|
||||
@Nullable @Override public String getSuperclass() { return null; }
|
||||
@Override public boolean isInterface() { return false; }
|
||||
@Override public boolean implementsInterface(@Nonnull String iface) { return false; }
|
||||
|
||||
@Nonnull @Override public TypeProto getCommonSuperclass(@Nonnull TypeProto other) {
|
||||
if (other.getType().equals("Ljava/lang/Object;")) {
|
||||
return other;
|
||||
}
|
||||
if (other instanceof ArrayProto) {
|
||||
// if it's an array class, it's safe to assume this unknown class isn't related, and so
|
||||
// java.lang.Object is the only possible superclass
|
||||
return classPath.getClass("Ljava/lang/Object;");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getType() {
|
||||
// use the otherwise used U prefix for an unknown/unresolvable class
|
||||
return "Ujava/lang/Object;";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FieldReference getFieldByOffset(int fieldOffset) {
|
||||
return classPath.getClass("Ljava/lang/Object;").getFieldByOffset(fieldOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public MethodReference getMethodByVtableIndex(int vtableIndex) {
|
||||
return classPath.getClass("Ljava/lang/Object;").getMethodByVtableIndex(vtableIndex);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
public class UnresolvedClassException extends ExceptionWithContext {
|
||||
public UnresolvedClassException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public UnresolvedClassException(Throwable cause, String message, Object... formatArgs) {
|
||||
super(cause, message, formatArgs);
|
||||
}
|
||||
|
||||
public UnresolvedClassException(String message, Object... formatArgs) {
|
||||
super(message, formatArgs);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.iface.instruction.Instruction;
|
||||
|
||||
/**
|
||||
* This represents a "fixed" odexed instruction, where the object register is always null and so the correct type
|
||||
* can't be determined. Typically, these are replaced by an equivalent instruction that would have the same
|
||||
* effect (namely, an NPE)
|
||||
*/
|
||||
public class UnresolvedOdexInstruction implements Instruction {
|
||||
public final Instruction originalInstruction;
|
||||
//the register number that holds the (null) reference type that the instruction operates on
|
||||
public final int objectRegisterNum;
|
||||
|
||||
public UnresolvedOdexInstruction(Instruction originalInstruction, int objectRegisterNumber) {
|
||||
this.originalInstruction = originalInstruction;
|
||||
this.objectRegisterNum = objectRegisterNumber;
|
||||
}
|
||||
|
||||
@Override public Opcode getOpcode() {
|
||||
return originalInstruction.getOpcode();
|
||||
}
|
||||
|
||||
@Override public int getCodeUnits() {
|
||||
return originalInstruction.getCodeUnits();
|
||||
}
|
||||
}
|
@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis.reflection;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterators;
|
||||
import org.jf.dexlib2.analysis.reflection.util.ReflectionUtils;
|
||||
import org.jf.dexlib2.base.reference.BaseTypeReference;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.Field;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Wraps a ClassDef around a class loaded in the current VM
|
||||
*
|
||||
* Only supports the basic information exposed by ClassProto
|
||||
*/
|
||||
public class ReflectionClassDef extends BaseTypeReference implements ClassDef {
|
||||
private final Class cls;
|
||||
|
||||
public ReflectionClassDef(Class cls) {
|
||||
this.cls = cls;
|
||||
}
|
||||
|
||||
@Override public int getAccessFlags() {
|
||||
// the java modifiers appear to be the same as the dex access flags
|
||||
return cls.getModifiers();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getSuperclass() {
|
||||
if (Modifier.isInterface(cls.getModifiers())) {
|
||||
return "Ljava/lang/Object;";
|
||||
}
|
||||
Class superClass = cls.getSuperclass();
|
||||
if (superClass == null) {
|
||||
return null;
|
||||
}
|
||||
return ReflectionUtils.javaToDexName(superClass.getName());
|
||||
}
|
||||
|
||||
@Nonnull @Override public Set<String> getInterfaces() {
|
||||
return new AbstractSet<String>() {
|
||||
@Nonnull @Override public Iterator<String> iterator() {
|
||||
return Iterators.transform(Iterators.forArray(cls.getInterfaces()), new Function<Class, String>() {
|
||||
@Nullable @Override public String apply(@Nullable Class input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
return ReflectionUtils.javaToDexName(input.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return cls.getInterfaces().length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable @Override public String getSourceFile() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Nonnull @Override public Iterable<? extends Field> getStaticFields() {
|
||||
return new Iterable<Field>() {
|
||||
@Nonnull @Override public Iterator<Field> iterator() {
|
||||
Iterator<java.lang.reflect.Field> staticFields = Iterators.filter(
|
||||
Iterators.forArray(cls.getDeclaredFields()),
|
||||
new Predicate<java.lang.reflect.Field>() {
|
||||
@Override public boolean apply(@Nullable java.lang.reflect.Field input) {
|
||||
return input!=null && Modifier.isStatic(input.getModifiers());
|
||||
}
|
||||
});
|
||||
|
||||
return Iterators.transform(staticFields,
|
||||
new Function<java.lang.reflect.Field, Field>() {
|
||||
@Nullable @Override public Field apply(@Nullable java.lang.reflect.Field input) {
|
||||
return new ReflectionField(input);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull @Override public Iterable<? extends Field> getInstanceFields() {
|
||||
return new Iterable<Field>() {
|
||||
@Nonnull @Override public Iterator<Field> iterator() {
|
||||
Iterator<java.lang.reflect.Field> staticFields = Iterators.filter(
|
||||
Iterators.forArray(cls.getDeclaredFields()),
|
||||
new Predicate<java.lang.reflect.Field>() {
|
||||
@Override public boolean apply(@Nullable java.lang.reflect.Field input) {
|
||||
return input!=null && !Modifier.isStatic(input.getModifiers());
|
||||
}
|
||||
});
|
||||
|
||||
return Iterators.transform(staticFields,
|
||||
new Function<java.lang.reflect.Field, Field>() {
|
||||
@Nullable @Override public Field apply(@Nullable java.lang.reflect.Field input) {
|
||||
return new ReflectionField(input);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull @Override public Set<? extends Field> getFields() {
|
||||
return new AbstractSet<Field>() {
|
||||
@Nonnull @Override public Iterator<Field> iterator() {
|
||||
return Iterators.transform(Iterators.forArray(cls.getDeclaredFields()),
|
||||
new Function<java.lang.reflect.Field, Field>() {
|
||||
@Nullable @Override public Field apply(@Nullable java.lang.reflect.Field input) {
|
||||
return new ReflectionField(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return cls.getDeclaredFields().length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static final int DIRECT_MODIFIERS = Modifier.PRIVATE | Modifier.STATIC;
|
||||
@Nonnull @Override public Iterable<? extends Method> getDirectMethods() {
|
||||
return new Iterable<Method>() {
|
||||
@Nonnull @Override public Iterator<Method> iterator() {
|
||||
Iterator<Method> constructorIterator =
|
||||
Iterators.transform(Iterators.forArray(cls.getDeclaredConstructors()),
|
||||
new Function<Constructor, Method>() {
|
||||
@Nullable @Override public Method apply(@Nullable Constructor input) {
|
||||
return new ReflectionConstructor(input);
|
||||
}
|
||||
});
|
||||
|
||||
Iterator<java.lang.reflect.Method> directMethods = Iterators.filter(
|
||||
Iterators.forArray(cls.getDeclaredMethods()),
|
||||
new Predicate<java.lang.reflect.Method>() {
|
||||
@Override public boolean apply(@Nullable java.lang.reflect.Method input) {
|
||||
return input != null && (input.getModifiers() & DIRECT_MODIFIERS) != 0;
|
||||
}
|
||||
});
|
||||
|
||||
Iterator<Method> methodIterator = Iterators.transform(directMethods,
|
||||
new Function<java.lang.reflect.Method, Method>() {
|
||||
@Nullable @Override public Method apply(@Nullable java.lang.reflect.Method input) {
|
||||
return new ReflectionMethod(input);
|
||||
}
|
||||
});
|
||||
return Iterators.concat(constructorIterator, methodIterator);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull @Override public Iterable<? extends Method> getVirtualMethods() {
|
||||
return new Iterable<Method>() {
|
||||
@Nonnull @Override public Iterator<Method> iterator() {
|
||||
Iterator<java.lang.reflect.Method> directMethods = Iterators.filter(
|
||||
Iterators.forArray(cls.getDeclaredMethods()),
|
||||
new Predicate<java.lang.reflect.Method>() {
|
||||
@Override public boolean apply(@Nullable java.lang.reflect.Method input) {
|
||||
return input != null && (input.getModifiers() & DIRECT_MODIFIERS) == 0;
|
||||
}
|
||||
});
|
||||
|
||||
return Iterators.transform(directMethods,
|
||||
new Function<java.lang.reflect.Method, Method>() {
|
||||
@Nullable @Override public Method apply(@Nullable java.lang.reflect.Method input) {
|
||||
return new ReflectionMethod(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull @Override public Set<? extends Method> getMethods() {
|
||||
return new AbstractSet<Method>() {
|
||||
@Nonnull @Override public Iterator<Method> iterator() {
|
||||
Iterator<Method> constructorIterator =
|
||||
Iterators.transform(Iterators.forArray(cls.getDeclaredConstructors()),
|
||||
new Function<Constructor, Method>() {
|
||||
@Nullable @Override public Method apply(@Nullable Constructor input) {
|
||||
return new ReflectionConstructor(input);
|
||||
}
|
||||
});
|
||||
|
||||
Iterator<Method> methodIterator =
|
||||
Iterators.transform(Iterators.forArray(cls.getDeclaredMethods()),
|
||||
new Function<java.lang.reflect.Method, Method>() {
|
||||
@Nullable @Override public Method apply(@Nullable java.lang.reflect.Method input) {
|
||||
return new ReflectionMethod(input);
|
||||
}
|
||||
});
|
||||
return Iterators.concat(constructorIterator, methodIterator);
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return cls.getDeclaredMethods().length + cls.getDeclaredConstructors().length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getType() {
|
||||
return ReflectionUtils.javaToDexName(cls.getName());
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis.reflection;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jf.dexlib2.analysis.reflection.util.ReflectionUtils;
|
||||
import org.jf.dexlib2.base.BaseMethodParameter;
|
||||
import org.jf.dexlib2.base.reference.BaseMethodReference;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.MethodImplementation;
|
||||
import org.jf.dexlib2.iface.MethodParameter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.AbstractList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ReflectionConstructor extends BaseMethodReference implements Method {
|
||||
private final Constructor constructor;
|
||||
|
||||
public ReflectionConstructor(Constructor constructor) {
|
||||
this.constructor = constructor;
|
||||
}
|
||||
|
||||
@Nonnull @Override public List<? extends MethodParameter> getParameters() {
|
||||
final Constructor method = this.constructor;
|
||||
return new AbstractList<MethodParameter>() {
|
||||
private final Class[] parameters = method.getParameterTypes();
|
||||
|
||||
@Override public MethodParameter get(final int index) {
|
||||
return new BaseMethodParameter() {
|
||||
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getType() {
|
||||
return ReflectionUtils.javaToDexName(parameters[index].getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return parameters.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public int getAccessFlags() {
|
||||
return constructor.getModifiers();
|
||||
}
|
||||
|
||||
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Nullable @Override public MethodImplementation getImplementation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getDefiningClass() {
|
||||
return ReflectionUtils.javaToDexName(constructor.getDeclaringClass().getName());
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getName() {
|
||||
return constructor.getName();
|
||||
}
|
||||
|
||||
@Nonnull @Override public List<String> getParameterTypes() {
|
||||
return new AbstractList<String>() {
|
||||
private final List<? extends MethodParameter> parameters = getParameters();
|
||||
|
||||
@Override public String get(int index) {
|
||||
return parameters.get(index).getType();
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return parameters.size();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getReturnType() {
|
||||
return "V";
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis.reflection;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jf.dexlib2.analysis.reflection.util.ReflectionUtils;
|
||||
import org.jf.dexlib2.base.reference.BaseFieldReference;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.Field;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Set;
|
||||
|
||||
public class ReflectionField extends BaseFieldReference implements Field {
|
||||
private final java.lang.reflect.Field field;
|
||||
|
||||
public ReflectionField(java.lang.reflect.Field field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override public int getAccessFlags() {
|
||||
return field.getModifiers();
|
||||
}
|
||||
|
||||
@Nullable @Override public EncodedValue getInitialValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getDefiningClass() {
|
||||
return ReflectionUtils.javaToDexName(field.getDeclaringClass().getName());
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getName() {
|
||||
return field.getName();
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getType() {
|
||||
return ReflectionUtils.javaToDexName(field.getType().getName());
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis.reflection;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jf.dexlib2.analysis.reflection.util.ReflectionUtils;
|
||||
import org.jf.dexlib2.base.BaseMethodParameter;
|
||||
import org.jf.dexlib2.base.reference.BaseMethodReference;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.MethodImplementation;
|
||||
import org.jf.dexlib2.iface.MethodParameter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.AbstractList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ReflectionMethod extends BaseMethodReference implements Method {
|
||||
private final java.lang.reflect.Method method;
|
||||
|
||||
public ReflectionMethod(java.lang.reflect.Method method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Nonnull @Override public List<? extends MethodParameter> getParameters() {
|
||||
final java.lang.reflect.Method method = this.method;
|
||||
return new AbstractList<MethodParameter>() {
|
||||
private final Class[] parameters = method.getParameterTypes();
|
||||
|
||||
@Override public MethodParameter get(final int index) {
|
||||
return new BaseMethodParameter() {
|
||||
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getType() {
|
||||
return ReflectionUtils.javaToDexName(parameters[index].getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return parameters.length;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public int getAccessFlags() {
|
||||
return method.getModifiers();
|
||||
}
|
||||
|
||||
@Nonnull @Override public Set<? extends Annotation> getAnnotations() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Nullable @Override public MethodImplementation getImplementation() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getDefiningClass() {
|
||||
return ReflectionUtils.javaToDexName(method.getDeclaringClass().getName());
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getName() {
|
||||
return method.getName();
|
||||
}
|
||||
|
||||
@Nonnull @Override public List<String> getParameterTypes() {
|
||||
return new AbstractList<String>() {
|
||||
private final List<? extends MethodParameter> parameters = getParameters();
|
||||
|
||||
@Override public String get(int index) {
|
||||
return parameters.get(index).getType();
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return parameters.size();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getReturnType() {
|
||||
return ReflectionUtils.javaToDexName(method.getReturnType().getName());
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis.reflection.util;
|
||||
|
||||
public class ReflectionUtils {
|
||||
public static String javaToDexName(String javaName) {
|
||||
javaName = javaName.replace('.', '/');
|
||||
if (javaName.length() > 1 && javaName.charAt(javaName.length()-1) != ';') {
|
||||
javaName = 'L' + javaName + ';';
|
||||
}
|
||||
return javaName;
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.analysis.util;
|
||||
|
||||
import org.jf.dexlib2.analysis.TypeProto;
|
||||
import org.jf.dexlib2.analysis.UnresolvedClassException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class TypeProtoUtils {
|
||||
/**
|
||||
* Get the chain of superclasses of the given class. The first element will be the immediate superclass followed by
|
||||
* it's superclass, etc. up to java.lang.Object.
|
||||
*
|
||||
* Returns an empty iterable if called on java.lang.Object or a primitive.
|
||||
*
|
||||
* If any class in the superclass chain can't be resolved, the iterable will return Ujava/lang/Object; to represent
|
||||
* the unknown class.
|
||||
*
|
||||
* @return An iterable containing the superclasses of this class.
|
||||
*/
|
||||
@Nonnull
|
||||
public static Iterable<TypeProto> getSuperclassChain(@Nonnull final TypeProto typeProto) {
|
||||
return new Iterable<TypeProto>() {
|
||||
|
||||
@Override public Iterator<TypeProto> iterator() {
|
||||
return new Iterator<TypeProto>() {
|
||||
@Nullable private TypeProto type = getSuperclassAsTypeProto(typeProto);
|
||||
|
||||
@Override public boolean hasNext() {
|
||||
return type != null;
|
||||
}
|
||||
|
||||
@Override public TypeProto next() {
|
||||
TypeProto type = this.type;
|
||||
if (type == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
this.type = getSuperclassAsTypeProto(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static TypeProto getSuperclassAsTypeProto(@Nonnull TypeProto type) {
|
||||
try {
|
||||
String next = type.getSuperclass();
|
||||
if (next != null) {
|
||||
return type.getClassPath().getClass(next);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (UnresolvedClassException ex) {
|
||||
return type.getClassPath().getUnknownClass();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.util.CollectionUtils;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public abstract class BaseAnnotation implements Annotation {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = getVisibility();
|
||||
hashCode = hashCode*31 + getType().hashCode();
|
||||
return hashCode*31 + getElements().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Annotation) {
|
||||
Annotation other = (Annotation)o;
|
||||
return (getVisibility() == other.getVisibility()) &&
|
||||
getType().equals(other.getType()) &&
|
||||
getElements().equals(other.getElements());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Annotation o) {
|
||||
int res = Ints.compare(getVisibility(), o.getVisibility());
|
||||
if (res != 0) return res;
|
||||
res = getType().compareTo(o.getType());
|
||||
if (res != 0) return res;
|
||||
return CollectionUtils.compareAsSet(getElements(), o.getElements());
|
||||
}
|
||||
|
||||
public static final Comparator<? super Annotation> BY_TYPE = new Comparator<Annotation>() {
|
||||
@Override
|
||||
public int compare(Annotation annotation1, Annotation annotation2) {
|
||||
return annotation1.getType().compareTo(annotation2.getType());
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base;
|
||||
|
||||
import org.jf.dexlib2.iface.AnnotationElement;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Comparator;
|
||||
|
||||
public abstract class BaseAnnotationElement implements AnnotationElement {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = getName().hashCode();
|
||||
return hashCode*31 + getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o != null && o instanceof AnnotationElement) {
|
||||
AnnotationElement other = (AnnotationElement)o;
|
||||
return getName().equals(other.getName()) &&
|
||||
getValue().equals(other.getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(AnnotationElement o) {
|
||||
int res = getName().compareTo(o.getName());
|
||||
if (res != 0) return res;
|
||||
return getValue().compareTo(o.getValue());
|
||||
}
|
||||
|
||||
public static final Comparator<AnnotationElement> BY_NAME = new Comparator<AnnotationElement>() {
|
||||
@Override
|
||||
public int compare(@Nonnull AnnotationElement element1, @Nonnull AnnotationElement element2) {
|
||||
return element1.getName().compareTo(element2.getName());
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.iface.ExceptionHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Comparator;
|
||||
|
||||
public abstract class BaseExceptionHandler implements ExceptionHandler {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
String exceptionType = getExceptionType();
|
||||
int hashCode = exceptionType==null?0:exceptionType.hashCode();
|
||||
return hashCode*31 + getHandlerCodeAddress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof ExceptionHandler) {
|
||||
ExceptionHandler other = (ExceptionHandler)o;
|
||||
return Objects.equal(getExceptionType(), other.getExceptionType()) &&
|
||||
(getHandlerCodeAddress() == other.getHandlerCodeAddress());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull ExceptionHandler o) {
|
||||
int res;
|
||||
String exceptionType = getExceptionType();
|
||||
if (exceptionType == null) {
|
||||
if (o.getExceptionType() != null) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
String otherExceptionType = o.getExceptionType();
|
||||
if (otherExceptionType == null) {
|
||||
return -1;
|
||||
}
|
||||
res = exceptionType.compareTo(o.getExceptionType());
|
||||
if (res != 0) return res;
|
||||
}
|
||||
return Ints.compare(getHandlerCodeAddress(), o.getHandlerCodeAddress());
|
||||
}
|
||||
|
||||
public static final Comparator<ExceptionHandler> BY_EXCEPTION = new Comparator<ExceptionHandler>() {
|
||||
@Override public int compare(ExceptionHandler o1, ExceptionHandler o2) {
|
||||
String exceptionType1 = o1.getExceptionType();
|
||||
if (exceptionType1 == null) {
|
||||
if (o2.getExceptionType() != null) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
String exceptionType2 = o2.getExceptionType();
|
||||
if (exceptionType2 == null) {
|
||||
return -1;
|
||||
}
|
||||
return exceptionType1.compareTo(o2.getExceptionType());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base;
|
||||
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.base.reference.BaseTypeReference;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.AnnotationElement;
|
||||
import org.jf.dexlib2.iface.MethodParameter;
|
||||
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.StringEncodedValue;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseMethodParameter extends BaseTypeReference implements MethodParameter {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSignature() {
|
||||
Annotation signatureAnnotation = null;
|
||||
for (Annotation annotation: getAnnotations()) {
|
||||
if (annotation.getType().equals("Ldalvik/annotation/Signature;")) {
|
||||
signatureAnnotation = annotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (signatureAnnotation == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayEncodedValue signatureValues = null;
|
||||
for (AnnotationElement annotationElement: signatureAnnotation.getElements()) {
|
||||
if (annotationElement.getName().equals("value")) {
|
||||
EncodedValue encodedValue = annotationElement.getValue();
|
||||
if (encodedValue.getValueType() != ValueType.ARRAY) {
|
||||
return null;
|
||||
}
|
||||
signatureValues = (ArrayEncodedValue)encodedValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (signatureValues == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (EncodedValue signatureValue: signatureValues.getValue()) {
|
||||
if (signatureValue.getValueType() != ValueType.STRING) {
|
||||
return null;
|
||||
}
|
||||
sb.append(((StringEncodedValue)signatureValue).getValue());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base;
|
||||
|
||||
import org.jf.dexlib2.iface.ExceptionHandler;
|
||||
import org.jf.dexlib2.iface.TryBlock;
|
||||
|
||||
public abstract class BaseTryBlock<EH extends ExceptionHandler> implements TryBlock<EH> {
|
||||
@Override public boolean equals(Object o) {
|
||||
if (o instanceof TryBlock) {
|
||||
TryBlock other = (TryBlock)o;
|
||||
return getStartCodeAddress() == other.getStartCodeAddress() &&
|
||||
getCodeUnitCount() == other.getCodeUnitCount() &&
|
||||
getExceptionHandlers().equals(other.getExceptionHandlers());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.reference;
|
||||
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseFieldReference implements FieldReference {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = getDefiningClass().hashCode();
|
||||
hashCode = hashCode*31 + getName().hashCode();
|
||||
return hashCode*31 + getType().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof FieldReference) {
|
||||
FieldReference other = (FieldReference)o;
|
||||
return getDefiningClass().equals(other.getDefiningClass()) &&
|
||||
getName().equals(other.getName()) &&
|
||||
getType().equals(other.getType());
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull FieldReference o) {
|
||||
int res = getDefiningClass().compareTo(o.getDefiningClass());
|
||||
if (res != 0) return res;
|
||||
res = getName().compareTo(o.getName());
|
||||
if (res != 0) return res;
|
||||
return getType().compareTo(o.getType());
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.reference;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
import org.jf.util.CharSequenceUtils;
|
||||
import org.jf.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseMethodReference implements MethodReference {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = getDefiningClass().hashCode();
|
||||
hashCode = hashCode*31 + getName().hashCode();
|
||||
hashCode = hashCode*31 + getReturnType().hashCode();
|
||||
return hashCode*31 + getParameterTypes().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o != null && o instanceof MethodReference) {
|
||||
MethodReference other = (MethodReference)o;
|
||||
return getDefiningClass().equals(other.getDefiningClass()) &&
|
||||
getName().equals(other.getName()) &&
|
||||
getReturnType().equals(other.getReturnType()) &&
|
||||
CharSequenceUtils.listEquals(getParameterTypes(), other.getParameterTypes());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull MethodReference o) {
|
||||
int res = getDefiningClass().compareTo(o.getDefiningClass());
|
||||
if (res != 0) return res;
|
||||
res = getName().compareTo(o.getName());
|
||||
if (res != 0) return res;
|
||||
res = getReturnType().compareTo(o.getReturnType());
|
||||
if (res != 0) return res;
|
||||
return CollectionUtils.compareAsIterable(Ordering.usingToString(), getParameterTypes(), o.getParameterTypes());
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.reference;
|
||||
|
||||
import org.jf.dexlib2.iface.reference.StringReference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseStringReference implements StringReference {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getString().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o != null && o instanceof StringReference) {
|
||||
return getString().equals(((StringReference)o).getString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull CharSequence o) {
|
||||
return getString().compareTo(o.toString());
|
||||
}
|
||||
|
||||
@Override public int length() { return getString().length(); }
|
||||
@Override public char charAt(int index) { return getString().charAt(index); }
|
||||
@Override public CharSequence subSequence(int start, int end) { return getString().subSequence(start, end); }
|
||||
@Override public String toString() { return getString(); }
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.reference;
|
||||
|
||||
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public abstract class BaseTypeReference implements TypeReference {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getType().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o != null) {
|
||||
if (o instanceof TypeReference) {
|
||||
return getType().equals(((TypeReference)o).getType());
|
||||
}
|
||||
if (o instanceof CharSequence) {
|
||||
return getType().equals(o.toString());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull CharSequence o) {
|
||||
return getType().compareTo(o.toString());
|
||||
}
|
||||
|
||||
@Override public int length() { return getType().length(); }
|
||||
@Override public char charAt(int index) { return getType().charAt(index); }
|
||||
@Override public CharSequence subSequence(int start, int end) { return getType().subSequence(start, end); }
|
||||
@Override @Nonnull public String toString() { return getType(); }
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.AnnotationEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseAnnotationEncodedValue implements AnnotationEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = getType().hashCode();
|
||||
return hashCode * 31 + getElements().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof AnnotationEncodedValue) {
|
||||
AnnotationEncodedValue other = (AnnotationEncodedValue)o;
|
||||
return getType().equals(other.getType()) &&
|
||||
getElements().equals(other.getElements());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
AnnotationEncodedValue other = (AnnotationEncodedValue)o;
|
||||
res = getType().compareTo(other.getType());
|
||||
if (res != 0) return res;
|
||||
return CollectionUtils.compareAsSet(getElements(), other.getElements());
|
||||
}
|
||||
|
||||
public int getValueType() {
|
||||
return ValueType.ANNOTATION;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.ArrayEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseArrayEncodedValue implements ArrayEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof ArrayEncodedValue) {
|
||||
return getValue().equals(((ArrayEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return CollectionUtils.compareAsList(getValue(), ((ArrayEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.ARRAY; }
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Booleans;
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.BooleanEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseBooleanEncodedValue implements BooleanEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue()?1:0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof BooleanEncodedValue) {
|
||||
return getValue() == ((BooleanEncodedValue)o).getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Booleans.compare(getValue(), ((BooleanEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.BOOLEAN; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.ByteEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseByteEncodedValue implements ByteEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof ByteEncodedValue) {
|
||||
return getValue() == ((ByteEncodedValue)o).getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Ints.compare(getValue(), ((ByteEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.BYTE; }
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Chars;
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.CharEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseCharEncodedValue implements CharEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof CharEncodedValue) {
|
||||
return getValue() == ((CharEncodedValue)o).getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Chars.compare(getValue(), ((CharEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.CHAR; }
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.DoubleEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseDoubleEncodedValue implements DoubleEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
long v = Double.doubleToRawLongBits(getValue());
|
||||
return (int)(v^(v>>>32));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof DoubleEncodedValue) {
|
||||
return Double.doubleToRawLongBits(getValue()) ==
|
||||
Double.doubleToRawLongBits(((DoubleEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Double.compare(getValue(), ((DoubleEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.DOUBLE; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EnumEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseEnumEncodedValue implements EnumEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof EnumEncodedValue) {
|
||||
return getValue().equals(((EnumEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return getValue().compareTo(((EnumEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.ENUM; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.FieldEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseFieldEncodedValue implements FieldEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof FieldEncodedValue) {
|
||||
return getValue().equals(((FieldEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return getValue().compareTo(((FieldEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.FIELD; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.FloatEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseFloatEncodedValue implements FloatEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Float.floatToRawIntBits(getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o != null && o instanceof FloatEncodedValue) {
|
||||
return Float.floatToRawIntBits(getValue()) == Float.floatToRawIntBits(((FloatEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Float.compare(getValue(), ((FloatEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.FLOAT; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.IntEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseIntEncodedValue implements IntEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof IntEncodedValue) {
|
||||
return getValue() == ((IntEncodedValue)o).getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Ints.compare(getValue(), ((IntEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.INT; }
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.Longs;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.LongEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseLongEncodedValue implements LongEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
long value = getValue();
|
||||
int hashCode = (int)value;
|
||||
return hashCode*31 + (int)(value>>>32);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof LongEncodedValue) {
|
||||
return getValue() == ((LongEncodedValue)o).getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Longs.compare(getValue(), ((LongEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.LONG; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.MethodEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseMethodEncodedValue implements MethodEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof MethodEncodedValue) {
|
||||
return getValue().equals(((MethodEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return getValue().compareTo(((MethodEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.METHOD; }
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.NullEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseNullEncodedValue implements NullEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
return o instanceof NullEncodedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
return Ints.compare(getValueType(), o.getValueType());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.NULL; }
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.Shorts;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.ShortEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseShortEncodedValue implements ShortEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof ShortEncodedValue) {
|
||||
return getValue() == ((ShortEncodedValue)o).getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return Shorts.compare(getValue(), ((ShortEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.SHORT; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.StringEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseStringEncodedValue implements StringEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof StringEncodedValue) {
|
||||
return getValue().equals(((StringEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return getValue().compareTo(((StringEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.STRING; }
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.base.value;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.jf.dexlib2.ValueType;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
import org.jf.dexlib2.iface.value.TypeEncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class BaseTypeEncodedValue implements TypeEncodedValue {
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getValue().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof TypeEncodedValue) {
|
||||
return getValue().equals(((TypeEncodedValue)o).getValue());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nonnull EncodedValue o) {
|
||||
int res = Ints.compare(getValueType(), o.getValueType());
|
||||
if (res != 0) return res;
|
||||
return getValue().compareTo(((TypeEncodedValue)o).getValue());
|
||||
}
|
||||
|
||||
public int getValueType() { return ValueType.TYPE; }
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class BaseDexBuffer {
|
||||
@Nonnull /* package private */ final byte[] buf;
|
||||
|
||||
public BaseDexBuffer(@Nonnull byte[] buf) {
|
||||
this.buf = buf;
|
||||
}
|
||||
|
||||
public int readSmallUint(int offset) {
|
||||
byte[] buf = this.buf;
|
||||
int result = (buf[offset] & 0xff) |
|
||||
((buf[offset+1] & 0xff) << 8) |
|
||||
((buf[offset+2] & 0xff) << 16) |
|
||||
((buf[offset+3]) << 24);
|
||||
if (result < 0) {
|
||||
throw new ExceptionWithContext("Encountered small uint that is out of range at offset 0x%x", offset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readOptionalUint(int offset) {
|
||||
byte[] buf = this.buf;
|
||||
int result = (buf[offset] & 0xff) |
|
||||
((buf[offset+1] & 0xff) << 8) |
|
||||
((buf[offset+2] & 0xff) << 16) |
|
||||
((buf[offset+3]) << 24);
|
||||
if (result < -1) {
|
||||
throw new ExceptionWithContext("Encountered optional uint that is out of range at offset 0x%x", offset);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readUshort(int offset) {
|
||||
byte[] buf = this.buf;
|
||||
return (buf[offset] & 0xff) |
|
||||
((buf[offset+1] & 0xff) << 8);
|
||||
}
|
||||
|
||||
public int readUbyte(int offset) {
|
||||
return buf[offset] & 0xff;
|
||||
}
|
||||
|
||||
public long readLong(int offset) {
|
||||
byte[] buf = this.buf;
|
||||
return (buf[offset] & 0xff) |
|
||||
((buf[offset+1] & 0xff) << 8) |
|
||||
((buf[offset+2] & 0xff) << 16) |
|
||||
((buf[offset+3] & 0xffL) << 24) |
|
||||
((buf[offset+4] & 0xffL) << 32) |
|
||||
((buf[offset+5] & 0xffL) << 40) |
|
||||
((buf[offset+6] & 0xffL) << 48) |
|
||||
(((long)buf[offset+7]) << 56);
|
||||
}
|
||||
|
||||
public int readInt(int offset) {
|
||||
byte[] buf = this.buf;
|
||||
return (buf[offset] & 0xff) |
|
||||
((buf[offset+1] & 0xff) << 8) |
|
||||
((buf[offset+2] & 0xff) << 16) |
|
||||
(buf[offset+3] << 24);
|
||||
}
|
||||
|
||||
public int readShort(int offset) {
|
||||
byte[] buf = this.buf;
|
||||
return (buf[offset] & 0xff) |
|
||||
(buf[offset+1] << 8);
|
||||
}
|
||||
|
||||
public int readByte(int offset) {
|
||||
return buf[offset];
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public BaseDexReader readerAt(int offset) {
|
||||
return new BaseDexReader<BaseDexBuffer>(this, offset);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
protected byte[] getBuf() {
|
||||
return buf;
|
||||
}
|
||||
}
|
@ -0,0 +1,508 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
import org.jf.util.Utf8Utils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class BaseDexReader<T extends BaseDexBuffer> {
|
||||
@Nonnull public final T dexBuf;
|
||||
private int offset;
|
||||
|
||||
public BaseDexReader(@Nonnull T dexBuf, int offset) {
|
||||
this.dexBuf = dexBuf;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int getOffset() { return offset; }
|
||||
public void setOffset(int offset) { this.offset = offset; }
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int readSleb128() {
|
||||
int end = offset;
|
||||
int currentByteValue;
|
||||
int result;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
result = buf[end++] & 0xff;
|
||||
if (result <= 0x7f) {
|
||||
result = (result << 25) >> 25;
|
||||
} else {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||
if (currentByteValue <= 0x7f) {
|
||||
result = (result << 18) >> 18;
|
||||
} else {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 14;
|
||||
if (currentByteValue <= 0x7f) {
|
||||
result = (result << 11) >> 11;
|
||||
} else {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 21;
|
||||
if (currentByteValue <= 0x7f) {
|
||||
result = (result << 4) >> 4;
|
||||
} else {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
if (currentByteValue > 0x7f) {
|
||||
throw new ExceptionWithContext(
|
||||
"Invalid sleb128 integer encountered at offset 0x%x", offset);
|
||||
}
|
||||
result |= currentByteValue << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offset = end;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readSmallUleb128() {
|
||||
int end = offset;
|
||||
int currentByteValue;
|
||||
int result;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
result = buf[end++] & 0xff;
|
||||
if (result > 0x7f) {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 14;
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 21;
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = buf[end++];
|
||||
|
||||
// MSB shouldn't be set on last byte
|
||||
if (currentByteValue < 0) {
|
||||
throw new ExceptionWithContext(
|
||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||
} else if ((currentByteValue & 0xf) > 0x07) {
|
||||
// we assume most significant bit of the result will not be set, so that it can fit into
|
||||
// a signed integer without wrapping
|
||||
throw new ExceptionWithContext(
|
||||
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
||||
}
|
||||
result |= currentByteValue << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offset = end;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a "big" uleb128 that can legitimately be > 2^31. The value is returned as a signed integer, with the
|
||||
* expected semantics of re-interpreting an unsigned value as a signed value.
|
||||
*
|
||||
* @return The unsigned value, reinterpreted as a signed int
|
||||
*/
|
||||
public int readBigUleb128() {
|
||||
int end = offset;
|
||||
int currentByteValue;
|
||||
int result;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
result = buf[end++] & 0xff;
|
||||
if (result > 0x7f) {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result = (result & 0x7f) | ((currentByteValue & 0x7f) << 7);
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 14;
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = buf[end++] & 0xff;
|
||||
result |= (currentByteValue & 0x7f) << 21;
|
||||
if (currentByteValue > 0x7f) {
|
||||
currentByteValue = buf[end++];
|
||||
|
||||
// MSB shouldn't be set on last byte
|
||||
if (currentByteValue < 0) {
|
||||
throw new ExceptionWithContext(
|
||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||
}
|
||||
result |= currentByteValue << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offset = end;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void skipUleb128() {
|
||||
int end = offset;
|
||||
byte currentByteValue;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
currentByteValue = buf[end++];
|
||||
if (currentByteValue < 0) { // if the MSB is set
|
||||
currentByteValue = buf[end++];
|
||||
if (currentByteValue < 0) { // if the MSB is set
|
||||
currentByteValue = buf[end++];
|
||||
if (currentByteValue < 0) { // if the MSB is set
|
||||
currentByteValue = buf[end++];
|
||||
if (currentByteValue < 0) { // if the MSB is set
|
||||
currentByteValue = buf[end++];
|
||||
if (currentByteValue < 0) {
|
||||
throw new ExceptionWithContext(
|
||||
"Invalid uleb128 integer encountered at offset 0x%x", offset);
|
||||
} else if ((currentByteValue & 0xf) > 0x07) {
|
||||
// we assume most significant bit of the result will not be set, so that it can fit into
|
||||
// a signed integer without wrapping
|
||||
throw new ExceptionWithContext(
|
||||
"Encountered valid uleb128 that is out of range at offset 0x%x", offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
offset = end;
|
||||
}
|
||||
|
||||
public int readSmallUint() {
|
||||
int o = offset;
|
||||
int result = dexBuf.readSmallUint(o);
|
||||
offset = o + 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readOptionalUint() {
|
||||
int o = offset;
|
||||
int result = dexBuf.readOptionalUint(o);
|
||||
offset = o + 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int peekUshort() {
|
||||
return dexBuf.readUshort(offset);
|
||||
}
|
||||
|
||||
public int readUshort() {
|
||||
int o = offset;
|
||||
int result = dexBuf.readUshort(offset);
|
||||
offset = o + 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int peekUbyte() {
|
||||
return dexBuf.readUbyte(offset);
|
||||
}
|
||||
|
||||
public int readUbyte() {
|
||||
int o = offset;
|
||||
int result = dexBuf.readUbyte(offset);
|
||||
offset = o + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
public long readLong() {
|
||||
int o = offset;
|
||||
long result = dexBuf.readLong(offset);
|
||||
offset = o + 8;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readInt() {
|
||||
int o = offset;
|
||||
int result = dexBuf.readInt(offset);
|
||||
offset = o + 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readShort() {
|
||||
int o = offset;
|
||||
int result = dexBuf.readShort(offset);
|
||||
offset = o + 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readByte() {
|
||||
int o = offset;
|
||||
int result = dexBuf.readByte(offset);
|
||||
offset = o + 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void skipByte() { offset++; }
|
||||
public void moveRelative(int i) { offset += i; }
|
||||
|
||||
public int readSmallUint(int offset) { return dexBuf.readSmallUint(offset); }
|
||||
public int readUshort(int offset) { return dexBuf.readUshort(offset); }
|
||||
public int readUbyte(int offset) { return dexBuf.readUbyte(offset); }
|
||||
public long readLong(int offset) { return dexBuf.readLong(offset); }
|
||||
public int readInt(int offset) { return dexBuf.readInt(offset); }
|
||||
public int readShort(int offset) { return dexBuf.readShort(offset); }
|
||||
public int readByte(int offset) { return dexBuf.readByte(offset); }
|
||||
|
||||
public int readSizedInt(int bytes) {
|
||||
int o = offset;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
int result;
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
(buf[o+3] << 24);
|
||||
break;
|
||||
case 3:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2]) << 16);
|
||||
break;
|
||||
case 2:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1]) << 8);
|
||||
break;
|
||||
case 1:
|
||||
result = buf[o];
|
||||
break;
|
||||
default:
|
||||
throw new ExceptionWithContext("Invalid size %d for sized int at offset 0x%x", bytes, offset);
|
||||
}
|
||||
offset = o + bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readSizedSmallUint(int bytes) {
|
||||
int o = offset;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
int result = 0;
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
int b = buf[o+3];
|
||||
if (b < 0) {
|
||||
throw new ExceptionWithContext(
|
||||
"Encountered valid sized uint that is out of range at offset 0x%x", offset);
|
||||
}
|
||||
result = b << 24;
|
||||
// fall-through
|
||||
case 3:
|
||||
result |= (buf[o+2] & 0xff) << 16;
|
||||
// fall-through
|
||||
case 2:
|
||||
result |= (buf[o+1] & 0xff) << 8;
|
||||
// fall-through
|
||||
case 1:
|
||||
result |= (buf[o] & 0xff);
|
||||
break;
|
||||
default:
|
||||
throw new ExceptionWithContext("Invalid size %d for sized uint at offset 0x%x", bytes, offset);
|
||||
}
|
||||
offset = o + bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int readSizedRightExtendedInt(int bytes) {
|
||||
int o = offset;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
int result;
|
||||
switch (bytes) {
|
||||
case 4:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
(buf[o+3] << 24);
|
||||
break;
|
||||
case 3:
|
||||
result = (buf[o] & 0xff) << 8 |
|
||||
((buf[o+1] & 0xff) << 16) |
|
||||
(buf[o+2] << 24);
|
||||
break;
|
||||
case 2:
|
||||
result = (buf[o] & 0xff) << 16 |
|
||||
(buf[o+1] << 24);
|
||||
break;
|
||||
case 1:
|
||||
result = buf[o] << 24;
|
||||
break;
|
||||
default:
|
||||
throw new ExceptionWithContext(
|
||||
"Invalid size %d for sized, right extended int at offset 0x%x", bytes, offset);
|
||||
}
|
||||
offset = o + bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
public long readSizedRightExtendedLong(int bytes) {
|
||||
int o = offset;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
long result;
|
||||
switch (bytes) {
|
||||
case 8:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
((buf[o+3] & 0xffL) << 24) |
|
||||
((buf[o+4] & 0xffL) << 32) |
|
||||
((buf[o+5] & 0xffL) << 40) |
|
||||
((buf[o+6] & 0xffL) << 48) |
|
||||
(((long)buf[o+7]) << 56);
|
||||
break;
|
||||
case 7:
|
||||
result = ((buf[o] & 0xff)) << 8 |
|
||||
((buf[o+1] & 0xff) << 16) |
|
||||
((buf[o+2] & 0xffL) << 24) |
|
||||
((buf[o+3] & 0xffL) << 32) |
|
||||
((buf[o+4] & 0xffL) << 40) |
|
||||
((buf[o+5] & 0xffL) << 48) |
|
||||
(((long)buf[o+6]) << 56);
|
||||
break;
|
||||
case 6:
|
||||
result = ((buf[o] & 0xff)) << 16 |
|
||||
((buf[o+1] & 0xffL) << 24) |
|
||||
((buf[o+2] & 0xffL) << 32) |
|
||||
((buf[o+3] & 0xffL) << 40) |
|
||||
((buf[o+4] & 0xffL) << 48) |
|
||||
(((long)buf[o+5]) << 56);
|
||||
break;
|
||||
case 5:
|
||||
result = ((buf[o] & 0xffL)) << 24 |
|
||||
((buf[o+1] & 0xffL) << 32) |
|
||||
((buf[o+2] & 0xffL) << 40) |
|
||||
((buf[o+3] & 0xffL) << 48) |
|
||||
(((long)buf[o+4]) << 56);
|
||||
break;
|
||||
case 4:
|
||||
result = ((buf[o] & 0xffL)) << 32 |
|
||||
((buf[o+1] & 0xffL) << 40) |
|
||||
((buf[o+2] & 0xffL) << 48) |
|
||||
(((long)buf[o+3]) << 56);
|
||||
break;
|
||||
case 3:
|
||||
result = ((buf[o] & 0xffL)) << 40 |
|
||||
((buf[o+1] & 0xffL) << 48) |
|
||||
(((long)buf[o+2]) << 56);
|
||||
break;
|
||||
case 2:
|
||||
result = ((buf[o] & 0xffL)) << 48 |
|
||||
(((long)buf[o+1]) << 56);
|
||||
break;
|
||||
case 1:
|
||||
result = ((long)buf[o]) << 56;
|
||||
break;
|
||||
default:
|
||||
throw new ExceptionWithContext(
|
||||
"Invalid size %d for sized, right extended long at offset 0x%x", bytes, offset);
|
||||
}
|
||||
offset = o + bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
public long readSizedLong(int bytes) {
|
||||
int o = offset;
|
||||
byte[] buf = dexBuf.buf;
|
||||
|
||||
long result;
|
||||
switch (bytes) {
|
||||
case 8:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
((buf[o+3] & 0xffL) << 24) |
|
||||
((buf[o+4] & 0xffL) << 32) |
|
||||
((buf[o+5] & 0xffL) << 40) |
|
||||
((buf[o+6] & 0xffL) << 48) |
|
||||
(((long)buf[o+7]) << 56);
|
||||
break;
|
||||
case 7:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
((buf[o+3] & 0xffL) << 24) |
|
||||
((buf[o+4] & 0xffL) << 32) |
|
||||
((buf[o+5] & 0xffL) << 40) |
|
||||
((long)(buf[o+6]) << 48);
|
||||
break;
|
||||
case 6:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
((buf[o+3] & 0xffL) << 24) |
|
||||
((buf[o+4] & 0xffL) << 32) |
|
||||
((long)(buf[o+5]) << 40);
|
||||
break;
|
||||
case 5:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
((buf[o+3] & 0xffL) << 24) |
|
||||
((long)(buf[o+4]) << 32);
|
||||
break;
|
||||
case 4:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
((buf[o+2] & 0xff) << 16) |
|
||||
(((long)buf[o+3]) << 24);
|
||||
break;
|
||||
case 3:
|
||||
result = (buf[o] & 0xff) |
|
||||
((buf[o+1] & 0xff) << 8) |
|
||||
(buf[o+2] << 16);
|
||||
break;
|
||||
case 2:
|
||||
result = (buf[o] & 0xff) |
|
||||
(buf[o+1] << 8);
|
||||
break;
|
||||
case 1:
|
||||
result = buf[o];
|
||||
break;
|
||||
default:
|
||||
throw new ExceptionWithContext("Invalid size %d for sized long at offset 0x%x", bytes, offset);
|
||||
}
|
||||
|
||||
offset = o + bytes;
|
||||
return result;
|
||||
}
|
||||
|
||||
public String readString(int utf16Length) {
|
||||
int[] ret = new int[1];
|
||||
String value = Utf8Utils.utf8BytesWithUtf16LengthToString(dexBuf.buf, offset, utf16Length, ret);
|
||||
offset += ret[0];
|
||||
return value;
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.dexlib2.base.BaseAnnotation;
|
||||
import org.jf.dexlib2.dexbacked.util.VariableSizeSet;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Set;
|
||||
|
||||
public class DexBackedAnnotation extends BaseAnnotation {
|
||||
@Nonnull public final DexBackedDexFile dexFile;
|
||||
|
||||
public final int visibility;
|
||||
public final int typeIndex;
|
||||
private final int elementsOffset;
|
||||
|
||||
public DexBackedAnnotation(@Nonnull DexBackedDexFile dexFile,
|
||||
int annotationOffset) {
|
||||
this.dexFile = dexFile;
|
||||
|
||||
DexReader reader = dexFile.readerAt(annotationOffset);
|
||||
this.visibility = reader.readUbyte();
|
||||
this.typeIndex = reader.readSmallUleb128();
|
||||
this.elementsOffset = reader.getOffset();
|
||||
}
|
||||
|
||||
@Override public int getVisibility() { return visibility; }
|
||||
@Nonnull @Override public String getType() { return dexFile.getType(typeIndex); }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Set<? extends DexBackedAnnotationElement> getElements() {
|
||||
DexReader reader = dexFile.readerAt(elementsOffset);
|
||||
final int size = reader.readSmallUleb128();
|
||||
|
||||
return new VariableSizeSet<DexBackedAnnotationElement>(dexFile, reader.getOffset(), size) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected DexBackedAnnotationElement readNextItem(@Nonnull DexReader reader, int index) {
|
||||
return new DexBackedAnnotationElement(reader);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.dexlib2.base.BaseAnnotationElement;
|
||||
import org.jf.dexlib2.dexbacked.value.DexBackedEncodedValue;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedAnnotationElement extends BaseAnnotationElement {
|
||||
@Nonnull private final DexBackedDexFile dexFile;
|
||||
public final int nameIndex;
|
||||
@Nonnull public final EncodedValue value;
|
||||
|
||||
public DexBackedAnnotationElement(@Nonnull DexReader reader) {
|
||||
this.dexFile = reader.dexBuf;
|
||||
this.nameIndex = reader.readSmallUleb128();
|
||||
this.value = DexBackedEncodedValue.readFrom(reader);
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getName() { return dexFile.getString(nameIndex); }
|
||||
@Nonnull @Override public EncodedValue getValue() { return value; }
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.dexlib2.base.BaseExceptionHandler;
|
||||
import org.jf.dexlib2.iface.ExceptionHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DexBackedCatchAllExceptionHandler extends DexBackedExceptionHandler {
|
||||
private final int handlerCodeAddress;
|
||||
|
||||
public DexBackedCatchAllExceptionHandler(@Nonnull DexReader reader) {
|
||||
this.handlerCodeAddress = reader.readSmallUleb128();
|
||||
}
|
||||
|
||||
@Nullable @Override public String getExceptionType() { return null; }
|
||||
@Override public int getHandlerCodeAddress() { return handlerCodeAddress; }
|
||||
}
|
@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jf.dexlib2.base.reference.BaseTypeReference;
|
||||
import org.jf.dexlib2.dexbacked.raw.ClassDefItem;
|
||||
import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
|
||||
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
|
||||
import org.jf.dexlib2.dexbacked.util.StaticInitialValueIterator;
|
||||
import org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.reference.FieldReference;
|
||||
import org.jf.dexlib2.iface.reference.MethodReference;
|
||||
import org.jf.dexlib2.immutable.reference.ImmutableFieldReference;
|
||||
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public class DexBackedClassDef extends BaseTypeReference implements ClassDef {
|
||||
@Nonnull public final DexBackedDexFile dexFile;
|
||||
private final int classDefOffset;
|
||||
|
||||
private final int staticFieldsOffset;
|
||||
private int instanceFieldsOffset = 0;
|
||||
private int directMethodsOffset = 0;
|
||||
private int virtualMethodsOffset = 0;
|
||||
|
||||
private final int staticFieldCount;
|
||||
private final int instanceFieldCount;
|
||||
private final int directMethodCount;
|
||||
private final int virtualMethodCount;
|
||||
|
||||
@Nullable private AnnotationsDirectory annotationsDirectory;
|
||||
|
||||
public DexBackedClassDef(@Nonnull DexBackedDexFile dexFile,
|
||||
int classDefOffset) {
|
||||
this.dexFile = dexFile;
|
||||
this.classDefOffset = classDefOffset;
|
||||
|
||||
int classDataOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_DATA_OFFSET);
|
||||
if (classDataOffset == 0) {
|
||||
staticFieldsOffset = -1;
|
||||
staticFieldCount = 0;
|
||||
instanceFieldCount = 0;
|
||||
directMethodCount = 0;
|
||||
virtualMethodCount = 0;
|
||||
} else {
|
||||
DexReader reader = dexFile.readerAt(classDataOffset);
|
||||
staticFieldCount = reader.readSmallUleb128();
|
||||
instanceFieldCount = reader.readSmallUleb128();
|
||||
directMethodCount = reader.readSmallUleb128();
|
||||
virtualMethodCount = reader.readSmallUleb128();
|
||||
staticFieldsOffset = reader.getOffset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType() {
|
||||
return dexFile.getType(dexFile.readSmallUint(classDefOffset + ClassDefItem.CLASS_OFFSET));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSuperclass() {
|
||||
return dexFile.getOptionalType(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SUPERCLASS_OFFSET));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAccessFlags() {
|
||||
return dexFile.readSmallUint(classDefOffset + ClassDefItem.ACCESS_FLAGS_OFFSET);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getSourceFile() {
|
||||
return dexFile.getOptionalString(dexFile.readOptionalUint(classDefOffset + ClassDefItem.SOURCE_FILE_OFFSET));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Set<String> getInterfaces() {
|
||||
final int interfacesOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.INTERFACES_OFFSET);
|
||||
if (interfacesOffset > 0) {
|
||||
final int size = dexFile.readSmallUint(interfacesOffset);
|
||||
return new FixedSizeSet<String>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public String readItem(int index) {
|
||||
return dexFile.getType(dexFile.readUshort(interfacesOffset + 4 + (2*index)));
|
||||
}
|
||||
|
||||
@Override public int size() { return size; }
|
||||
};
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Set<? extends DexBackedAnnotation> getAnnotations() {
|
||||
return getAnnotationsDirectory().getClassAnnotations();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterable<? extends DexBackedField> getStaticFields() {
|
||||
return getStaticFields(true);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Iterable<? extends DexBackedField> getStaticFields(final boolean skipDuplicates) {
|
||||
if (staticFieldCount > 0) {
|
||||
DexReader reader = dexFile.readerAt(staticFieldsOffset);
|
||||
|
||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||
final int staticInitialValuesOffset =
|
||||
dexFile.readSmallUint(classDefOffset + ClassDefItem.STATIC_VALUES_OFFSET);
|
||||
final int fieldsStartOffset = reader.getOffset();
|
||||
final AnnotationsDirectory.AnnotationIterator annotationIterator =
|
||||
annotationsDirectory.getFieldAnnotationIterator();
|
||||
final StaticInitialValueIterator staticInitialValueIterator =
|
||||
StaticInitialValueIterator.newOrEmpty(dexFile, staticInitialValuesOffset);
|
||||
|
||||
|
||||
return new Iterable<DexBackedField>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterator<DexBackedField> iterator() {
|
||||
return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) {
|
||||
private int count;
|
||||
@Nullable private FieldReference previousField;
|
||||
private int previousIndex;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected DexBackedField readNextItem(@Nonnull DexReader reader) {
|
||||
while (true) {
|
||||
if (++count > staticFieldCount) {
|
||||
instanceFieldsOffset = reader.getOffset();
|
||||
return null;
|
||||
}
|
||||
|
||||
DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this,
|
||||
previousIndex, staticInitialValueIterator, annotationIterator);
|
||||
FieldReference currentField = previousField;
|
||||
FieldReference nextField = ImmutableFieldReference.of(item);
|
||||
|
||||
previousField = nextField;
|
||||
previousIndex = item.fieldIndex;
|
||||
|
||||
if (skipDuplicates && currentField != null && currentField.equals(nextField)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
} else {
|
||||
instanceFieldsOffset = staticFieldsOffset;
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterable<? extends DexBackedField> getInstanceFields() {
|
||||
return getInstanceFields(true);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Iterable<? extends DexBackedField> getInstanceFields(final boolean skipDuplicates) {
|
||||
if (instanceFieldCount > 0) {
|
||||
DexReader reader = dexFile.readerAt(getInstanceFieldsOffset());
|
||||
|
||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||
final AnnotationsDirectory.AnnotationIterator annotationIterator =
|
||||
annotationsDirectory.getFieldAnnotationIterator();
|
||||
final int fieldsStartOffset = reader.getOffset();
|
||||
|
||||
return new Iterable<DexBackedField>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterator<DexBackedField> iterator() {
|
||||
return new VariableSizeLookaheadIterator<DexBackedField>(dexFile, fieldsStartOffset) {
|
||||
private int count;
|
||||
@Nullable private FieldReference previousField;
|
||||
private int previousIndex;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected DexBackedField readNextItem(@Nonnull DexReader reader) {
|
||||
while (true) {
|
||||
if (++count > instanceFieldCount) {
|
||||
directMethodsOffset = reader.getOffset();
|
||||
return null;
|
||||
}
|
||||
|
||||
DexBackedField item = new DexBackedField(reader, DexBackedClassDef.this,
|
||||
previousIndex, annotationIterator);
|
||||
FieldReference currentField = previousField;
|
||||
FieldReference nextField = ImmutableFieldReference.of(item);
|
||||
|
||||
previousField = nextField;
|
||||
previousIndex = item.fieldIndex;
|
||||
|
||||
if (skipDuplicates && currentField != null && currentField.equals(nextField)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
} else {
|
||||
if (instanceFieldsOffset > 0) {
|
||||
directMethodsOffset = instanceFieldsOffset;
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterable<? extends DexBackedField> getFields() {
|
||||
return Iterables.concat(getStaticFields(), getInstanceFields());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterable<? extends DexBackedMethod> getDirectMethods() {
|
||||
return getDirectMethods(true);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Iterable<? extends DexBackedMethod> getDirectMethods(final boolean skipDuplicates) {
|
||||
if (directMethodCount > 0) {
|
||||
DexReader reader = dexFile.readerAt(getDirectMethodsOffset());
|
||||
|
||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||
final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator =
|
||||
annotationsDirectory.getMethodAnnotationIterator();
|
||||
final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator =
|
||||
annotationsDirectory.getParameterAnnotationIterator();
|
||||
final int methodsStartOffset = reader.getOffset();
|
||||
|
||||
return new Iterable<DexBackedMethod>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterator<DexBackedMethod> iterator() {
|
||||
return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile, methodsStartOffset) {
|
||||
private int count;
|
||||
@Nullable private MethodReference previousMethod;
|
||||
private int previousIndex;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected DexBackedMethod readNextItem(@Nonnull DexReader reader) {
|
||||
while (true) {
|
||||
if (++count > directMethodCount) {
|
||||
virtualMethodsOffset = reader.getOffset();
|
||||
return null;
|
||||
}
|
||||
|
||||
DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this,
|
||||
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
|
||||
MethodReference currentMethod = previousMethod;
|
||||
MethodReference nextMethod = ImmutableMethodReference.of(item);
|
||||
|
||||
previousMethod = nextMethod;
|
||||
previousIndex = item.methodIndex;
|
||||
|
||||
if (skipDuplicates && currentMethod != null && currentMethod.equals(nextMethod)) {
|
||||
continue;
|
||||
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
} else {
|
||||
if (directMethodsOffset > 0) {
|
||||
virtualMethodsOffset = directMethodsOffset;
|
||||
}
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Iterable<? extends DexBackedMethod> getVirtualMethods(final boolean skipDuplicates) {
|
||||
if (virtualMethodCount > 0) {
|
||||
DexReader reader = dexFile.readerAt(getVirtualMethodsOffset());
|
||||
|
||||
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
|
||||
final AnnotationsDirectory.AnnotationIterator methodAnnotationIterator =
|
||||
annotationsDirectory.getMethodAnnotationIterator();
|
||||
final AnnotationsDirectory.AnnotationIterator parameterAnnotationIterator =
|
||||
annotationsDirectory.getParameterAnnotationIterator();
|
||||
final int methodsStartOffset = reader.getOffset();
|
||||
|
||||
return new Iterable<DexBackedMethod>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterator<DexBackedMethod> iterator() {
|
||||
return new VariableSizeLookaheadIterator<DexBackedMethod>(dexFile, methodsStartOffset) {
|
||||
private int count;
|
||||
@Nullable private MethodReference previousMethod;
|
||||
private int previousIndex;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected DexBackedMethod readNextItem(@Nonnull DexReader reader) {
|
||||
while (true) {
|
||||
if (++count > virtualMethodCount) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DexBackedMethod item = new DexBackedMethod(reader, DexBackedClassDef.this,
|
||||
previousIndex, methodAnnotationIterator, parameterAnnotationIterator);
|
||||
MethodReference currentMethod = previousMethod;
|
||||
MethodReference nextMethod = ImmutableMethodReference.of(item);
|
||||
|
||||
previousMethod = nextMethod;
|
||||
previousIndex = item.methodIndex;
|
||||
|
||||
if (skipDuplicates && currentMethod != null && currentMethod.equals(nextMethod)) {
|
||||
continue;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterable<? extends DexBackedMethod> getVirtualMethods() {
|
||||
return getVirtualMethods(true);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Iterable<? extends DexBackedMethod> getMethods() {
|
||||
return Iterables.concat(getDirectMethods(), getVirtualMethods());
|
||||
}
|
||||
|
||||
private AnnotationsDirectory getAnnotationsDirectory() {
|
||||
if (annotationsDirectory == null) {
|
||||
int annotationsDirectoryOffset = dexFile.readSmallUint(classDefOffset + ClassDefItem.ANNOTATIONS_OFFSET);
|
||||
annotationsDirectory = AnnotationsDirectory.newOrEmpty(dexFile, annotationsDirectoryOffset);
|
||||
}
|
||||
return annotationsDirectory;
|
||||
}
|
||||
|
||||
private int getInstanceFieldsOffset() {
|
||||
if (instanceFieldsOffset > 0) {
|
||||
return instanceFieldsOffset;
|
||||
}
|
||||
DexReader reader = new DexReader(dexFile, staticFieldsOffset);
|
||||
DexBackedField.skipFields(reader, staticFieldCount);
|
||||
instanceFieldsOffset = reader.getOffset();
|
||||
return instanceFieldsOffset;
|
||||
}
|
||||
|
||||
private int getDirectMethodsOffset() {
|
||||
if (directMethodsOffset > 0) {
|
||||
return directMethodsOffset;
|
||||
}
|
||||
DexReader reader = dexFile.readerAt(getInstanceFieldsOffset());
|
||||
DexBackedField.skipFields(reader, instanceFieldCount);
|
||||
directMethodsOffset = reader.getOffset();
|
||||
return directMethodsOffset;
|
||||
}
|
||||
|
||||
private int getVirtualMethodsOffset() {
|
||||
if (virtualMethodsOffset > 0) {
|
||||
return virtualMethodsOffset;
|
||||
}
|
||||
DexReader reader = dexFile.readerAt(getDirectMethodsOffset());
|
||||
DexBackedMethod.skipMethods(reader, directMethodCount);
|
||||
virtualMethodsOffset = reader.getOffset();
|
||||
return virtualMethodsOffset;
|
||||
}
|
||||
}
|
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
import org.jf.dexlib2.Opcodes;
|
||||
import org.jf.dexlib2.dexbacked.raw.*;
|
||||
import org.jf.dexlib2.dexbacked.util.FixedSizeSet;
|
||||
import org.jf.dexlib2.iface.DexFile;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Set;
|
||||
|
||||
public class DexBackedDexFile extends BaseDexBuffer implements DexFile {
|
||||
private final Opcodes opcodes;
|
||||
|
||||
private final int stringCount;
|
||||
private final int stringStartOffset;
|
||||
private final int typeCount;
|
||||
private final int typeStartOffset;
|
||||
private final int protoCount;
|
||||
private final int protoStartOffset;
|
||||
private final int fieldCount;
|
||||
private final int fieldStartOffset;
|
||||
private final int methodCount;
|
||||
private final int methodStartOffset;
|
||||
private final int classCount;
|
||||
private final int classStartOffset;
|
||||
|
||||
private DexBackedDexFile(Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) {
|
||||
super(buf);
|
||||
|
||||
this.opcodes = opcodes;
|
||||
|
||||
if (verifyMagic) {
|
||||
verifyMagicAndByteOrder(buf, offset);
|
||||
}
|
||||
|
||||
stringCount = readSmallUint(HeaderItem.STRING_COUNT_OFFSET);
|
||||
stringStartOffset = readSmallUint(HeaderItem.STRING_START_OFFSET);
|
||||
typeCount = readSmallUint(HeaderItem.TYPE_COUNT_OFFSET);
|
||||
typeStartOffset = readSmallUint(HeaderItem.TYPE_START_OFFSET);
|
||||
protoCount = readSmallUint(HeaderItem.PROTO_COUNT_OFFSET);
|
||||
protoStartOffset = readSmallUint(HeaderItem.PROTO_START_OFFSET);
|
||||
fieldCount = readSmallUint(HeaderItem.FIELD_COUNT_OFFSET);
|
||||
fieldStartOffset = readSmallUint(HeaderItem.FIELD_START_OFFSET);
|
||||
methodCount = readSmallUint(HeaderItem.METHOD_COUNT_OFFSET);
|
||||
methodStartOffset = readSmallUint(HeaderItem.METHOD_START_OFFSET);
|
||||
classCount = readSmallUint(HeaderItem.CLASS_COUNT_OFFSET);
|
||||
classStartOffset = readSmallUint(HeaderItem.CLASS_START_OFFSET);
|
||||
}
|
||||
|
||||
public DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull BaseDexBuffer buf) {
|
||||
this(opcodes, buf.buf);
|
||||
}
|
||||
|
||||
public DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull byte[] buf, int offset) {
|
||||
this(opcodes, buf, offset, false);
|
||||
}
|
||||
|
||||
public DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull byte[] buf) {
|
||||
this(opcodes, buf, 0, true);
|
||||
}
|
||||
|
||||
public static DexBackedDexFile fromInputStream(@Nonnull Opcodes opcodes, @Nonnull InputStream is)
|
||||
throws IOException {
|
||||
if (!is.markSupported()) {
|
||||
throw new IllegalArgumentException("InputStream must support mark");
|
||||
}
|
||||
is.mark(44);
|
||||
byte[] partialHeader = new byte[44];
|
||||
try {
|
||||
ByteStreams.readFully(is, partialHeader);
|
||||
} catch (EOFException ex) {
|
||||
throw new NotADexFile("File is too short");
|
||||
} finally {
|
||||
is.reset();
|
||||
}
|
||||
|
||||
verifyMagicAndByteOrder(partialHeader, 0);
|
||||
|
||||
byte[] buf = ByteStreams.toByteArray(is);
|
||||
return new DexBackedDexFile(opcodes, buf, 0, false);
|
||||
}
|
||||
|
||||
public Opcodes getOpcodes() {
|
||||
return opcodes;
|
||||
}
|
||||
|
||||
public boolean isOdexFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Set<? extends DexBackedClassDef> getClasses() {
|
||||
return new FixedSizeSet<DexBackedClassDef>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public DexBackedClassDef readItem(int index) {
|
||||
return new DexBackedClassDef(DexBackedDexFile.this, getClassDefItemOffset(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return classCount;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void verifyMagicAndByteOrder(@Nonnull byte[] buf, int offset) {
|
||||
if (!HeaderItem.verifyMagic(buf, offset)) {
|
||||
StringBuilder sb = new StringBuilder("Invalid magic value:");
|
||||
for (int i=0; i<8; i++) {
|
||||
sb.append(String.format(" %02x", buf[i]));
|
||||
}
|
||||
throw new NotADexFile(sb.toString());
|
||||
}
|
||||
|
||||
int endian = HeaderItem.getEndian(buf, offset);
|
||||
if (endian == HeaderItem.BIG_ENDIAN_TAG) {
|
||||
throw new ExceptionWithContext("Big endian dex files are not currently supported");
|
||||
}
|
||||
|
||||
if (endian != HeaderItem.LITTLE_ENDIAN_TAG) {
|
||||
throw new ExceptionWithContext("Invalid endian tag: 0x%x", endian);
|
||||
}
|
||||
}
|
||||
|
||||
public int getStringIdItemOffset(int stringIndex) {
|
||||
if (stringIndex < 0 || stringIndex >= stringCount) {
|
||||
throw new ExceptionWithContext("String index out of bounds: %d", stringIndex);
|
||||
}
|
||||
return stringStartOffset + stringIndex*StringIdItem.ITEM_SIZE;
|
||||
}
|
||||
|
||||
public int getTypeIdItemOffset(int typeIndex) {
|
||||
if (typeIndex < 0 || typeIndex >= typeCount) {
|
||||
throw new ExceptionWithContext("Type index out of bounds: %d", typeIndex);
|
||||
}
|
||||
return typeStartOffset + typeIndex*TypeIdItem.ITEM_SIZE;
|
||||
}
|
||||
|
||||
public int getFieldIdItemOffset(int fieldIndex) {
|
||||
if (fieldIndex < 0 || fieldIndex >= fieldCount) {
|
||||
throw new ExceptionWithContext("Field index out of bounds: %d", fieldIndex);
|
||||
}
|
||||
return fieldStartOffset + fieldIndex*FieldIdItem.ITEM_SIZE;
|
||||
}
|
||||
|
||||
public int getMethodIdItemOffset(int methodIndex) {
|
||||
if (methodIndex < 0 || methodIndex >= methodCount) {
|
||||
throw new ExceptionWithContext("Method index out of bounds: %d", methodIndex);
|
||||
}
|
||||
return methodStartOffset + methodIndex*MethodIdItem.ITEM_SIZE;
|
||||
}
|
||||
|
||||
public int getProtoIdItemOffset(int protoIndex) {
|
||||
if (protoIndex < 0 || protoIndex >= protoCount) {
|
||||
throw new ExceptionWithContext("Proto index out of bounds: %d", protoIndex);
|
||||
}
|
||||
return protoStartOffset + protoIndex*ProtoIdItem.ITEM_SIZE;
|
||||
}
|
||||
|
||||
public int getClassDefItemOffset(int classIndex) {
|
||||
if (classIndex < 0 || classIndex >= classCount) {
|
||||
throw new ExceptionWithContext("Class index out of bounds: %d", classIndex);
|
||||
}
|
||||
return classStartOffset + classIndex*ClassDefItem.ITEM_SIZE;
|
||||
}
|
||||
|
||||
public int getClassCount() {
|
||||
return classCount;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getString(int stringIndex) {
|
||||
int stringOffset = getStringIdItemOffset(stringIndex);
|
||||
int stringDataOffset = readSmallUint(stringOffset);
|
||||
DexReader reader = readerAt(stringDataOffset);
|
||||
int utf16Length = reader.readSmallUleb128();
|
||||
return reader.readString(utf16Length);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getOptionalString(int stringIndex) {
|
||||
if (stringIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
return getString(stringIndex);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String getType(int typeIndex) {
|
||||
int typeOffset = getTypeIdItemOffset(typeIndex);
|
||||
int stringIndex = readSmallUint(typeOffset);
|
||||
return getString(stringIndex);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getOptionalType(int typeIndex) {
|
||||
if (typeIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
return getType(typeIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public DexReader readerAt(int offset) {
|
||||
return new DexReader(this, offset);
|
||||
}
|
||||
|
||||
public static class NotADexFile extends RuntimeException {
|
||||
public NotADexFile() {
|
||||
}
|
||||
|
||||
public NotADexFile(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public NotADexFile(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotADexFile(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.dexlib2.base.BaseExceptionHandler;
|
||||
|
||||
public abstract class DexBackedExceptionHandler extends BaseExceptionHandler {
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.dexlib2.base.reference.BaseFieldReference;
|
||||
import org.jf.dexlib2.dexbacked.raw.FieldIdItem;
|
||||
import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
|
||||
import org.jf.dexlib2.dexbacked.util.StaticInitialValueIterator;
|
||||
import org.jf.dexlib2.iface.ClassDef;
|
||||
import org.jf.dexlib2.iface.Field;
|
||||
import org.jf.dexlib2.iface.value.EncodedValue;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Set;
|
||||
|
||||
public class DexBackedField extends BaseFieldReference implements Field {
|
||||
@Nonnull public final DexBackedDexFile dexFile;
|
||||
@Nonnull public final ClassDef classDef;
|
||||
|
||||
public final int accessFlags;
|
||||
@Nullable public final EncodedValue initialValue;
|
||||
public final int annotationSetOffset;
|
||||
|
||||
public final int fieldIndex;
|
||||
|
||||
private int fieldIdItemOffset;
|
||||
|
||||
public DexBackedField(@Nonnull DexReader reader,
|
||||
@Nonnull DexBackedClassDef classDef,
|
||||
int previousFieldIndex,
|
||||
@Nonnull StaticInitialValueIterator staticInitialValueIterator,
|
||||
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
|
||||
this.dexFile = reader.dexBuf;
|
||||
this.classDef = classDef;
|
||||
|
||||
int fieldIndexDiff = reader.readSmallUleb128();
|
||||
this.fieldIndex = fieldIndexDiff + previousFieldIndex;
|
||||
this.accessFlags = reader.readSmallUleb128();
|
||||
|
||||
this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
|
||||
this.initialValue = staticInitialValueIterator.getNextOrNull();
|
||||
}
|
||||
|
||||
public DexBackedField(@Nonnull DexReader reader,
|
||||
@Nonnull DexBackedClassDef classDef,
|
||||
int previousFieldIndex,
|
||||
@Nonnull AnnotationsDirectory.AnnotationIterator annotationIterator) {
|
||||
this.dexFile = reader.dexBuf;
|
||||
this.classDef = classDef;
|
||||
|
||||
int fieldIndexDiff = reader.readSmallUleb128();
|
||||
this.fieldIndex = fieldIndexDiff + previousFieldIndex;
|
||||
this.accessFlags = reader.readSmallUleb128();
|
||||
|
||||
this.annotationSetOffset = annotationIterator.seekTo(fieldIndex);
|
||||
this.initialValue = null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getName() {
|
||||
return dexFile.getString(dexFile.readSmallUint(getFieldIdItemOffset() + FieldIdItem.NAME_OFFSET));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getType() {
|
||||
return dexFile.getType(dexFile.readUshort(getFieldIdItemOffset() + FieldIdItem.TYPE_OFFSET));
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
|
||||
@Override public int getAccessFlags() { return accessFlags; }
|
||||
@Nullable @Override public EncodedValue getInitialValue() { return initialValue; }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Set<? extends DexBackedAnnotation> getAnnotations() {
|
||||
return AnnotationsDirectory.getAnnotations(dexFile, annotationSetOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the reader over the specified number of encoded_field structures
|
||||
*
|
||||
* @param reader The reader to skip
|
||||
* @param count The number of encoded_field structures to skip over
|
||||
*/
|
||||
public static void skipFields(@Nonnull DexReader reader, int count) {
|
||||
for (int i=0; i<count; i++) {
|
||||
reader.skipUleb128();
|
||||
reader.skipUleb128();
|
||||
}
|
||||
}
|
||||
|
||||
private int getFieldIdItemOffset() {
|
||||
if (fieldIdItemOffset == 0) {
|
||||
fieldIdItemOffset = dexFile.getFieldIdItemOffset(fieldIndex);
|
||||
}
|
||||
return fieldIdItemOffset;
|
||||
}
|
||||
}
|
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterators;
|
||||
import org.jf.dexlib2.base.reference.BaseMethodReference;
|
||||
import org.jf.dexlib2.dexbacked.raw.MethodIdItem;
|
||||
import org.jf.dexlib2.dexbacked.raw.ProtoIdItem;
|
||||
import org.jf.dexlib2.dexbacked.raw.TypeListItem;
|
||||
import org.jf.dexlib2.dexbacked.util.AnnotationsDirectory;
|
||||
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||
import org.jf.dexlib2.dexbacked.util.ParameterIterator;
|
||||
import org.jf.dexlib2.iface.Annotation;
|
||||
import org.jf.dexlib2.iface.Method;
|
||||
import org.jf.dexlib2.iface.MethodParameter;
|
||||
import org.jf.util.AbstractForwardSequentialList;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class DexBackedMethod extends BaseMethodReference implements Method {
|
||||
@Nonnull public final DexBackedDexFile dexFile;
|
||||
@Nonnull public final DexBackedClassDef classDef;
|
||||
|
||||
public final int accessFlags;
|
||||
|
||||
private final int codeOffset;
|
||||
private final int parameterAnnotationSetListOffset;
|
||||
private final int methodAnnotationSetOffset;
|
||||
|
||||
public final int methodIndex;
|
||||
|
||||
private int methodIdItemOffset;
|
||||
private int protoIdItemOffset;
|
||||
private int parametersOffset = -1;
|
||||
|
||||
public DexBackedMethod(@Nonnull DexReader reader,
|
||||
@Nonnull DexBackedClassDef classDef,
|
||||
int previousMethodIndex) {
|
||||
this.dexFile = reader.dexBuf;
|
||||
this.classDef = classDef;
|
||||
|
||||
int methodIndexDiff = reader.readSmallUleb128();
|
||||
this.methodIndex = methodIndexDiff + previousMethodIndex;
|
||||
this.accessFlags = reader.readSmallUleb128();
|
||||
this.codeOffset = reader.readSmallUleb128();
|
||||
|
||||
this.methodAnnotationSetOffset = 0;
|
||||
this.parameterAnnotationSetListOffset = 0;
|
||||
}
|
||||
|
||||
public DexBackedMethod(@Nonnull DexReader reader,
|
||||
@Nonnull DexBackedClassDef classDef,
|
||||
int previousMethodIndex,
|
||||
@Nonnull AnnotationsDirectory.AnnotationIterator methodAnnotationIterator,
|
||||
@Nonnull AnnotationsDirectory.AnnotationIterator paramaterAnnotationIterator) {
|
||||
this.dexFile = reader.dexBuf;
|
||||
this.classDef = classDef;
|
||||
|
||||
int methodIndexDiff = reader.readSmallUleb128();
|
||||
this.methodIndex = methodIndexDiff + previousMethodIndex;
|
||||
this.accessFlags = reader.readSmallUleb128();
|
||||
this.codeOffset = reader.readSmallUleb128();
|
||||
|
||||
this.methodAnnotationSetOffset = methodAnnotationIterator.seekTo(methodIndex);
|
||||
this.parameterAnnotationSetListOffset = paramaterAnnotationIterator.seekTo(methodIndex);
|
||||
}
|
||||
|
||||
public int getMethodIndex() { return methodIndex; }
|
||||
@Nonnull @Override public String getDefiningClass() { return classDef.getType(); }
|
||||
@Override public int getAccessFlags() { return accessFlags; }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getName() {
|
||||
return dexFile.getString(dexFile.readSmallUint(getMethodIdItemOffset() + MethodIdItem.NAME_OFFSET));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public String getReturnType() {
|
||||
return dexFile.getType(dexFile.readSmallUint(getProtoIdItemOffset() + ProtoIdItem.RETURN_TYPE_OFFSET));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<? extends MethodParameter> getParameters() {
|
||||
int parametersOffset = getParametersOffset();
|
||||
if (parametersOffset > 0) {
|
||||
final List<String> parameterTypes = getParameterTypes();
|
||||
|
||||
return new AbstractForwardSequentialList<MethodParameter>() {
|
||||
@Nonnull @Override public Iterator<MethodParameter> iterator() {
|
||||
return new ParameterIterator(parameterTypes,
|
||||
getParameterAnnotations(),
|
||||
getParameterNames());
|
||||
}
|
||||
|
||||
@Override public int size() {
|
||||
return parameterTypes.size();
|
||||
}
|
||||
};
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<? extends Set<? extends DexBackedAnnotation>> getParameterAnnotations() {
|
||||
return AnnotationsDirectory.getParameterAnnotations(dexFile, parameterAnnotationSetListOffset);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Iterator<String> getParameterNames() {
|
||||
DexBackedMethodImplementation methodImpl = getImplementation();
|
||||
if (methodImpl != null) {
|
||||
return methodImpl.getParameterNames(null);
|
||||
}
|
||||
return Iterators.emptyIterator();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<String> getParameterTypes() {
|
||||
final int parametersOffset = getParametersOffset();
|
||||
if (parametersOffset > 0) {
|
||||
final int parameterCount = dexFile.readSmallUint(parametersOffset + TypeListItem.SIZE_OFFSET);
|
||||
final int paramListStart = parametersOffset + TypeListItem.LIST_OFFSET;
|
||||
return new FixedSizeList<String>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public String readItem(final int index) {
|
||||
return dexFile.getType(dexFile.readUshort(paramListStart + 2*index));
|
||||
}
|
||||
@Override public int size() { return parameterCount; }
|
||||
};
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Set<? extends Annotation> getAnnotations() {
|
||||
return AnnotationsDirectory.getAnnotations(dexFile, methodAnnotationSetOffset);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public DexBackedMethodImplementation getImplementation() {
|
||||
if (codeOffset > 0) {
|
||||
return new DexBackedMethodImplementation(dexFile, this, codeOffset);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int getMethodIdItemOffset() {
|
||||
if (methodIdItemOffset == 0) {
|
||||
methodIdItemOffset = dexFile.getMethodIdItemOffset(methodIndex);
|
||||
}
|
||||
return methodIdItemOffset;
|
||||
}
|
||||
|
||||
private int getProtoIdItemOffset() {
|
||||
if (protoIdItemOffset == 0) {
|
||||
int protoIndex = dexFile.readUshort(getMethodIdItemOffset() + MethodIdItem.PROTO_OFFSET);
|
||||
protoIdItemOffset = dexFile.getProtoIdItemOffset(protoIndex);
|
||||
}
|
||||
return protoIdItemOffset;
|
||||
}
|
||||
|
||||
private int getParametersOffset() {
|
||||
if (parametersOffset == -1) {
|
||||
parametersOffset = dexFile.readSmallUint(getProtoIdItemOffset() + ProtoIdItem.PARAMETERS_OFFSET);
|
||||
}
|
||||
return parametersOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips the reader over the specified number of encoded_method structures
|
||||
*
|
||||
* @param reader The reader to skip
|
||||
* @param count The number of encoded_method structures to skip over
|
||||
*/
|
||||
public static void skipMethods(@Nonnull DexReader reader, int count) {
|
||||
for (int i=0; i<count; i++) {
|
||||
reader.skipUleb128();
|
||||
reader.skipUleb128();
|
||||
reader.skipUleb128();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.jf.dexlib2.dexbacked.instruction.DexBackedInstruction;
|
||||
import org.jf.dexlib2.dexbacked.raw.CodeItem;
|
||||
import org.jf.dexlib2.dexbacked.util.DebugInfo;
|
||||
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||
import org.jf.dexlib2.dexbacked.util.VariableSizeLookaheadIterator;
|
||||
import org.jf.dexlib2.iface.MethodImplementation;
|
||||
import org.jf.dexlib2.iface.debug.DebugItem;
|
||||
import org.jf.dexlib2.iface.instruction.Instruction;
|
||||
import org.jf.util.AlignmentUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class DexBackedMethodImplementation implements MethodImplementation {
|
||||
@Nonnull public final DexBackedDexFile dexFile;
|
||||
@Nonnull public final DexBackedMethod method;
|
||||
private final int codeOffset;
|
||||
|
||||
public DexBackedMethodImplementation(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull DexBackedMethod method,
|
||||
int codeOffset) {
|
||||
this.dexFile = dexFile;
|
||||
this.method = method;
|
||||
this.codeOffset = codeOffset;
|
||||
}
|
||||
|
||||
@Override public int getRegisterCount() { return dexFile.readUshort(codeOffset); }
|
||||
|
||||
@Nonnull @Override public Iterable<? extends Instruction> getInstructions() {
|
||||
// instructionsSize is the number of 16-bit code units in the instruction list, not the number of instructions
|
||||
int instructionsSize = dexFile.readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET);
|
||||
|
||||
final int instructionsStartOffset = codeOffset + CodeItem.INSTRUCTION_START_OFFSET;
|
||||
final int endOffset = instructionsStartOffset + (instructionsSize*2);
|
||||
return new Iterable<Instruction>() {
|
||||
@Override
|
||||
public Iterator<Instruction> iterator() {
|
||||
return new VariableSizeLookaheadIterator<Instruction>(dexFile, instructionsStartOffset) {
|
||||
@Override
|
||||
protected Instruction readNextItem(@Nonnull DexReader reader) {
|
||||
if (reader.getOffset() >= endOffset) {
|
||||
return null;
|
||||
}
|
||||
return DexBackedInstruction.readFrom(reader);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<? extends DexBackedTryBlock> getTryBlocks() {
|
||||
final int triesSize = dexFile.readUshort(codeOffset + CodeItem.TRIES_SIZE_OFFSET);
|
||||
if (triesSize > 0) {
|
||||
int instructionsSize = dexFile.readSmallUint(codeOffset + CodeItem.INSTRUCTION_COUNT_OFFSET);
|
||||
final int triesStartOffset = AlignmentUtils.alignOffset(
|
||||
codeOffset + CodeItem.INSTRUCTION_START_OFFSET + (instructionsSize*2), 4);
|
||||
final int handlersStartOffset = triesStartOffset + triesSize*CodeItem.TryItem.ITEM_SIZE;
|
||||
|
||||
return new FixedSizeList<DexBackedTryBlock>() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public DexBackedTryBlock readItem(int index) {
|
||||
return new DexBackedTryBlock(dexFile,
|
||||
triesStartOffset + index*CodeItem.TryItem.ITEM_SIZE,
|
||||
handlersStartOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return triesSize;
|
||||
}
|
||||
};
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private DebugInfo getDebugInfo() {
|
||||
return DebugInfo.newOrEmpty(dexFile, dexFile.readSmallUint(codeOffset + CodeItem.DEBUG_INFO_OFFSET), this);
|
||||
}
|
||||
|
||||
@Nonnull @Override
|
||||
public Iterable<? extends DebugItem> getDebugItems() {
|
||||
return getDebugInfo();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Iterator<String> getParameterNames(@Nullable DexReader dexReader) {
|
||||
return getDebugInfo().getParameterNames(dexReader);
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.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;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.List;
|
||||
|
||||
public class DexBackedOdexFile extends DexBackedDexFile {
|
||||
private static final int DEPENDENCY_COUNT_OFFSET = 12;
|
||||
private static final int DEPENDENCY_START_OFFSET = 16;
|
||||
|
||||
private final byte[] odexBuf;
|
||||
|
||||
|
||||
public DexBackedOdexFile(@Nonnull Opcodes opcodes, @Nonnull byte[] odexBuf, byte[] dexBuf) {
|
||||
super(opcodes, dexBuf);
|
||||
|
||||
this.odexBuf = odexBuf;
|
||||
}
|
||||
|
||||
@Override public boolean isOdexFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<String> getDependencies() {
|
||||
final int dexOffset = OdexHeaderItem.getDexOffset(odexBuf);
|
||||
final int dependencyOffset = OdexHeaderItem.getDependenciesOffset(odexBuf) - dexOffset;
|
||||
|
||||
BaseDexBuffer buf = new BaseDexBuffer(this.buf);
|
||||
int dependencyCount = buf.readInt(dependencyOffset + DEPENDENCY_COUNT_OFFSET);
|
||||
|
||||
return new VariableSizeList<String>(this, dependencyOffset + DEPENDENCY_START_OFFSET, dependencyCount) {
|
||||
@Override protected String readNextItem(@Nonnull DexReader reader, int index) {
|
||||
int length = reader.readInt();
|
||||
int offset = reader.getOffset();
|
||||
reader.moveRelative(length + 20);
|
||||
try {
|
||||
return new String(DexBackedOdexFile.this.buf, offset, length-1, "US-ASCII");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static DexBackedOdexFile fromInputStream(@Nonnull Opcodes opcodes, @Nonnull InputStream is)
|
||||
throws IOException {
|
||||
if (!is.markSupported()) {
|
||||
throw new IllegalArgumentException("InputStream must support mark");
|
||||
}
|
||||
is.mark(8);
|
||||
byte[] partialHeader = new byte[8];
|
||||
try {
|
||||
ByteStreams.readFully(is, partialHeader);
|
||||
} catch (EOFException ex) {
|
||||
throw new NotADexFile("File is too short");
|
||||
} finally {
|
||||
is.reset();
|
||||
}
|
||||
|
||||
verifyMagic(partialHeader);
|
||||
|
||||
is.reset();
|
||||
byte[] odexBuf = new byte[OdexHeaderItem.ITEM_SIZE];
|
||||
ByteStreams.readFully(is, odexBuf);
|
||||
int dexOffset = OdexHeaderItem.getDexOffset(odexBuf);
|
||||
if (dexOffset > OdexHeaderItem.ITEM_SIZE) {
|
||||
ByteStreams.skipFully(is, dexOffset - OdexHeaderItem.ITEM_SIZE);
|
||||
}
|
||||
|
||||
byte[] dexBuf = ByteStreams.toByteArray(is);
|
||||
|
||||
return new DexBackedOdexFile(opcodes, odexBuf, dexBuf);
|
||||
}
|
||||
|
||||
private static void verifyMagic(byte[] buf) {
|
||||
if (!OdexHeaderItem.verifyMagic(buf)) {
|
||||
StringBuilder sb = new StringBuilder("Invalid magic value:");
|
||||
for (int i=0; i<8; i++) {
|
||||
sb.append(String.format(" %02x", buf[i]));
|
||||
}
|
||||
throw new NotAnOdexFile(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public int getOdexVersion() {
|
||||
return OdexHeaderItem.getVersion(odexBuf);
|
||||
}
|
||||
|
||||
public static class NotAnOdexFile extends RuntimeException {
|
||||
public NotAnOdexFile() {
|
||||
}
|
||||
|
||||
public NotAnOdexFile(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public NotAnOdexFile(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public NotAnOdexFile(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import org.jf.dexlib2.base.BaseTryBlock;
|
||||
import org.jf.dexlib2.dexbacked.raw.CodeItem;
|
||||
import org.jf.dexlib2.dexbacked.util.VariableSizeList;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
public class DexBackedTryBlock extends BaseTryBlock<DexBackedExceptionHandler> {
|
||||
@Nonnull public final DexBackedDexFile dexFile;
|
||||
private final int tryItemOffset;
|
||||
private final int handlersStartOffset;
|
||||
|
||||
public DexBackedTryBlock(@Nonnull DexBackedDexFile dexFile,
|
||||
int tryItemOffset,
|
||||
int handlersStartOffset) {
|
||||
this.dexFile = dexFile;
|
||||
this.tryItemOffset = tryItemOffset;
|
||||
this.handlersStartOffset = handlersStartOffset;
|
||||
}
|
||||
|
||||
@Override public int getStartCodeAddress() {
|
||||
return dexFile.readSmallUint(tryItemOffset + CodeItem.TryItem.START_ADDRESS_OFFSET);
|
||||
}
|
||||
|
||||
@Override public int getCodeUnitCount() {
|
||||
return dexFile.readUshort(tryItemOffset + CodeItem.TryItem.CODE_UNIT_COUNT_OFFSET);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<? extends DexBackedExceptionHandler> getExceptionHandlers() {
|
||||
DexReader reader = dexFile.readerAt(
|
||||
handlersStartOffset + dexFile.readUshort(tryItemOffset + CodeItem.TryItem.HANDLER_OFFSET));
|
||||
final int encodedSize = reader.readSleb128();
|
||||
|
||||
if (encodedSize > 0) {
|
||||
//no catch-all
|
||||
return new VariableSizeList<DexBackedTypedExceptionHandler>(dexFile, reader.getOffset(), encodedSize) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected DexBackedTypedExceptionHandler readNextItem(@Nonnull DexReader reader, int index) {
|
||||
return new DexBackedTypedExceptionHandler(reader);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
//with catch-all
|
||||
final int sizeWithCatchAll = (-1 * encodedSize) + 1;
|
||||
return new VariableSizeList<DexBackedExceptionHandler>(dexFile, reader.getOffset(), sizeWithCatchAll) {
|
||||
@Nonnull
|
||||
@Override
|
||||
protected DexBackedExceptionHandler readNextItem(@Nonnull DexReader dexReader, int index) {
|
||||
if (index == sizeWithCatchAll-1) {
|
||||
return new DexBackedCatchAllExceptionHandler(dexReader);
|
||||
} else {
|
||||
return new DexBackedTypedExceptionHandler(dexReader);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedTypedExceptionHandler extends DexBackedExceptionHandler {
|
||||
@Nonnull private final DexBackedDexFile dexFile;
|
||||
private final int typeId;
|
||||
private final int handlerCodeAddress;
|
||||
|
||||
public DexBackedTypedExceptionHandler(@Nonnull DexReader reader) {
|
||||
this.dexFile = reader.dexBuf;
|
||||
this.typeId = reader.readSmallUleb128();
|
||||
this.handlerCodeAddress = reader.readSmallUleb128();
|
||||
}
|
||||
|
||||
@Nonnull @Override public String getExceptionType() { return dexFile.getType(typeId); }
|
||||
@Override public int getHandlerCodeAddress() { return handlerCodeAddress; }
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexReader extends BaseDexReader<DexBackedDexFile> {
|
||||
public DexReader(@Nonnull DexBackedDexFile dexFile, int offset) {
|
||||
super(dexFile, offset);
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.dexbacked.util.FixedSizeList;
|
||||
import org.jf.dexlib2.iface.instruction.formats.ArrayPayload;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
public class DexBackedArrayPayload extends DexBackedInstruction implements ArrayPayload {
|
||||
public static final Opcode OPCODE = Opcode.ARRAY_PAYLOAD;
|
||||
|
||||
public final int elementWidth;
|
||||
public final int elementCount;
|
||||
|
||||
private static final int ELEMENT_WIDTH_OFFSET = 2;
|
||||
private static final int ELEMENT_COUNT_OFFSET = 4;
|
||||
private static final int ELEMENTS_OFFSET = 8;
|
||||
|
||||
public DexBackedArrayPayload(@Nonnull DexBackedDexFile dexFile,
|
||||
int instructionStart) {
|
||||
super(dexFile, OPCODE, instructionStart);
|
||||
|
||||
elementWidth = dexFile.readUshort(instructionStart + ELEMENT_WIDTH_OFFSET);
|
||||
elementCount = dexFile.readSmallUint(instructionStart + ELEMENT_COUNT_OFFSET);
|
||||
}
|
||||
|
||||
@Override public int getElementWidth() { return elementWidth; }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<Number> getArrayElements() {
|
||||
final int elementsStart = instructionStart + ELEMENTS_OFFSET;
|
||||
|
||||
abstract class ReturnedList extends FixedSizeList<Number> {
|
||||
@Override public int size() { return elementCount; }
|
||||
}
|
||||
|
||||
switch (elementWidth) {
|
||||
case 1:
|
||||
return new ReturnedList() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Number readItem(int index) {
|
||||
return dexFile.readByte(elementsStart + index);
|
||||
}
|
||||
};
|
||||
case 2:
|
||||
return new ReturnedList() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Number readItem(int index) {
|
||||
return dexFile.readShort(elementsStart + index*2);
|
||||
}
|
||||
};
|
||||
case 4:
|
||||
return new ReturnedList() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Number readItem(int index) {
|
||||
return dexFile.readInt(elementsStart + index*4);
|
||||
}
|
||||
};
|
||||
case 8:
|
||||
return new ReturnedList() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Number readItem(int index) {
|
||||
return dexFile.readLong(elementsStart + index*8);
|
||||
}
|
||||
};
|
||||
default:
|
||||
throw new ExceptionWithContext("Invalid element width: %d", elementWidth);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCodeUnits() {
|
||||
return 4 + (elementWidth*elementCount + 1) / 2;
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.dexbacked.DexReader;
|
||||
import org.jf.dexlib2.iface.instruction.Instruction;
|
||||
import org.jf.util.ExceptionWithContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class DexBackedInstruction implements Instruction {
|
||||
@Nonnull public final DexBackedDexFile dexFile;
|
||||
@Nonnull public final Opcode opcode;
|
||||
public final int instructionStart;
|
||||
|
||||
public DexBackedInstruction(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
this.dexFile = dexFile;
|
||||
this.opcode = opcode;
|
||||
this.instructionStart = instructionStart;
|
||||
}
|
||||
|
||||
@Nonnull public Opcode getOpcode() { return opcode; }
|
||||
@Override public int getCodeUnits() { return opcode.format.size / 2; }
|
||||
|
||||
@Nonnull
|
||||
public static Instruction readFrom(@Nonnull DexReader reader) {
|
||||
int opcodeValue = reader.peekUbyte();
|
||||
|
||||
if (opcodeValue == 0) {
|
||||
opcodeValue = reader.peekUshort();
|
||||
}
|
||||
|
||||
Opcode opcode = reader.dexBuf.getOpcodes().getOpcodeByValue(opcodeValue);
|
||||
|
||||
Instruction instruction = buildInstruction(reader.dexBuf, opcode, reader.getOffset());
|
||||
reader.moveRelative(instruction.getCodeUnits()*2);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
private static DexBackedInstruction buildInstruction(@Nonnull DexBackedDexFile dexFile, @Nullable Opcode opcode,
|
||||
int instructionStartOffset) {
|
||||
if (opcode == null) {
|
||||
return new DexBackedUnknownInstruction(dexFile, instructionStartOffset);
|
||||
}
|
||||
switch (opcode.format) {
|
||||
case Format10t:
|
||||
return new DexBackedInstruction10t(dexFile, opcode, instructionStartOffset);
|
||||
case Format10x:
|
||||
return new DexBackedInstruction10x(dexFile, opcode, instructionStartOffset);
|
||||
case Format11n:
|
||||
return new DexBackedInstruction11n(dexFile, opcode, instructionStartOffset);
|
||||
case Format11x:
|
||||
return new DexBackedInstruction11x(dexFile, opcode, instructionStartOffset);
|
||||
case Format12x:
|
||||
return new DexBackedInstruction12x(dexFile, opcode, instructionStartOffset);
|
||||
case Format20bc:
|
||||
return new DexBackedInstruction20bc(dexFile, opcode, instructionStartOffset);
|
||||
case Format20t:
|
||||
return new DexBackedInstruction20t(dexFile, opcode, instructionStartOffset);
|
||||
case Format21c:
|
||||
return new DexBackedInstruction21c(dexFile, opcode, instructionStartOffset);
|
||||
case Format21ih:
|
||||
return new DexBackedInstruction21ih(dexFile, opcode, instructionStartOffset);
|
||||
case Format21lh:
|
||||
return new DexBackedInstruction21lh(dexFile, opcode, instructionStartOffset);
|
||||
case Format21s:
|
||||
return new DexBackedInstruction21s(dexFile, opcode, instructionStartOffset);
|
||||
case Format21t:
|
||||
return new DexBackedInstruction21t(dexFile, opcode, instructionStartOffset);
|
||||
case Format22b:
|
||||
return new DexBackedInstruction22b(dexFile, opcode, instructionStartOffset);
|
||||
case Format22c:
|
||||
return new DexBackedInstruction22c(dexFile, opcode, instructionStartOffset);
|
||||
case Format22cs:
|
||||
return new DexBackedInstruction22cs(dexFile, opcode, instructionStartOffset);
|
||||
case Format22s:
|
||||
return new DexBackedInstruction22s(dexFile, opcode, instructionStartOffset);
|
||||
case Format22t:
|
||||
return new DexBackedInstruction22t(dexFile, opcode, instructionStartOffset);
|
||||
case Format22x:
|
||||
return new DexBackedInstruction22x(dexFile, opcode, instructionStartOffset);
|
||||
case Format23x:
|
||||
return new DexBackedInstruction23x(dexFile, opcode, instructionStartOffset);
|
||||
case Format30t:
|
||||
return new DexBackedInstruction30t(dexFile, opcode, instructionStartOffset);
|
||||
case Format31c:
|
||||
return new DexBackedInstruction31c(dexFile, opcode, instructionStartOffset);
|
||||
case Format31i:
|
||||
return new DexBackedInstruction31i(dexFile, opcode, instructionStartOffset);
|
||||
case Format31t:
|
||||
return new DexBackedInstruction31t(dexFile, opcode, instructionStartOffset);
|
||||
case Format32x:
|
||||
return new DexBackedInstruction32x(dexFile, opcode, instructionStartOffset);
|
||||
case Format35c:
|
||||
return new DexBackedInstruction35c(dexFile, opcode, instructionStartOffset);
|
||||
case Format35ms:
|
||||
return new DexBackedInstruction35ms(dexFile, opcode, instructionStartOffset);
|
||||
case Format35mi:
|
||||
return new DexBackedInstruction35mi(dexFile, opcode, instructionStartOffset);
|
||||
case Format3rc:
|
||||
return new DexBackedInstruction3rc(dexFile, opcode, instructionStartOffset);
|
||||
case Format3rmi:
|
||||
return new DexBackedInstruction3rmi(dexFile, opcode, instructionStartOffset);
|
||||
case Format3rms:
|
||||
return new DexBackedInstruction3rms(dexFile, opcode, instructionStartOffset);
|
||||
case Format51l:
|
||||
return new DexBackedInstruction51l(dexFile, opcode, instructionStartOffset);
|
||||
case PackedSwitchPayload:
|
||||
return new DexBackedPackedSwitchPayload(dexFile, instructionStartOffset);
|
||||
case SparseSwitchPayload:
|
||||
return new DexBackedSparseSwitchPayload(dexFile, instructionStartOffset);
|
||||
case ArrayPayload:
|
||||
return new DexBackedArrayPayload(dexFile, instructionStartOffset);
|
||||
default:
|
||||
throw new ExceptionWithContext("Unexpected opcode format: %s", opcode.format.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction10t;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction10t extends DexBackedInstruction implements Instruction10t {
|
||||
public DexBackedInstruction10t(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getCodeOffset() { return dexFile.readByte(instructionStart + 1); }
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction10x;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction10x extends DexBackedInstruction implements Instruction10x {
|
||||
public DexBackedInstruction10x(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction11n;
|
||||
import org.jf.util.NibbleUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction11n extends DexBackedInstruction implements Instruction11n {
|
||||
public DexBackedInstruction11n(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterA() {
|
||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNarrowLiteral() {
|
||||
return NibbleUtils.extractHighSignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction11x;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction11x extends DexBackedInstruction implements Instruction11x {
|
||||
public DexBackedInstruction11x(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction12x;
|
||||
import org.jf.util.NibbleUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction12x extends DexBackedInstruction implements Instruction12x {
|
||||
public DexBackedInstruction12x(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterA() {
|
||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterB() {
|
||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.dexbacked.reference.DexBackedReference;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction20bc;
|
||||
import org.jf.dexlib2.iface.reference.Reference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction20bc extends DexBackedInstruction implements Instruction20bc {
|
||||
public DexBackedInstruction20bc(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getVerificationError() { return dexFile.readUbyte(instructionStart + 1) & 0x3f; }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Reference getReference() {
|
||||
int refType = (dexFile.readUbyte(instructionStart + 1) >>> 6) + 1;
|
||||
return DexBackedReference.makeReference(dexFile, refType, dexFile.readUshort(instructionStart + 2));
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction20t;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction20t extends DexBackedInstruction implements Instruction20t {
|
||||
public DexBackedInstruction20t(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getCodeOffset() { return dexFile.readShort(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.dexbacked.reference.DexBackedReference;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21c;
|
||||
import org.jf.dexlib2.iface.reference.Reference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction21c extends DexBackedInstruction implements Instruction21c {
|
||||
public DexBackedInstruction21c(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Reference getReference() {
|
||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType, dexFile.readUshort(instructionStart + 2));
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21ih;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction21ih extends DexBackedInstruction implements Instruction21ih {
|
||||
public DexBackedInstruction21ih(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getNarrowLiteral() { return getHatLiteral() << 16; }
|
||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||
@Override public short getHatLiteral() { return (short)dexFile.readShort(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21lh;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction21lh extends DexBackedInstruction implements Instruction21lh {
|
||||
public DexBackedInstruction21lh(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public long getWideLiteral() { return ((long)getHatLiteral()) << 48; }
|
||||
@Override public short getHatLiteral() { return (short)dexFile.readShort(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21s;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction21s extends DexBackedInstruction implements Instruction21s {
|
||||
public DexBackedInstruction21s(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getNarrowLiteral() { return dexFile.readShort(instructionStart + 2); }
|
||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction21t;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction21t extends DexBackedInstruction implements Instruction21t {
|
||||
public DexBackedInstruction21t(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getCodeOffset() { return dexFile.readShort(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22b;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction22b extends DexBackedInstruction implements Instruction22b {
|
||||
public DexBackedInstruction22b(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getRegisterB() { return dexFile.readUbyte(instructionStart + 2); }
|
||||
@Override public int getNarrowLiteral() { return dexFile.readByte(instructionStart + 3); }
|
||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.dexbacked.reference.DexBackedReference;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22c;
|
||||
import org.jf.dexlib2.iface.reference.Reference;
|
||||
import org.jf.util.NibbleUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction22c extends DexBackedInstruction implements Instruction22c {
|
||||
public DexBackedInstruction22c(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterA() {
|
||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterB() {
|
||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Reference getReference() {
|
||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType, dexFile.readUshort(instructionStart + 2));
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22cs;
|
||||
import org.jf.util.NibbleUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction22cs extends DexBackedInstruction implements Instruction22cs {
|
||||
public DexBackedInstruction22cs(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterA() {
|
||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterB() {
|
||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFieldOffset() {
|
||||
return dexFile.readUshort(instructionStart + 2);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22s;
|
||||
import org.jf.util.NibbleUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction22s extends DexBackedInstruction implements Instruction22s {
|
||||
public DexBackedInstruction22s(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterA() {
|
||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterB() {
|
||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override public int getNarrowLiteral() { return dexFile.readShort(instructionStart + 2); }
|
||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22t;
|
||||
import org.jf.util.NibbleUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction22t extends DexBackedInstruction implements Instruction22t {
|
||||
public DexBackedInstruction22t(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterA() {
|
||||
return NibbleUtils.extractLowUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegisterB() {
|
||||
return NibbleUtils.extractHighUnsignedNibble(dexFile.readByte(instructionStart + 1));
|
||||
}
|
||||
|
||||
@Override public int getCodeOffset() { return dexFile.readShort(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction22x;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction22x extends DexBackedInstruction implements Instruction22x {
|
||||
public DexBackedInstruction22x(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getRegisterB() { return dexFile.readUshort(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction23x;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction23x extends DexBackedInstruction implements Instruction23x {
|
||||
public DexBackedInstruction23x(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getRegisterB() { return dexFile.readUbyte(instructionStart + 2); }
|
||||
@Override public int getRegisterC() { return dexFile.readUbyte(instructionStart + 3); }
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction30t;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction30t extends DexBackedInstruction implements Instruction30t {
|
||||
public DexBackedInstruction30t(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getCodeOffset() { return dexFile.readInt(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.dexbacked.reference.DexBackedReference;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction31c;
|
||||
import org.jf.dexlib2.iface.reference.Reference;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction31c extends DexBackedInstruction implements Instruction31c {
|
||||
public DexBackedInstruction31c(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Reference getReference() {
|
||||
return DexBackedReference.makeReference(dexFile, opcode.referenceType,
|
||||
dexFile.readSmallUint(instructionStart + 2));
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction31i;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction31i extends DexBackedInstruction implements Instruction31i {
|
||||
public DexBackedInstruction31i(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getNarrowLiteral() { return dexFile.readInt(instructionStart + 2); }
|
||||
@Override public long getWideLiteral() { return getNarrowLiteral(); }
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction31t;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction31t extends DexBackedInstruction implements Instruction31t {
|
||||
public DexBackedInstruction31t(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUbyte(instructionStart + 1); }
|
||||
@Override public int getCodeOffset() { return dexFile.readInt(instructionStart + 2); }
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2012, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.dexlib2.dexbacked.instruction;
|
||||
|
||||
import org.jf.dexlib2.Opcode;
|
||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import org.jf.dexlib2.iface.instruction.formats.Instruction32x;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class DexBackedInstruction32x extends DexBackedInstruction implements Instruction32x {
|
||||
public DexBackedInstruction32x(@Nonnull DexBackedDexFile dexFile,
|
||||
@Nonnull Opcode opcode,
|
||||
int instructionStart) {
|
||||
super(dexFile, opcode, instructionStart);
|
||||
}
|
||||
|
||||
@Override public int getRegisterA() { return dexFile.readUshort(instructionStart + 2); }
|
||||
@Override public int getRegisterB() { return dexFile.readUshort(instructionStart + 4); }
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user