This commit is contained in:
5ec1cff
2024-07-11 21:50:42 +08:00
parent 1fbcfd4654
commit 81ee8bd1e4
8 changed files with 46 additions and 26 deletions

View File

@@ -29,7 +29,7 @@ val verCode by extra(gitCommitCount)
val commitHash by extra(gitCommitHash) val commitHash by extra(gitCommitHash)
val abiList by extra(listOf("arm64-v8a", "x86_64")) 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 androidTargetSdkVersion by extra(34)
val androidCompileSdkVersion by extra(34) val androidCompileSdkVersion by extra(34)
val androidBuildToolsVersion by extra("34.0.0") val androidBuildToolsVersion by extra("34.0.0")

View File

@@ -14,6 +14,12 @@ val verName: String by rootProject.extra
val commitHash: String by rootProject.extra val commitHash: String by rootProject.extra
val abiList: List<String> by rootProject.extra val abiList: List<String> by rootProject.extra
val releaseFlags = arrayOf(
"-Oz", "-flto",
"-Wno-unused", "-Wno-unused-parameter",
"-Wl,--exclude-libs,ALL", "-Wl,--gc-sections",
)
android { android {
defaultConfig { defaultConfig {
ndk { ndk {
@@ -34,6 +40,14 @@ android {
path("src/main/cpp/CMakeLists.txt") path("src/main/cpp/CMakeLists.txt")
} }
} }
buildTypes {
release {
externalNativeBuild.cmake {
cFlags += releaseFlags
cppFlags += releaseFlags
}
}
}
} }
androidComponents.onVariants { variant -> androidComponents.onVariants { variant ->

View File

@@ -3,7 +3,6 @@ project(sample)
set(LINKER_FLAGS "-ffixed-x18 -Wl,--hash-style=both") 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(CXX_FLAGS "${CXX_FLAGS} -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_FLAGS}") 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) add_executable(libinject.so inject/main.cpp inject/utils.cpp)
target_link_libraries(libinject.so lspmparser my_logging) 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) add_library(${MODULE_NAME} SHARED binder_interceptor.cpp)
target_link_libraries(${MODULE_NAME} log binder utils dobby elf_util my_logging) target_link_libraries(${MODULE_NAME} log binder utils dobby elf_util my_logging)
target_compile_options(${MODULE_NAME} PRIVATE -fvisibility=hidden -fvisibility-inlines-hidden)

View File

@@ -290,7 +290,9 @@ bool inject_library(int pid, const char *lib_path, const char* entry_name) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
#ifndef NDEBUG
logging::setPrintEnabled(true); logging::setPrintEnabled(true);
#endif
auto pid = strtol(argv[1], nullptr, 0); auto pid = strtol(argv[1], nullptr, 0);
char buf[4096]; char buf[4096];
realpath(argv[2], buf); realpath(argv[2], buf);

View File

@@ -13,7 +13,8 @@ android {
buildTypes { buildTypes {
release { release {
isMinifyEnabled = false isMinifyEnabled = true
isShrinkResources = true
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"
@@ -23,6 +24,11 @@ android {
kotlinOptions { kotlinOptions {
jvmTarget = "17" jvmTarget = "17"
} }
buildTypes {
release {
signingConfig = signingConfigs["debug"]
}
}
} }
dependencies { dependencies {

View File

@@ -19,3 +19,10 @@
# If you keep the line number information, uncomment this to # If you keep the line number information, uncomment this to
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-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);
}

View File

@@ -16,4 +16,8 @@ public class Logger {
Log.e(TAG, msg, t); Log.e(TAG, msg, t);
} }
public static void i(String msg) {
Log.i(TAG, msg);
}
} }

View File

@@ -119,20 +119,6 @@ fun registerBinderInterceptor(backdoor: IBinder, target: IBinder, interceptor: B
val targetPackages = mutableSetOf<String>() val targetPackages = mutableSetOf<String>()
val DEFAULT_TARGET_PACKAGES = listOf("com.google.android.gms", "icu.nullptr.nativetest", "io.github.vvb2060.mahoshojo", "io.github.vvb2060.keyattestation") 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 var iPm: IPackageManager? = null
fun getPm(): IPackageManager? { fun getPm(): IPackageManager? {
@@ -163,7 +149,7 @@ const val TARGET_FILE = "target.txt"
const val KEYBOX_FILE = "keybox.xml" const val KEYBOX_FILE = "keybox.xml"
class ConfigObserver : FileObserver(CONFIG_PATH, CLOSE_WRITE) { 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?) { override fun onEvent(event: Int, path: String?) {
path ?: return path ?: return
if (event == CLOSE_WRITE) { if (event == CLOSE_WRITE) {
@@ -180,7 +166,7 @@ class ConfigObserver : FileObserver(CONFIG_PATH, CLOSE_WRITE) {
fun tryRunKeystoreInterceptor(): Boolean { fun tryRunKeystoreInterceptor(): Boolean {
val b = ServiceManager.getService("android.system.keystore2.IKeystoreService/default") ?: return false val b = ServiceManager.getService("android.system.keystore2.IKeystoreService/default") ?: return false
b.linkToDeath({ b.linkToDeath({
logD("keystore exit, daemon exit") Logger.d("keystore exit, daemon exit")
exitProcess(0) exitProcess(0)
}, 0) }, 0)
val bd = getBinderBackdoor(b) ?: return true val bd = getBinderBackdoor(b) ?: return true
@@ -195,11 +181,11 @@ fun tryRunKeystoreInterceptor(): Boolean {
data: Parcel data: Parcel
): Result { ): Result {
if (code == targetTransaction) { 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 { kotlin.runCatching {
val ps = getPm()?.getPackagesForUid(callingUid) val ps = getPm()?.getPackagesForUid(callingUid)
if (ps?.any { it in targetPackages } == true) return Continue 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 return Skip
} }
@@ -216,7 +202,7 @@ fun tryRunKeystoreInterceptor(): Boolean {
): Result { ): Result {
if (code != targetTransaction || reply == null) return Skip if (code != targetTransaction || reply == null) return Skip
val p = Parcel.obtain() 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 { try {
reply.readException() reply.readException()
val response = reply.readTypedObject(KeyEntryResponse.CREATOR) val response = reply.readTypedObject(KeyEntryResponse.CREATOR)
@@ -227,7 +213,7 @@ fun tryRunKeystoreInterceptor(): Boolean {
p.writeTypedObject(response, 0) p.writeTypedObject(response, 0)
return OverrideReply(0, p) return OverrideReply(0, p)
} catch (t: Throwable) { } catch (t: Throwable) {
logE("failed to hack certificate chain!", t) Logger.e("failed to hack certificate chain!", t)
p.recycle() p.recycle()
} }
return Skip return Skip
@@ -255,7 +241,7 @@ fun tryRunKeystoreInterceptor(): Boolean {
} }
} }
fun main() { fun main(args: Array<String>) {
while (true) { while (true) {
Thread.sleep(1000) Thread.sleep(1000)
// true -> can inject, false -> service not found, loop -> running // true -> can inject, false -> service not found, loop -> running
@@ -271,7 +257,7 @@ fun main() {
// logD(p.inputStream.readBytes().decodeToString()) // logD(p.inputStream.readBytes().decodeToString())
// logD(p.errorStream.readBytes().decodeToString()) // logD(p.errorStream.readBytes().decodeToString())
if (p.waitFor() != 0) { if (p.waitFor() != 0) {
logE("failed to inject! daemon exit") Logger.e("failed to inject! daemon exit")
exitProcess(1) exitProcess(1)
} }
} }