Update to smali 2b5

This commit is contained in:
Connor Tumbleson
2013-06-20 08:03:20 -05:00
parent 115db91fab
commit 007a6d45a2
596 changed files with 54475 additions and 5112 deletions

View File

@ -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());
}
}
}
}
}

View File

@ -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;
}
}

View File

@ -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() {}
}

View File

@ -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() {}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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];
}
}
}

View File

@ -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() {}
}

View File

@ -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() {}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
});
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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];
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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());
}
}

View File

@ -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";
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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());
}
};
}

View File

@ -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());
}
};
}

View File

@ -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());
}
}
};
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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(); }
}

View File

@ -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(); }
}

View File

@ -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;
}
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
};
}
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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 {
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
};
}
}
}

View File

@ -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; }
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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());
}
}
}

View File

@ -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); }
}

View File

@ -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);
}
}

View File

@ -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(); }
}

View File

@ -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); }
}

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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); }
}

View File

@ -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));
}
}

View File

@ -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); }
}

View File

@ -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); }
}

View File

@ -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(); }
}

View File

@ -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); }
}

View File

@ -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(); }
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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(); }
}

View File

@ -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); }
}

View File

@ -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); }
}

View File

@ -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); }
}

View File

@ -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); }
}

View File

@ -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));
}
}

View File

@ -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(); }
}

View File

@ -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); }
}

View File

@ -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