use of org.jf.dexlib2.iface.DexFile in project smali by JesusFreke.
the class FieldGapOrderTest method testOldOrder.
@Test
public void testOldOrder() {
DexFile dexFile = getInputDexFile("FieldGapOrder", new BaksmaliOptions());
Assert.assertEquals(3, dexFile.getClasses().size());
ClassPath classPath = new ClassPath(Lists.newArrayList(new DexClassProvider(dexFile)), false, 66);
ClassProto classProto = (ClassProto) classPath.getClass("LGapOrder;");
Assert.assertEquals("r1", classProto.getFieldByOffset(12).getName());
Assert.assertEquals("r2", classProto.getFieldByOffset(16).getName());
Assert.assertEquals("d", classProto.getFieldByOffset(24).getName());
Assert.assertEquals("s", classProto.getFieldByOffset(36).getName());
Assert.assertEquals("i", classProto.getFieldByOffset(32).getName());
}
use of org.jf.dexlib2.iface.DexFile in project smali by JesusFreke.
the class DexFileFactory method loadDexContainer.
/**
* Loads a file containing 1 or more dex files
*
* If the given file is a dex or odex file, it will return a MultiDexContainer containing that single entry.
* Otherwise, for an oat or zip file, it will return an OatFile or ZipDexContainer respectively.
*
* @param file The file to open
* @param opcodes The set of opcodes to use
* @return A MultiDexContainer
* @throws DexFileNotFoundException If the given file does not exist
* @throws UnsupportedFileTypeException If the given file is not a valid dex/zip/odex/oat file
*/
public static MultiDexContainer<? extends DexBackedDexFile> loadDexContainer(@Nonnull File file, @Nonnull final Opcodes opcodes) throws IOException {
if (!file.exists()) {
throw new DexFileNotFoundException("%s does not exist", file.getName());
}
ZipDexContainer zipDexContainer = new ZipDexContainer(file, opcodes);
if (zipDexContainer.isZipFile()) {
return zipDexContainer;
}
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
try {
try {
DexBackedDexFile dexFile = DexBackedDexFile.fromInputStream(opcodes, inputStream);
return new SingletonMultiDexContainer(file.getPath(), dexFile);
} catch (DexBackedDexFile.NotADexFile ex) {
// just eat it
}
try {
DexBackedOdexFile odexFile = DexBackedOdexFile.fromInputStream(opcodes, inputStream);
return new SingletonMultiDexContainer(file.getPath(), odexFile);
} catch (DexBackedOdexFile.NotAnOdexFile ex) {
// just eat it
}
// Note: DexBackedDexFile.fromInputStream and DexBackedOdexFile.fromInputStream will reset inputStream
// back to the same position, if they fails
OatFile oatFile = null;
try {
oatFile = OatFile.fromInputStream(inputStream);
} catch (NotAnOatFileException ex) {
// just eat it
}
if (oatFile != null) {
// TODO: we should support loading earlier oat files, just not deodexing them
if (oatFile.isSupportedVersion() == OatFile.UNSUPPORTED) {
throw new UnsupportedOatVersionException(oatFile);
}
return oatFile;
}
} finally {
inputStream.close();
}
throw new UnsupportedFileTypeException("%s is not an apk, dex, odex or oat file.", file.getPath());
}
use of org.jf.dexlib2.iface.DexFile in project smali by JesusFreke.
the class DexBackedClassDef method getInstanceFields.
@Nonnull
public Iterable<? extends DexBackedField> getInstanceFields(final boolean skipDuplicates) {
if (instanceFieldCount > 0) {
DexReader reader = dexFile.readerAt(getInstanceFieldsOffset());
final AnnotationsDirectory annotationsDirectory = getAnnotationsDirectory();
final int fieldsStartOffset = reader.getOffset();
return new Iterable<DexBackedField>() {
@Nonnull
@Override
public Iterator<DexBackedField> iterator() {
final AnnotationsDirectory.AnnotationIterator annotationIterator = annotationsDirectory.getFieldAnnotationIterator();
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 endOfData();
}
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();
}
}
use of org.jf.dexlib2.iface.DexFile in project smali by JesusFreke.
the class DexBackedMethodImplementation method getInstructions.
@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 endOfData();
}
Instruction instruction = DexBackedInstruction.readFrom(reader);
// Does the instruction extend past the end of the method?
int offset = reader.getOffset();
if (offset > endOffset || offset < 0) {
throw new ExceptionWithContext("The last instruction in method %s is truncated", method);
}
return instruction;
}
};
}
};
}
use of org.jf.dexlib2.iface.DexFile in project smali by JesusFreke.
the class ClassDataItem method makeAnnotator.
@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
return new SectionAnnotator(annotator, mapItem) {
private SectionAnnotator codeItemAnnotator = null;
@Override
public void annotateSection(@Nonnull AnnotatedBytes out) {
codeItemAnnotator = annotator.getAnnotator(ItemType.CODE_ITEM);
super.annotateSection(out);
}
@Nonnull
@Override
public String getItemName() {
return "class_data_item";
}
@Override
protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
DexReader reader = dexFile.readerAt(out.getCursor());
int staticFieldsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "static_fields_size = %d", staticFieldsSize);
int instanceFieldsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "instance_fields_size = %d", instanceFieldsSize);
int directMethodsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "direct_methods_size = %d", directMethodsSize);
int virtualMethodsSize = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "virtual_methods_size = %d", virtualMethodsSize);
int previousIndex = 0;
if (staticFieldsSize > 0) {
out.annotate(0, "static_fields:");
out.indent();
for (int i = 0; i < staticFieldsSize; i++) {
out.annotate(0, "static_field[%d]", i);
out.indent();
previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
if (instanceFieldsSize > 0) {
out.annotate(0, "instance_fields:");
out.indent();
previousIndex = 0;
for (int i = 0; i < instanceFieldsSize; i++) {
out.annotate(0, "instance_field[%d]", i);
out.indent();
previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
if (directMethodsSize > 0) {
out.annotate(0, "direct_methods:");
out.indent();
previousIndex = 0;
for (int i = 0; i < directMethodsSize; i++) {
out.annotate(0, "direct_method[%d]", i);
out.indent();
previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
if (virtualMethodsSize > 0) {
out.annotate(0, "virtual_methods:");
out.indent();
previousIndex = 0;
for (int i = 0; i < virtualMethodsSize; i++) {
out.annotate(0, "virtual_method[%d]", i);
out.indent();
previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex);
out.deindent();
}
out.deindent();
}
}
private int annotateEncodedField(@Nonnull AnnotatedBytes out, @Nonnull RawDexFile dexFile, @Nonnull DexReader reader, int previousIndex) {
// large values may be used for the index delta, which cause the cumulative index to overflow upon
// addition, effectively allowing out of order entries.
int indexDelta = reader.readLargeUleb128();
int fieldIndex = previousIndex + indexDelta;
out.annotateTo(reader.getOffset(), "field_idx_diff = %d: %s", indexDelta, FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex));
int accessFlags = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, Joiner.on('|').join(AccessFlags.getAccessFlagsForField(accessFlags)));
return fieldIndex;
}
private int annotateEncodedMethod(@Nonnull AnnotatedBytes out, @Nonnull RawDexFile dexFile, @Nonnull DexReader reader, int previousIndex) {
// large values may be used for the index delta, which cause the cumulative index to overflow upon
// addition, effectively allowing out of order entries.
int indexDelta = reader.readLargeUleb128();
int methodIndex = previousIndex + indexDelta;
out.annotateTo(reader.getOffset(), "method_idx_diff = %d: %s", indexDelta, MethodIdItem.getReferenceAnnotation(dexFile, methodIndex));
int accessFlags = reader.readSmallUleb128();
out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, Joiner.on('|').join(AccessFlags.getAccessFlagsForMethod(accessFlags)));
int codeOffset = reader.readSmallUleb128();
if (codeOffset == 0) {
out.annotateTo(reader.getOffset(), "code_off = code_item[NO_OFFSET]");
} else {
out.annotateTo(reader.getOffset(), "code_off = code_item[0x%x]", codeOffset);
addCodeItemIdentity(codeOffset, MethodIdItem.asString(dexFile, methodIndex));
}
return methodIndex;
}
private void addCodeItemIdentity(int codeItemOffset, String methodString) {
if (codeItemAnnotator != null) {
codeItemAnnotator.setItemIdentity(codeItemOffset, methodString);
}
}
};
}
Aggregations