diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 05a5a15..297946e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -57,7 +57,7 @@ android { } lint { - isAbortOnError = false + abortOnError = false } } @@ -89,6 +89,7 @@ androidComponents.onVariants { variant -> } dependencies { + implementation(project(":daemon-service")) implementation(project(":lspcore")) implementation(project(":hiddenapi-bridge")) compileOnly(project(":hiddenapi-stubs")) diff --git a/app/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java b/app/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java index ef7e4b5..4bd0f1d 100644 --- a/app/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java +++ b/app/src/main/java/org/lsposed/lspatch/loader/LSPApplication.java @@ -3,7 +3,6 @@ package org.lsposed.lspatch.loader; import static android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE; import static org.lsposed.lspatch.share.Constants.CONFIG_ASSET_PATH; import static org.lsposed.lspatch.share.Constants.ORIGINAL_APK_ASSET_PATH; -import static org.lsposed.lspd.service.ConfigFileManager.loadModule; import android.app.ActivityThread; import android.app.LoadedApk; @@ -25,6 +24,7 @@ import android.util.Log; import com.google.gson.Gson; import org.lsposed.lspatch.loader.util.FileUtils; +import org.lsposed.lspatch.loader.util.ModuleLoader; import org.lsposed.lspatch.loader.util.XLog; import org.lsposed.lspatch.share.Constants; import org.lsposed.lspatch.share.PatchConfig; @@ -267,7 +267,7 @@ public class LSPApplication extends ApplicationServiceClient { var module = new Module(); module.apkPath = cacheApkPath; module.packageName = packageName; - module.file = loadModule(cacheApkPath); + module.file = ModuleLoader.loadModule(cacheApkPath); modules.add(module); } } catch (Throwable ignored) { diff --git a/app/src/main/java/org/lsposed/lspatch/loader/util/ModuleLoader.java b/app/src/main/java/org/lsposed/lspatch/loader/util/ModuleLoader.java new file mode 100644 index 0000000..d6a90bc --- /dev/null +++ b/app/src/main/java/org/lsposed/lspatch/loader/util/ModuleLoader.java @@ -0,0 +1,75 @@ +package org.lsposed.lspatch.loader.util; + +import android.os.SharedMemory; +import android.system.ErrnoException; +import android.system.OsConstants; +import android.util.Log; + +import org.lsposed.lspd.models.PreLoadedApk; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.channels.Channels; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipFile; + +public class ModuleLoader { + private static final String TAG = "LSPatch"; + + private static void readDexes(ZipFile apkFile, List preLoadedDexes) { + int secondary = 2; + for (var dexFile = apkFile.getEntry("classes.dex"); dexFile != null; + dexFile = apkFile.getEntry("classes" + secondary + ".dex"), secondary++) { + try (var in = apkFile.getInputStream(dexFile)) { + var memory = SharedMemory.create(null, in.available()); + var byteBuffer = memory.mapReadWrite(); + Channels.newChannel(in).read(byteBuffer); + SharedMemory.unmap(byteBuffer); + memory.setProtect(OsConstants.PROT_READ); + preLoadedDexes.add(memory); + } catch (IOException | ErrnoException e) { + Log.w(TAG, "Can not load " + dexFile + " in " + apkFile, e); + } + } + } + + private static void readName(ZipFile apkFile, String initName, List names) { + var initEntry = apkFile.getEntry(initName); + if (initEntry == null) return; + try (var in = apkFile.getInputStream(initEntry)) { + var reader = new BufferedReader(new InputStreamReader(in)); + String name; + while ((name = reader.readLine()) != null) { + name = name.trim(); + if (name.isEmpty() || name.startsWith("#")) continue; + names.add(name); + } + } catch (IOException e) { + Log.e(TAG, "Can not open " + initEntry, e); + } + } + + public static PreLoadedApk loadModule(String path) { + if (path == null) return null; + var file = new PreLoadedApk(); + var preLoadedDexes = new ArrayList(); + var moduleClassNames = new ArrayList(1); + var moduleLibraryNames = new ArrayList(1); + try (var apkFile = new ZipFile(path)) { + readDexes(apkFile, preLoadedDexes); + readName(apkFile, "assets/xposed_init", moduleClassNames); + readName(apkFile, "assets/native_init", moduleLibraryNames); + } catch (IOException e) { + Log.e(TAG, "Can not open " + path, e); + return null; + } + if (preLoadedDexes.isEmpty()) return null; + if (moduleClassNames.isEmpty()) return null; + file.preLoadedDexes = preLoadedDexes; + file.moduleClassNames = moduleClassNames; + file.moduleLibraryNames = moduleLibraryNames; + return file; + } +} diff --git a/build.gradle.kts b/build.gradle.kts index e1092de..2d47533 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,12 +5,10 @@ buildscript { google() mavenCentral() } - val agpVersion by extra("7.0.3") - val navVersion by extra("2.5.0-alpha01") + val agpVersion by extra("7.1.1") dependencies { classpath("com.android.tools.build:gradle:$agpVersion") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10") - classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$navVersion") } } diff --git a/core b/core index a06ba93..216a6f0 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit a06ba931a533198cd906825d436280db8247c869 +Subproject commit 216a6f00435b4ab00f5fadc80c1c3b1e7ac9b20c diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2275fc..c17f829 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Tue Aug 24 21:50:17 CST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/imanager/build.gradle.kts b/imanager/build.gradle.kts index 7e9c77f..df41b2f 100644 --- a/imanager/build.gradle.kts +++ b/imanager/build.gradle.kts @@ -36,5 +36,5 @@ android { } dependencies { - implementation(project(":lspcore")) + api(project(":daemon-service")) } diff --git a/manager/build.gradle.kts b/manager/build.gradle.kts index 0dd3c2a..ee0ef5b 100644 --- a/manager/build.gradle.kts +++ b/manager/build.gradle.kts @@ -47,8 +47,7 @@ android { } dependencies { - compileOnly(project(":patch")) - compileOnly(project(":lspcore")) + implementation(project(":patch")) implementation(project(":imanager")) implementation("androidx.core:core-ktx:1.7.0") diff --git a/settings.gradle.kts b/settings.gradle.kts index c3b3647..b63343a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,16 +1,16 @@ rootProject.name = "LSPatch" +include(":daemon-service") include(":hiddenapi-bridge") include(":hiddenapi-stubs") include(":interface") -include(":lspapp") include(":lspcore") include(":manager-service") +project(":daemon-service").projectDir = file("core/daemon-service") project(":hiddenapi-bridge").projectDir = file("core/hiddenapi-bridge") project(":hiddenapi-stubs").projectDir = file("core/hiddenapi-stubs") project(":interface").projectDir = file("core/service/interface") -project(":lspapp").projectDir = file("core/app") project(":lspcore").projectDir = file("core/core") project(":manager-service").projectDir = file("core/manager-service")