diff --git a/build.gradle.kts b/build.gradle.kts index eb24b6b2..02217912 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -48,7 +48,6 @@ val androidCompileNdkVersion by extra("22.1.7171670") val androidSourceCompatibility by extra(JavaVersion.VERSION_11) val androidTargetCompatibility by extra(JavaVersion.VERSION_11) val apiCode by extra(93) -val magiskDir by extra(project(":core").projectDir.path + "/build/tmp/magisk/") allprojects { repositories { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 54689014..db274383 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -17,11 +17,13 @@ * Copyright (C) 2021 LSPosed Contributors */ +import com.android.build.gradle.BaseExtension +import com.android.ide.common.signing.KeystoreHelper import org.apache.tools.ant.filters.FixCrLfFilter import org.gradle.internal.os.OperatingSystem import org.jetbrains.kotlin.daemon.common.toHexString +import java.io.PrintStream import java.nio.file.Paths - import java.security.MessageDigest plugins { @@ -58,8 +60,6 @@ val androidCompileNdkVersion: String by rootProject.extra val androidSourceCompatibility: JavaVersion by rootProject.extra val androidTargetCompatibility: JavaVersion by rootProject.extra -val magiskDir: String by rootProject.extra - val verCode: Int by rootProject.extra val verName: String by rootProject.extra @@ -221,32 +221,54 @@ task("buildLibcxx", Exec::class) { tasks.getByName("preBuild").dependsOn("buildLibcxx") -afterEvaluate { - android.applicationVariants.forEach { variant -> - val variantCapped = variant.name.capitalize() - val variantLowered = variant.name.toLowerCase() - val zipFileName = "$moduleName-$verName-$verCode-$variantLowered.zip" +android.applicationVariants.all { + val variantCapped = name.capitalize() + val variantLowered = name.toLowerCase() + val zipFileName = "$moduleName-$verName-$verCode-$variantLowered.zip" + val magiskDir = "$buildDir/magisk/$variantLowered" - val prepareMagiskFilesTask = task("prepareMagiskFiles$variantCapped") { - dependsOn("assemble$variantCapped") - dependsOn(":app:assemble$variantCapped") - doLast { - delete { - delete(magiskDir) + val app = rootProject.project(":app").extensions.getByName("android") + val outSrcDir = file("$buildDir/generated/source/signInfo/${name.toLowerCase()}") + val outSrc = file("$outSrcDir/org/lsposed/lspd/util/SignInfo.java") + val signInfoTask = tasks.register("generate${name.capitalize()}SignInfo") { + outputs.file(outSrc) + doLast { + val sign = app.buildTypes.named(buildType.name).get().signingConfig + if (sign?.isSigningReady == true) { + outSrc.parentFile.mkdirs() + val certificateInfo = KeystoreHelper.getCertificateInfo( + sign.storeType, + sign.storeFile, + sign.storePassword, + sign.keyPassword, + sign.keyAlias + ) + PrintStream(outSrc).apply { + println("package org.lsposed.lspd.util;") + println("public final class SignInfo {") + print("public static final byte[] CERTIFICATE = {") + val bytes = certificateInfo.certificate.encoded + print(bytes.joinToString(",") { it.toString() }) + println("};") + println("}") } - copy { - from("${rootProject.projectDir}/README.md") - into(magiskDir) - } - copy { - from("$projectDir/magisk_module") + } + } + } + registerJavaGeneratingTask(signInfoTask.get(), outSrcDir) + + val prepareMagiskFilesTask = task("prepareMagiskFiles$variantCapped") { + dependsOn("assemble$variantCapped") + dependsOn(":app:assemble$variantCapped") + doLast { + sync { + into(magiskDir) + from("${rootProject.projectDir}/README.md") + from("$projectDir/magisk_module") { exclude("riru.sh", "module.prop") - into(magiskDir) } - copy { - from("$projectDir/magisk_module") + from("$projectDir/magisk_module") { include("module.prop") - into(magiskDir) expand( "moduleId" to moduleId, "versionName" to verName, @@ -259,10 +281,8 @@ afterEvaluate { FixCrLfFilter::class.java ) } - copy { - from("${projectDir}/magisk_module") + from("${projectDir}/magisk_module") { include("riru.sh") - into(magiskDir) filter { line -> line.replace("%%%RIRU_MODULE_LIB_NAME%%%", "lspd") .replace( @@ -279,7 +299,7 @@ afterEvaluate { ) .replace( "%%RIRU_MODULE_DEBUG%%", - if (variantLowered == "debug") "true" else "false" + if (buildType.name == "debug") "true" else "false" ) } filter( @@ -287,79 +307,73 @@ afterEvaluate { FixCrLfFilter::class.java ) } - copy { - from("${buildDir}/intermediates/cmake/$variantLowered/obj") - exclude("**/*.txt") - into("$magiskDir/lib") - } - val dexOutPath = if (variant.name.contains("release")) - "$buildDir/intermediates/dex/$variantLowered/minify${variantCapped}WithR8" else - "$buildDir/intermediates/dex/$variantLowered/mergeDex$variantCapped" - copy { - from(dexOutPath) - rename("classes.dex", "lspd.dex") - into("$magiskDir/framework") - } - copy { - from("${project(":app").projectDir}/build/outputs/apk/${variantLowered}") + from("${project(":app").buildDir}/outputs/apk/${variantLowered}") { include("*.apk") rename(".*\\.apk", "manager.apk") - into(magiskDir) } - // generate sha1sum - fileTree(magiskDir).matching { - exclude("README.md", "META-INF") - }.visit { - if (isDirectory) return@visit - file(file.path + ".sha256").writeText(calcSha256(file)) + into("lib") { + from("${buildDir}/intermediates/cmake/$variantLowered/obj") + exclude("**/*.txt") + } + val dexOutPath = if (buildType.name == "release") + "$buildDir/intermediates/dex/$variantLowered/minify${variantCapped}WithR8" else + "$buildDir/intermediates/dex/$variantLowered/mergeDex$variantCapped" + into("framework") { + from(dexOutPath) + rename("classes.dex", "lspd.dex") } } - } - - val zipTask = task("zip${variantCapped}", Zip::class) { - dependsOn(prepareMagiskFilesTask) - archiveFileName.set(zipFileName) - destinationDirectory.set(file("$projectDir/release")) - from(magiskDir) - } - - val pushTask = task("push${variantCapped}", Exec::class) { - dependsOn(zipTask) - workingDir("${projectDir}/release") - val commands = arrayOf( - android.adbExecutable, "push", - zipFileName, - "/data/local/tmp/" - ) - if (isWindows) { - commandLine("cmd", "/c", commands.joinToString(" ")) - } else { - commandLine(commands) - } - } - val flashTask = task("flash${variantCapped}", Exec::class) { - dependsOn(pushTask) - workingDir("${projectDir}/release") - val commands = arrayOf( - android.adbExecutable, "shell", "su", "-c", - "magisk --install-module /data/local/tmp/${zipFileName}" - ) - if (isWindows) { - commandLine("cmd", "/c", commands.joinToString(" ")) - } else { - commandLine(commands) - } - } - task("flashAndReboot${variantCapped}", Exec::class) { - dependsOn(flashTask) - workingDir("${projectDir}/release") - val commands = arrayOf(android.adbExecutable, "shell", "reboot") - if (isWindows) { - commandLine("cmd", "/c", commands.joinToString(" ")) - } else { - commandLine(commands) + fileTree(magiskDir).matching { + exclude("README.md", "META-INF") + }.visit { + if (isDirectory) return@visit + file(file.path + ".sha256").writeText(calcSha256(file)) } } } + val zipTask = task("zip${variantCapped}", Zip::class) { + dependsOn(prepareMagiskFilesTask) + archiveFileName.set(zipFileName) + destinationDirectory.set(file("$projectDir/release")) + from(magiskDir) + } + + val pushTask = task("push${variantCapped}", Exec::class) { + dependsOn(zipTask) + workingDir("${projectDir}/release") + val commands = arrayOf( + android.adbExecutable, "push", + zipFileName, + "/data/local/tmp/" + ) + if (isWindows) { + commandLine("cmd", "/c", commands.joinToString(" ")) + } else { + commandLine(commands) + } + } + val flashTask = task("flash${variantCapped}", Exec::class) { + dependsOn(pushTask) + workingDir("${projectDir}/release") + val commands = arrayOf( + android.adbExecutable, "shell", "su", "-c", + "magisk --install-module /data/local/tmp/${zipFileName}" + ) + if (isWindows) { + commandLine("cmd", "/c", commands.joinToString(" ")) + } else { + commandLine(commands) + } + } + task("flashAndReboot${variantCapped}", Exec::class) { + dependsOn(flashTask) + workingDir("${projectDir}/release") + val commands = arrayOf(android.adbExecutable, "shell", "reboot") + if (isWindows) { + commandLine("cmd", "/c", commands.joinToString(" ")) + } else { + commandLine(commands) + } + } } diff --git a/core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java b/core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java index c1a412bb..769bccc7 100644 --- a/core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java +++ b/core/src/main/java/org/lsposed/lspd/util/InstallerVerifier.java @@ -20,6 +20,8 @@ package org.lsposed.lspd.util; +import static org.lsposed.lspd.util.SignInfo.CERTIFICATE; + import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Bundle; @@ -35,9 +37,6 @@ import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; public class InstallerVerifier { - - private static final byte[] CERTIFICATE = {48, -126, 2, -61, 48, -126, 1, -85, -96, 3, 2, 1, 2, 2, 4, 36, 13, 10, 11, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 10, 19, 7, 76, 83, 80, 111, 115, 101, 100, 48, 30, 23, 13, 50, 49, 48, 51, 48, 49, 49, 55, 49, 49, 48, 55, 90, 23, 13, 52, 54, 48, 50, 50, 51, 49, 55, 49, 49, 48, 55, 90, 48, 18, 49, 16, 48, 14, 6, 3, 85, 4, 10, 19, 7, 76, 83, 80, 111, 115, 101, 100, 48, -126, 1, 34, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -126, 1, 15, 0, 48, -126, 1, 10, 2, -126, 1, 1, 0, -122, -20, -29, -82, 21, 0, 37, -64, -36, 21, 88, -73, 39, -107, 72, -34, -126, 30, 106, 8, 99, 62, -108, 126, 124, 6, -7, 12, -90, -8, -55, -24, -88, -108, 7, -109, 54, 12, -111, 85, -72, 119, -37, -112, -106, -106, 6, -120, 43, -120, 8, -8, 57, 102, -104, -28, -39, -120, 58, -124, -56, 67, 118, 55, 31, 124, -21, 101, 110, 59, 109, 119, 78, -103, 90, 101, -85, -67, 52, -42, -63, 74, 34, -11, 50, -55, 4, 7, -101, -45, -64, 87, -9, 0, -60, -125, -16, 68, -115, -87, 108, -110, 10, 3, -95, 15, -103, 56, -47, -25, 4, 24, -74, 102, 86, 2, 30, -86, -22, 25, 124, -4, -2, 43, -45, 63, 66, -93, 115, 14, 9, -82, 68, 19, -6, -120, 62, 71, 61, -119, 33, 115, -80, 23, -99, 13, 91, 99, -104, -105, -16, 47, -40, 69, 48, -87, 100, 8, -111, 93, 54, 83, 106, -49, -78, -42, 104, 44, 70, -36, 101, -27, -10, -92, -44, 90, -84, -52, -79, 120, -102, 27, -95, -71, 91, -98, -116, 35, 105, 53, 120, -61, -99, 89, 72, -18, -120, 31, 48, 104, -10, -22, -10, 121, 107, -38, -122, -7, -111, -88, -98, 36, 55, 82, -10, -80, -23, -10, 67, -62, 87, 96, 80, 4, 79, 116, 12, -20, -92, 14, -118, -11, -28, 12, -100, 79, 79, 4, -43, 33, -5, 28, -45, 39, -91, 50, -119, 62, -103, -101, 11, 23, 13, 79, -60, -99, 2, 3, 1, 0, 1, -93, 33, 48, 31, 48, 29, 6, 3, 85, 29, 14, 4, 22, 4, 20, -12, 0, 95, -84, 54, 105, -5, 73, 14, -74, -128, 118, 112, 113, 67, -21, -92, -37, 13, -73, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 3, -126, 1, 1, 0, 24, 12, 70, -87, -94, -63, 25, -29, -57, 108, 117, 95, -12, -50, 23, 40, -95, -105, 38, -112, -75, 68, 109, -2, 127, 28, 45, -115, 37, 44, -15, 68, 77, -33, 20, 30, 23, 63, 60, -42, 7, -14, -76, 9, -79, 57, 47, 67, -30, 8, 89, 95, -108, -1, -40, -115, 21, -61, -35, -111, -95, -2, -22, -35, -107, 92, -122, -72, 47, 78, 24, 35, -127, 107, -101, 64, -65, -54, 38, 46, 76, -90, 50, 60, 63, -106, -73, 3, -6, -85, 103, -29, -17, 1, -104, 15, -4, 125, -60, 25, 105, -94, -38, -58, 103, 117, -89, 95, -85, 14, 7, 120, -75, 106, -38, -67, -44, 42, 42, -93, 12, -47, 102, -55, -105, 116, -117, 69, -127, -68, 105, -27, 15, -86, -75, -58, -90, 119, -4, 1, 107, -66, -86, 48, -53, -39, 29, -54, -84, 92, 115, -45, -31, -50, 100, -75, -106, 13, 101, -101, 37, -25, -82, 63, -100, 22, 52, 57, 54, 96, 95, -19, -16, 46, -58, -55, 48, 22, 68, -28, 109, 78, 112, 123, 32, -4, -51, 41, -79, -97, 41, 7, -11, 85, -112, 0, -40, -50, 106, -104, 32, 69, 46, 68, -120, -17, -112, -72, -90, -103, 120, -95, 28, 85, 12, 35, 48, -66, 47, 84, -38, 31, -18, 6, -73, -62, 126, 60, -15, -67, 49, 22, 103, 96, -33, -27, -114, 81, -68, 123, 62, 115, 46, -106, 121, -61, -89, -28, -40, 115, 32, -13, 20, -10, 89, 87}; - public static boolean verifyInstallerSignature(ApplicationInfo appInfo) { if ((appInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0) { return true;