diff --git a/build.gradle.kts b/build.gradle.kts index 29d908f..4beddc7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ val verCode by extra(gitCommitCount) val commitHash by extra(gitCommitHash) val abiList by extra(listOf("arm64-v8a", "x86_64")) -val androidMinSdkVersion by extra(26) +val androidMinSdkVersion by extra(31) val androidTargetSdkVersion by extra(34) val androidCompileSdkVersion by extra(34) val androidBuildToolsVersion by extra("34.0.0") diff --git a/module/build.gradle.kts b/module/build.gradle.kts index e40d1be..12d3bac 100644 --- a/module/build.gradle.kts +++ b/module/build.gradle.kts @@ -14,6 +14,12 @@ val verName: String by rootProject.extra val commitHash: String by rootProject.extra val abiList: List by rootProject.extra +val releaseFlags = arrayOf( + "-Oz", "-flto", + "-Wno-unused", "-Wno-unused-parameter", + "-Wl,--exclude-libs,ALL", "-Wl,--gc-sections", +) + android { defaultConfig { ndk { @@ -34,6 +40,14 @@ android { path("src/main/cpp/CMakeLists.txt") } } + buildTypes { + release { + externalNativeBuild.cmake { + cFlags += releaseFlags + cppFlags += releaseFlags + } + } + } } androidComponents.onVariants { variant -> diff --git a/module/src/main/cpp/CMakeLists.txt b/module/src/main/cpp/CMakeLists.txt index ee13a33..d7c8dc6 100644 --- a/module/src/main/cpp/CMakeLists.txt +++ b/module/src/main/cpp/CMakeLists.txt @@ -3,7 +3,6 @@ project(sample) set(LINKER_FLAGS "-ffixed-x18 -Wl,--hash-style=both") -# TODO: set visibility only for our libs (-fvisibility=hidden -fvisibility-inlines-hidden) set(CXX_FLAGS "${CXX_FLAGS} -fno-exceptions -fno-rtti") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS}") @@ -37,6 +36,8 @@ target_link_libraries(binder utils) add_executable(libinject.so inject/main.cpp inject/utils.cpp) target_link_libraries(libinject.so lspmparser my_logging) +target_compile_options(libinject.so PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden) add_library(${MODULE_NAME} SHARED binder_interceptor.cpp) target_link_libraries(${MODULE_NAME} log binder utils dobby elf_util my_logging) +target_compile_options(${MODULE_NAME} PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden) diff --git a/module/src/main/cpp/inject/main.cpp b/module/src/main/cpp/inject/main.cpp index 0fe6c7d..7da8aeb 100644 --- a/module/src/main/cpp/inject/main.cpp +++ b/module/src/main/cpp/inject/main.cpp @@ -290,7 +290,9 @@ bool inject_library(int pid, const char *lib_path, const char* entry_name) { } int main(int argc, char **argv) { +#ifndef NDEBUG logging::setPrintEnabled(true); +#endif auto pid = strtol(argv[1], nullptr, 0); char buf[4096]; realpath(argv[2], buf); diff --git a/service/build.gradle.kts b/service/build.gradle.kts index 9a8e041..eb92a16 100644 --- a/service/build.gradle.kts +++ b/service/build.gradle.kts @@ -13,7 +13,8 @@ android { buildTypes { release { - isMinifyEnabled = false + isMinifyEnabled = true + isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" @@ -23,6 +24,11 @@ android { kotlinOptions { jvmTarget = "17" } + buildTypes { + release { + signingConfig = signingConfigs["debug"] + } + } } dependencies { diff --git a/service/proguard-rules.pro b/service/proguard-rules.pro index 481bb43..082bf02 100644 --- a/service/proguard-rules.pro +++ b/service/proguard-rules.pro @@ -18,4 +18,11 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile +-keepclasseswithmembers class io.github.a13e300.tricky_store.MainKt { + public static void main(java.lang.String[]); +} + +-assumenosideeffects class io.github.a13e300.tricky_store.Logger { + public static void d(java.lang.String); +} diff --git a/service/src/main/java/io/github/a13e300/tricky_store/Logger.java b/service/src/main/java/io/github/a13e300/tricky_store/Logger.java index bebd1b3..43bc0ac 100644 --- a/service/src/main/java/io/github/a13e300/tricky_store/Logger.java +++ b/service/src/main/java/io/github/a13e300/tricky_store/Logger.java @@ -16,4 +16,8 @@ public class Logger { Log.e(TAG, msg, t); } + public static void i(String msg) { + Log.i(TAG, msg); + } + } 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 c610843..1e19458 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 @@ -119,20 +119,6 @@ fun registerBinderInterceptor(backdoor: IBinder, target: IBinder, interceptor: B val targetPackages = mutableSetOf() val DEFAULT_TARGET_PACKAGES = listOf("com.google.android.gms", "icu.nullptr.nativetest", "io.github.vvb2060.mahoshojo", "io.github.vvb2060.keyattestation") -const val TAG = "TrickyStore" - -fun logD(msg: String) { - Log.d(TAG, msg) -} - -fun logE(msg: String, t: Throwable? = null) { - if (t == null) { - Log.e(TAG, msg) - } else { - Log.e(TAG, msg, t) - } -} - var iPm: IPackageManager? = null fun getPm(): IPackageManager? { @@ -163,7 +149,7 @@ const val TARGET_FILE = "target.txt" const val KEYBOX_FILE = "keybox.xml" class ConfigObserver : FileObserver(CONFIG_PATH, CLOSE_WRITE) { - val root = File(CONFIG_PATH) + private val root = File(CONFIG_PATH) override fun onEvent(event: Int, path: String?) { path ?: return if (event == CLOSE_WRITE) { @@ -180,7 +166,7 @@ class ConfigObserver : FileObserver(CONFIG_PATH, CLOSE_WRITE) { fun tryRunKeystoreInterceptor(): Boolean { val b = ServiceManager.getService("android.system.keystore2.IKeystoreService/default") ?: return false b.linkToDeath({ - logD("keystore exit, daemon exit") + Logger.d("keystore exit, daemon exit") exitProcess(0) }, 0) val bd = getBinderBackdoor(b) ?: return true @@ -195,11 +181,11 @@ fun tryRunKeystoreInterceptor(): Boolean { data: Parcel ): Result { if (code == targetTransaction) { - logD("intercept pre $target uid=$callingUid pid=$callingPid dataSz=${data.dataSize()}") + Logger.d("intercept pre $target uid=$callingUid pid=$callingPid dataSz=${data.dataSize()}") kotlin.runCatching { val ps = getPm()?.getPackagesForUid(callingUid) if (ps?.any { it in targetPackages } == true) return Continue - }.onFailure { logE("failed to get packages", it) } + }.onFailure { Logger.e("failed to get packages", it) } } return Skip } @@ -216,7 +202,7 @@ fun tryRunKeystoreInterceptor(): Boolean { ): Result { if (code != targetTransaction || reply == null) return Skip val p = Parcel.obtain() - logD("intercept post $target uid=$callingUid pid=$callingPid dataSz=${data.dataSize()} replySz=${reply.dataSize()}") + Logger.d("intercept post $target uid=$callingUid pid=$callingPid dataSz=${data.dataSize()} replySz=${reply.dataSize()}") try { reply.readException() val response = reply.readTypedObject(KeyEntryResponse.CREATOR) @@ -227,7 +213,7 @@ fun tryRunKeystoreInterceptor(): Boolean { p.writeTypedObject(response, 0) return OverrideReply(0, p) } catch (t: Throwable) { - logE("failed to hack certificate chain!", t) + Logger.e("failed to hack certificate chain!", t) p.recycle() } return Skip @@ -255,7 +241,7 @@ fun tryRunKeystoreInterceptor(): Boolean { } } -fun main() { +fun main(args: Array) { while (true) { Thread.sleep(1000) // true -> can inject, false -> service not found, loop -> running @@ -271,7 +257,7 @@ fun main() { // logD(p.inputStream.readBytes().decodeToString()) // logD(p.errorStream.readBytes().decodeToString()) if (p.waitFor() != 0) { - logE("failed to inject! daemon exit") + Logger.e("failed to inject! daemon exit") exitProcess(1) } }