use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project smali by JesusFreke.
the class DexEntryFinderTest method testNormalStuff.
@Test
public void testNormalStuff() throws Exception {
Map<String, DexBackedDexFile> entries = Maps.newHashMap();
DexBackedDexFile dexFile1 = mock(DexBackedDexFile.class);
entries.put("/system/framework/framework.jar", dexFile1);
DexBackedDexFile dexFile2 = mock(DexBackedDexFile.class);
entries.put("/system/framework/framework.jar:classes2.dex", dexFile2);
DexEntryFinder testFinder = new DexEntryFinder("blah.oat", new TestMultiDexContainer(entries));
Assert.assertEquals(dexFile1, testFinder.findEntry("/system/framework/framework.jar", true).getDexFile());
assertEntryNotFound(testFinder, "system/framework/framework.jar", true);
assertEntryNotFound(testFinder, "/framework/framework.jar", true);
assertEntryNotFound(testFinder, "framework/framework.jar", true);
assertEntryNotFound(testFinder, "/framework.jar", true);
assertEntryNotFound(testFinder, "framework.jar", true);
Assert.assertEquals(dexFile1, testFinder.findEntry("system/framework/framework.jar", false).getDexFile());
Assert.assertEquals(dexFile1, testFinder.findEntry("/framework/framework.jar", false).getDexFile());
Assert.assertEquals(dexFile1, testFinder.findEntry("framework/framework.jar", false).getDexFile());
Assert.assertEquals(dexFile1, testFinder.findEntry("/framework.jar", false).getDexFile());
Assert.assertEquals(dexFile1, testFinder.findEntry("framework.jar", false).getDexFile());
assertEntryNotFound(testFinder, "ystem/framework/framework.jar", false);
assertEntryNotFound(testFinder, "ssystem/framework/framework.jar", false);
assertEntryNotFound(testFinder, "ramework/framework.jar", false);
assertEntryNotFound(testFinder, "ramework.jar", false);
assertEntryNotFound(testFinder, "framework", false);
Assert.assertEquals(dexFile2, testFinder.findEntry("/system/framework/framework.jar:classes2.dex", true).getDexFile());
assertEntryNotFound(testFinder, "system/framework/framework.jar:classes2.dex", true);
assertEntryNotFound(testFinder, "framework.jar:classes2.dex", true);
assertEntryNotFound(testFinder, "classes2.dex", true);
Assert.assertEquals(dexFile2, testFinder.findEntry("system/framework/framework.jar:classes2.dex", false).getDexFile());
Assert.assertEquals(dexFile2, testFinder.findEntry("/framework/framework.jar:classes2.dex", false).getDexFile());
Assert.assertEquals(dexFile2, testFinder.findEntry("framework/framework.jar:classes2.dex", false).getDexFile());
Assert.assertEquals(dexFile2, testFinder.findEntry("/framework.jar:classes2.dex", false).getDexFile());
Assert.assertEquals(dexFile2, testFinder.findEntry("framework.jar:classes2.dex", false).getDexFile());
Assert.assertEquals(dexFile2, testFinder.findEntry(":classes2.dex", false).getDexFile());
Assert.assertEquals(dexFile2, testFinder.findEntry("classes2.dex", false).getDexFile());
assertEntryNotFound(testFinder, "ystem/framework/framework.jar:classes2.dex", false);
assertEntryNotFound(testFinder, "ramework.jar:classes2.dex", false);
assertEntryNotFound(testFinder, "lasses2.dex", false);
assertEntryNotFound(testFinder, "classes2", false);
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project smali by JesusFreke.
the class SmaliTestUtils method compileSmali.
public static DexBackedClassDef compileSmali(String smaliText, int apiLevel) throws RecognitionException, IOException {
CommonTokenStream tokens;
LexerErrorInterface lexer;
DexBuilder dexBuilder = new DexBuilder(Opcodes.forApi(apiLevel));
Reader reader = new StringReader(smaliText);
lexer = new smaliFlexLexer(reader, apiLevel);
tokens = new CommonTokenStream((TokenSource) lexer);
smaliParser parser = new smaliParser(tokens);
parser.setVerboseErrors(true);
parser.setAllowOdex(false);
parser.setApiLevel(apiLevel);
smaliParser.smali_file_return result = parser.smali_file();
if (parser.getNumberOfSyntaxErrors() > 0 || lexer.getNumberOfSyntaxErrors() > 0) {
throw new RuntimeException("Error occurred while compiling text");
}
CommonTree t = result.getTree();
CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
treeStream.setTokenStream(tokens);
smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
dexGen.setApiLevel(apiLevel);
dexGen.setVerboseErrors(true);
dexGen.setDexBuilder(dexBuilder);
dexGen.smali_file();
if (dexGen.getNumberOfSyntaxErrors() > 0) {
throw new RuntimeException("Error occurred while compiling text");
}
MemoryDataStore dataStore = new MemoryDataStore();
dexBuilder.writeTo(dataStore);
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(apiLevel), dataStore.getBuffer());
return Iterables.getFirst(dexFile.getClasses(), null);
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project smali by JesusFreke.
the class AnalysisArguments method loadClassPathForDexFile.
@Nonnull
public ClassPath loadClassPathForDexFile(@Nonnull File dexFileDir, @Nonnull MultiDexContainer.DexEntry<? extends DexBackedDexFile> dexEntry, boolean checkPackagePrivateAccess, int oatVersion) throws IOException {
ClassPathResolver resolver;
MultiDexContainer<? extends DexBackedDexFile> container = dexEntry.getContainer();
if (oatVersion == NOT_SPECIFIED) {
if (container instanceof OatFile) {
checkPackagePrivateAccess = true;
oatVersion = ((OatFile) container).getOatVersion();
} else {
oatVersion = VersionMap.mapApiToArtVersion(dexEntry.getDexFile().getOpcodes().api);
}
} else {
// this should always be true for ART
checkPackagePrivateAccess = true;
}
if (classPathDirectories == null || classPathDirectories.size() == 0) {
classPathDirectories = Lists.newArrayList(dexFileDir.getPath());
}
List<String> filteredClassPathDirectories = Lists.newArrayList();
if (classPathDirectories != null) {
for (String dir : classPathDirectories) {
File file = new File(dir);
if (!file.exists()) {
System.err.println(String.format("Warning: directory %s does not exist. Ignoring.", dir));
} else if (!file.isDirectory()) {
System.err.println(String.format("Warning: %s is not a directory. Ignoring.", dir));
} else {
filteredClassPathDirectories.add(dir);
}
}
}
if (bootClassPath == null) {
// TODO: we should be able to get the api from the Opcodes object associated with the dexFile..
// except that the oat version -> api mapping doesn't fully work yet
resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexEntry);
} else if (bootClassPath.size() == 1 && bootClassPath.get(0).length() == 0) {
// --bootclasspath "" is a special case, denoting that no bootclasspath should be used
resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), classPath, dexEntry);
} else {
resolver = new ClassPathResolver(filteredClassPathDirectories, bootClassPath, classPath, dexEntry);
}
if (oatVersion == 0 && container instanceof OatFile) {
oatVersion = ((OatFile) container).getOatVersion();
}
return new ClassPath(resolver.getResolvedClassProviders(), checkPackagePrivateAccess, oatVersion);
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project smali by JesusFreke.
the class DexBackedInstruction method readFrom.
@Nonnull
public static Instruction readFrom(DexBackedDexFile dexFile, @Nonnull DexReader reader) {
int opcodeValue = reader.peekUbyte();
if (opcodeValue == 0) {
opcodeValue = reader.peekUshort();
}
Opcode opcode = dexFile.getOpcodes().getOpcodeByValue(opcodeValue);
Instruction instruction = buildInstruction(dexFile, opcode, reader.getOffset() + reader.dexBuf.getBaseOffset() - dexFile.getBuffer().getBaseOffset() - dexFile.getBaseDataOffset());
reader.moveRelative(instruction.getCodeUnits() * 2);
return instruction;
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile 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.getBuffer().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 DexBackedDexFile 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 DexBackedDexFile 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