ClassPathResolver resolver = new ClassPathResolver(classpathList, classpathList, classpathList, dexFile); cp = new ClassPath(resolver.getResolvedClassProviders().toArray(new ClassProvider[0])); } catch (IOException e) { throw new RuntimeException(e);
private static List<String> bootClassPathForOat(@Nonnull OatDexFile dexFile) { List<String> bcp = dexFile.getContainer().getBootClassPath(); if(bcp.isEmpty()) { return Lists.newArrayList("boot.oat"); } else { return replaceElementsSuffix(bcp, ".art", ".oat"); } }
bootClassPathEntries = getDefaultBootClassPath(dexFile, dexFile.getOpcodes().api); loadLocalOrDeviceBootClassPathEntry(entry); } catch (PathEntryLoader.NoDexException ex) { if (entry.endsWith(".jar")) { String odexEntry = entry.substring(0, entry.length() - 4) + ".odex"; try { loadLocalOrDeviceBootClassPathEntry(odexEntry); } catch (PathEntryLoader.NoDexException ex2) { throw new ResolveException("Neither %s nor %s contain a dex file", entry, odexEntry); String jarEntry = entry.substring(0, entry.length() - 5) + ".jar"; try { loadLocalOrDeviceBootClassPathEntry(jarEntry); } catch (PathEntryLoader.NoDexException ex2) { throw new ResolveException("Neither %s nor %s contain a dex file", entry, jarEntry); loadLocalClassPathEntry(entry); } catch (PathEntryLoader.NoDexException ex) { throw new ResolveException(ex);
private void loadLocalOrDeviceBootClassPathEntry(@Nonnull String entry) throws IOException, PathEntryLoader.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()) { pathEntryLoader.loadEntry(entryFile, true); return; } } } throw new NotFoundException("Could not find classpath entry %s", entry); }
private static List<String> getDefaultBootClassPath(@Nonnull DexFile dexFile, int apiLevel) { if (dexFile instanceof OatFile.OatDexFile) { return bootClassPathForOat((OatDexFile) dexFile);
bootClassPathEntries = getDefaultBootClassPath(dexFile, dexFile.getOpcodes().api); loadLocalOrDeviceBootClassPathEntry(entry); } catch (PathEntryLoader.NoDexException ex) { if (entry.endsWith(".jar")) { String odexEntry = entry.substring(0, entry.length() - 4) + ".odex"; try { loadLocalOrDeviceBootClassPathEntry(odexEntry); } catch (PathEntryLoader.NoDexException ex2) { throw new ResolveException("Neither %s nor %s contain a dex file", entry, odexEntry); String jarEntry = entry.substring(0, entry.length() - 5) + ".jar"; try { loadLocalOrDeviceBootClassPathEntry(jarEntry); } catch (PathEntryLoader.NoDexException ex2) { throw new ResolveException("Neither %s nor %s contain a dex file", entry, jarEntry); loadLocalClassPathEntry(entry); } catch (PathEntryLoader.NoDexException ex) { throw new ResolveException(ex);
private void loadLocalOrDeviceBootClassPathEntry(@Nonnull String entry) throws IOException, PathEntryLoader.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()) { pathEntryLoader.loadEntry(entryFile, true); return; } } } throw new NotFoundException("Could not find classpath entry %s", entry); }
private static List<String> getDefaultBootClassPath(@Nonnull DexFile dexFile, int apiLevel) { if (dexFile instanceof OatFile.OatDexFile) { return bootClassPathForOat((OatDexFile) dexFile);
resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexFile); } else if (bootClassPath.size() == 1 && bootClassPath.get(0).length() == 0) { resolver = new ClassPathResolver( ImmutableList.<String>of(), ImmutableList.<String>of(), classPath, dexFile); } else { resolver = new ClassPathResolver(filteredClassPathDirectories, bootClassPath, classPath, dexFile); oatVersion = ((OatDexFile)dexFile).getContainer().getOatVersion(); return new ClassPath(resolver.getResolvedClassProviders(), checkPackagePrivateAccess, oatVersion);
private static List<String> bootClassPathForOat(@Nonnull OatDexFile dexFile) { List<String> bcp = dexFile.getContainer().getBootClassPath(); if(bcp.isEmpty()) { return Lists.newArrayList("boot.oat"); } else { return replaceElementsSuffix(bcp, ".art", ".oat"); } }
resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexFile); } else if (bootClassPath.size() == 1 && bootClassPath.get(0).length() == 0) { resolver = new ClassPathResolver( ImmutableList.<String>of(), ImmutableList.<String>of(), classPath, dexFile); } else { resolver = new ClassPathResolver(filteredClassPathDirectories, bootClassPath, classPath, dexFile); oatVersion = ((OatDexFile)dexFile).getContainer().getOatVersion(); return new ClassPath(resolver.getResolvedClassProviders(), checkPackagePrivateAccess, oatVersion);
Iterable<? extends org.jf.dexlib2.iface.instruction.Instruction> deodex() { try { DexFileModule m = myClass.getContainer(); ClassPathResolver path = new ClassPathResolver(Collections.singletonList(m.getFile().getParent() + '/'), Collections.<String>emptyList(), m.getDexFile()); ClassPath cp = new ClassPath(path.getResolvedClassProviders(), false, m.getDexFile().getOpcodes().artVersion); MethodAnalyzer analyzer = new MethodAnalyzer(cp, eMethod, null, false); return analyzer.getInstructions(); } catch (Exception e) { assert false : e; return eMethod.getImplementation().getInstructions(); } }
Iterable<? extends org.jf.dexlib2.iface.instruction.Instruction> deodex() { try { DexFileModule m = myClass.getContainer(); ClassPathResolver path = new ClassPathResolver(Collections.singletonList(m.getFile().getParent() + '/'), Collections.<String>emptyList(), m.getDexFile()); ClassPath cp = new ClassPath(path.getResolvedClassProviders(), false, m.getDexFile().getOpcodes().artVersion); MethodAnalyzer analyzer = new MethodAnalyzer(cp, eMethod, null, false); return analyzer.getInstructions(); } catch (Exception e) { assert false : e; return eMethod.getImplementation().getInstructions(); } }
@Test public void testCustomMethodInlineTable_Direct() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PRIVATE.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, ImmutableList.of(method), null); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_DIRECT, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); } }
@Test public void testCustomMethodInlineTable_Virtual() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PUBLIC.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, null, ImmutableList.of(method)); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_VIRTUAL, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); }
@Test public void testCustomMethodInlineTable_Static() throws IOException { List<ImmutableInstruction> instructions = Lists.newArrayList( new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID)); ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null); ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.STATIC.getValue(), null, methodImpl); ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, ImmutableList.of(method), null); DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef)); ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile); ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART); InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V"); MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false); Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0); Assert.assertEquals(Opcode.INVOKE_STATIC, deodexedInstruction.getOpcode()); MethodReference methodReference = (MethodReference)((Instruction35c)deodexedInstruction).getReference(); Assert.assertEquals(method, methodReference); }