diff --git a/build.gradle.kts b/build.gradle.kts index 22e4a07..69f3271 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,8 @@ import com.android.build.gradle.AppExtension import com.android.build.gradle.LibraryExtension +import org.jetbrains.kotlin.daemon.common.toHexString import java.io.ByteArrayOutputStream +import java.security.MessageDigest plugins { alias(libs.plugins.agp.app) apply false @@ -24,11 +26,25 @@ val gitCommitHash = "git rev-parse --verify --short HEAD".execute() // also the soname val moduleId by extra("tricky_store") val moduleName by extra("Tricky Store") +val author by extra("5ec1cff") +val description by extra("A trick of keystore") val verName by extra("v1.0.3") val verCode by extra(gitCommitCount) val commitHash by extra(gitCommitHash) val abiList by extra(listOf("arm64-v8a", "x86_64")) +fun calculateChecksum(): String { + return MessageDigest.getInstance("SHA-256").run { + update(moduleId.toByteArray(Charsets.UTF_8)) + update(moduleName.toByteArray(Charsets.UTF_8)) + update(verName.toByteArray(Charsets.UTF_8)) + update(verCode.toString().toByteArray(Charsets.UTF_8)) + update(author.toByteArray(Charsets.UTF_8)) + update(description.toByteArray(Charsets.UTF_8)) + digest().toHexString() + } +} + val androidMinSdkVersion by extra(31) val androidTargetSdkVersion by extra(34) val androidCompileSdkVersion by extra(34) diff --git a/module/build.gradle.kts b/module/build.gradle.kts index 4e77b02..500fca0 100644 --- a/module/build.gradle.kts +++ b/module/build.gradle.kts @@ -15,6 +15,9 @@ val verName: String by rootProject.extra val commitHash: String by rootProject.extra val abiList: List by rootProject.extra val androidMinSdkVersion: Int by rootProject.extra +val author: String by rootProject.extra +val description: String by rootProject.extra +val moduleDescription = description android { defaultConfig { @@ -91,7 +94,9 @@ androidComponents.onVariants { variant -> "moduleId" to moduleId, "moduleName" to moduleName, "versionName" to "$verName ($verCode-$commitHash-$variantLowered)", - "versionCode" to verCode + "versionCode" to verCode, + "author" to author, + "description" to moduleDescription, ) } from(layout.projectDirectory.file("template")) { diff --git a/module/template/module.prop b/module/template/module.prop index 7fe0ac9..acd5150 100644 --- a/module/template/module.prop +++ b/module/template/module.prop @@ -2,6 +2,6 @@ id=${moduleId} name=${moduleName} version=${versionName} versionCode=${versionCode} -author=5ec1cff -description=A trick of keystore +author=${author} +description=${description} #updateJson= diff --git a/service/build.gradle.kts b/service/build.gradle.kts index 01d3db1..c4667f7 100644 --- a/service/build.gradle.kts +++ b/service/build.gradle.kts @@ -1,10 +1,33 @@ import android.databinding.tool.ext.capitalizeUS +import org.jetbrains.kotlin.daemon.common.toHexString +import java.security.MessageDigest plugins { alias(libs.plugins.jetbrains.kotlin.android) alias(libs.plugins.agp.app) } +val moduleId: String by rootProject.extra +val moduleName: String by rootProject.extra +val verCode: Int by rootProject.extra +val verName: String by rootProject.extra +val commitHash: String by rootProject.extra +val author: String by rootProject.extra +val description: String by rootProject.extra +val moduleDescription = description + +fun calculateChecksum(variantLowered: String): String { + return MessageDigest.getInstance("SHA-256").run { + update(moduleId.toByteArray(Charsets.UTF_8)) + update(moduleName.toByteArray(Charsets.UTF_8)) + update("$verName ($verCode-$commitHash-$variantLowered)".toByteArray(Charsets.UTF_8)) + update(verCode.toString().toByteArray(Charsets.UTF_8)) + update(author.toByteArray(Charsets.UTF_8)) + update(description.toByteArray(Charsets.UTF_8)) + digest().toHexString() + } +} + android { namespace = "io.github.a13e300.tricky_store" compileSdk = 34 @@ -22,6 +45,10 @@ android { "proguard-rules.pro" ) } + forEach { + val checksum = calculateChecksum(it.name) + it.buildConfigField("String", "CHECKSUM", "\"$checksum\"") + } } kotlinOptions { @@ -44,6 +71,11 @@ android { checkReleaseBuilds = false abortOnError = true } + + buildFeatures { + buildConfig = true + } + } dependencies { diff --git a/service/src/main/java/io/github/a13e300/tricky_store/Main.kt b/service/src/main/java/io/github/a13e300/tricky_store/Main.kt index 15033d3..27eff8c 100644 --- a/service/src/main/java/io/github/a13e300/tricky_store/Main.kt +++ b/service/src/main/java/io/github/a13e300/tricky_store/Main.kt @@ -1,6 +1,11 @@ package io.github.a13e300.tricky_store +import java.io.File +import java.security.MessageDigest +import kotlin.system.exitProcess + fun main(args: Array) { + verifySelf() Logger.i("Welcome to TrickyStore!") while (true) { if (!KeystoreInterceptor.tryRunKeystoreInterceptor()) { @@ -13,3 +18,42 @@ fun main(args: Array) { } } } + +@OptIn(ExperimentalStdlibApi::class) +fun verifySelf() { + val kv = mutableMapOf() + val prop = File("./module.prop") + runCatching { + if (prop.canonicalPath != "/data/adb/modules/tricky_store/module.prop") error("wrong directory ${prop.canonicalPath}!") + prop.forEachLine(Charsets.UTF_8) { + val a = it.split("=", limit = 2) + if (a.size != 2) return@forEachLine + kv[a[0]] = a[1] + } + val checksum = MessageDigest.getInstance("SHA-256").run { + update(kv["id"]!!.toByteArray(Charsets.UTF_8)) + update(kv["name"]!!.toByteArray(Charsets.UTF_8)) + update(kv["version"]!!.toByteArray(Charsets.UTF_8)) + update(kv["versionCode"]!!.toByteArray(Charsets.UTF_8)) + update(kv["author"]!!.toByteArray(Charsets.UTF_8)) + update(kv["description"]!!.toByteArray(Charsets.UTF_8)) + digest().toHexString() + } + if (checksum != BuildConfig.CHECKSUM) { + Logger.e("unverified module files! ($checksum != ${BuildConfig.CHECKSUM})") + prop.writeText(kv.entries.joinToString("\n") { (k, v) -> + when (k) { + "description" -> "description=×Module files corrupted, please re-download it from github.com/5ec1cff/TrickyStore" + "author" -> "author=5ec1cff" + else -> "$k=$v" + } + }) + File("./remove").createNewFile() + exitProcess(1) + } + Logger.d("verify success!") + }.onFailure { + Logger.e("error while verifying self", it) + exitProcess(1) + } +}