use of org.jf.dexlib2.analysis.ClassPath in project smali by JesusFreke.
the class MethodAnalyzerTest method testInstanceOfNarrowingEqz_art.
@Test
public void testInstanceOfNarrowingEqz_art() throws IOException {
MethodImplementationBuilder builder = new MethodImplementationBuilder(2);
builder.addInstruction(new BuilderInstruction22c(Opcode.INSTANCE_OF, 0, 1, new ImmutableTypeReference("Lmain;")));
builder.addInstruction(new BuilderInstruction21t(Opcode.IF_EQZ, 0, builder.getLabel("not_instance_of")));
builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
builder.addLabel("not_instance_of");
builder.addInstruction(new BuilderInstruction10x(Opcode.RETURN_VOID));
MethodImplementation methodImplementation = builder.getMethodImplementation();
Method method = new ImmutableMethod("Lmain;", "narrowing", Collections.singletonList(new ImmutableMethodParameter("Ljava/lang/Object;", null, null)), "V", AccessFlags.PUBLIC.getValue(), null, methodImplementation);
ClassDef classDef = new ImmutableClassDef("Lmain;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, Collections.singletonList(method));
DexFile dexFile = new ImmutableDexFile(forArtVersion(56), Collections.singletonList(classDef));
ClassPath classPath = new ClassPath(Lists.newArrayList(new DexClassProvider(dexFile)), true, 56);
MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, null, false);
List<AnalyzedInstruction> analyzedInstructions = methodAnalyzer.getAnalyzedInstructions();
Assert.assertEquals("Lmain;", analyzedInstructions.get(2).getPreInstructionRegisterType(1).type.getType());
Assert.assertEquals("Ljava/lang/Object;", analyzedInstructions.get(3).getPreInstructionRegisterType(1).type.getType());
}
use of org.jf.dexlib2.analysis.ClassPath in project smali by JesusFreke.
the class AnalysisArguments method loadClassPathForDexFile.
@Nonnull
public ClassPath loadClassPathForDexFile(@Nonnull File dexFileDir, @Nonnull DexFile dexFile, boolean checkPackagePrivateAccess, int oatVersion) throws IOException {
ClassPathResolver resolver;
// regardless of the actual version of the oat file
if (oatVersion == NOT_ART) {
if (dexFile instanceof OatDexFile) {
checkPackagePrivateAccess = true;
oatVersion = ((OatDexFile) dexFile).getContainer().getOatVersion();
}
} 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, dexFile);
} 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, dexFile);
} else {
resolver = new ClassPathResolver(filteredClassPathDirectories, bootClassPath, classPath, dexFile);
}
if (oatVersion == 0 && dexFile instanceof OatDexFile) {
oatVersion = ((OatDexFile) dexFile).getContainer().getOatVersion();
}
return new ClassPath(resolver.getResolvedClassProviders(), checkPackagePrivateAccess, oatVersion);
}
use of org.jf.dexlib2.analysis.ClassPath in project smali by JesusFreke.
the class AnalyzedMethodUtil method canAccess.
public static boolean canAccess(@Nonnull TypeProto type, @Nonnull Method virtualMethod, boolean checkPackagePrivate, boolean checkProtected, boolean checkClass) {
if (checkPackagePrivate && MethodUtil.isPackagePrivate(virtualMethod)) {
String otherPackage = TypeUtils.getPackage(virtualMethod.getDefiningClass());
String thisPackage = TypeUtils.getPackage(type.getType());
if (!otherPackage.equals(thisPackage)) {
return false;
}
}
if (checkProtected && (virtualMethod.getAccessFlags() & AccessFlags.PROTECTED.getValue()) != 0) {
if (!TypeProtoUtils.extendsFrom(type, virtualMethod.getDefiningClass())) {
return false;
}
}
if (checkClass) {
ClassPath classPath = type.getClassPath();
ClassDef methodClassDef = classPath.getClassDef(virtualMethod.getDefiningClass());
if (!TypeUtils.canAccessClass(type.getType(), methodClassDef)) {
return false;
}
}
return true;
}
use of org.jf.dexlib2.analysis.ClassPath in project smali by JesusFreke.
the class ClassPathResolver method loadLocalOrDeviceBootClassPathEntry.
private void loadLocalOrDeviceBootClassPathEntry(@Nonnull String entry) throws IOException, NoDexException, NotFoundException {
// first, see if the entry is a valid local path
if (loadLocalClassPathEntry(entry)) {
return;
}
// It's not a local path, so let's try to resolve it as a device path, relative to one of the provided
// directories
List<String> pathComponents = splitDevicePath(entry);
Joiner pathJoiner = Joiner.on(File.pathSeparatorChar);
for (String directory : classPathDirs) {
File directoryFile = new File(directory);
if (!directoryFile.exists()) {
continue;
}
for (int i = 0; i < pathComponents.size(); i++) {
String partialPath = pathJoiner.join(pathComponents.subList(i, pathComponents.size()));
File entryFile = new File(directoryFile, partialPath);
if (entryFile.exists() && entryFile.isFile()) {
loadEntry(entryFile, true);
return;
}
}
}
throw new NotFoundException("Could not find classpath entry %s", entry);
}
use of org.jf.dexlib2.analysis.ClassPath in project smali by JesusFreke.
the class MethodAnalyzer method analyzeNewInstance.
private void analyzeNewInstance(@Nonnull AnalyzedInstruction analyzedInstruction) {
ReferenceInstruction instruction = (ReferenceInstruction) analyzedInstruction.instruction;
int register = ((OneRegisterInstruction) analyzedInstruction.instruction).getRegisterA();
RegisterType destRegisterType = analyzedInstruction.getPostInstructionRegisterType(register);
if (destRegisterType.category != RegisterType.UNKNOWN) {
//successors and nothing else needs to be done.
assert destRegisterType.category == RegisterType.UNINIT_REF;
return;
}
TypeReference typeReference = (TypeReference) instruction.getReference();
RegisterType classType = RegisterType.getRegisterType(classPath, typeReference);
setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, RegisterType.getRegisterType(RegisterType.UNINIT_REF, classType.type));
}
Aggregations