diff --git a/core/src/main/java/org/lsposed/lspd/util/InMemoryDelegateLastClassLoader.java b/core/src/main/java/org/lsposed/lspd/util/InMemoryDelegateLastClassLoader.java index fd8e46cc..996e0232 100644 --- a/core/src/main/java/org/lsposed/lspd/util/InMemoryDelegateLastClassLoader.java +++ b/core/src/main/java/org/lsposed/lspd/util/InMemoryDelegateLastClassLoader.java @@ -2,6 +2,9 @@ package org.lsposed.lspd.util; import static de.robv.android.xposed.XposedBridge.TAG; +import android.system.ErrnoException; +import android.system.Os; +import android.system.OsConstants; import android.util.Log; import java.io.File; @@ -12,20 +15,36 @@ import java.nio.channels.Channels; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import hidden.ByteBufferDexClassLoader; @SuppressWarnings("ConstantConditions") public final class InMemoryDelegateLastClassLoader extends ByteBufferDexClassLoader { + private static final String zipSeparator = "!/"; private final String apk; + private final List nativeLibraryDirs; + + private static List splitPaths(String searchPath) { + var result = new ArrayList(); + if (searchPath == null) return result; + for (var path : searchPath.split(File.pathSeparator)) { + result.add(new File(path)); + } + return result; + } private InMemoryDelegateLastClassLoader(ByteBuffer[] dexBuffers, String librarySearchPath, ClassLoader parent, String apk) { - super(dexBuffers, librarySearchPath, parent); + super(dexBuffers, parent); this.apk = apk; + nativeLibraryDirs = new ArrayList<>(splitPaths(librarySearchPath)); + nativeLibraryDirs.addAll(splitPaths(System.getProperty("java.library.path"))); } @Override @@ -51,6 +70,35 @@ public final class InMemoryDelegateLastClassLoader extends ByteBufferDexClassLoa } } + @Override + public String findLibrary(String libraryName) { + var fileName = System.mapLibraryName(libraryName); + for (var file : nativeLibraryDirs) { + var path = file.getPath(); + if (path.contains(zipSeparator)) { + var split = path.split(zipSeparator, 2); + try (var jarFile = new JarFile(split[0])) { + var entryName = split[1] + '/' + fileName; + var entry = jarFile.getEntry(entryName); + if (entry != null && entry.getMethod() == ZipEntry.STORED) { + return split[0] + zipSeparator + entryName; + } + } catch (IOException e) { + Log.e(TAG, "Can not open " + split[0], e); + } + } else if (file.isDirectory()) { + var entryPath = new File(file, fileName).getPath(); + try { + var fd = Os.open(entryPath, OsConstants.O_RDONLY, 0); + Os.close(fd); + return entryPath; + } catch (ErrnoException ignored) { + } + } + } + return null; + } + @Override protected URL findResource(String name) { try { diff --git a/hiddenapi-bridge/src/main/java/hidden/ByteBufferDexClassLoader.java b/hiddenapi-bridge/src/main/java/hidden/ByteBufferDexClassLoader.java index 2f659f60..70328f18 100644 --- a/hiddenapi-bridge/src/main/java/hidden/ByteBufferDexClassLoader.java +++ b/hiddenapi-bridge/src/main/java/hidden/ByteBufferDexClassLoader.java @@ -5,7 +5,7 @@ import java.nio.ByteBuffer; import dalvik.system.BaseDexClassLoader; public class ByteBufferDexClassLoader extends BaseDexClassLoader { - public ByteBufferDexClassLoader(ByteBuffer[] dexFiles, String librarySearchPath, ClassLoader parent) { - super(dexFiles, librarySearchPath, parent); + public ByteBufferDexClassLoader(ByteBuffer[] dexFiles, ClassLoader parent) { + super(dexFiles, parent); } } diff --git a/hiddenapi-stubs/src/main/java/dalvik/system/BaseDexClassLoader.java b/hiddenapi-stubs/src/main/java/dalvik/system/BaseDexClassLoader.java index 00ffd551..959aba41 100644 --- a/hiddenapi-stubs/src/main/java/dalvik/system/BaseDexClassLoader.java +++ b/hiddenapi-stubs/src/main/java/dalvik/system/BaseDexClassLoader.java @@ -15,7 +15,7 @@ public class BaseDexClassLoader extends ClassLoader { throw new RuntimeException("Stub!"); } - public BaseDexClassLoader(ByteBuffer[] dexFiles, String librarySearchPath, ClassLoader parent) { + public BaseDexClassLoader(ByteBuffer[] dexFiles, ClassLoader parent) { throw new RuntimeException("Stub!"); }