Fix Android 11 Keystore execution: Init framework and spoof UID 1000 (#85)

This commit resolves `KeyStore` API failures on Android 11 when running as a standalone CLI executable (UID 0), addressing both environment initialization and permission denial issues.

1. Initialize Android Framework Environment:
   Android 11 Keystore APIs expect a fully initialized application context and a Main Looper, which are missing in a raw root process. This patch:
   - Manually bootstraps `ActivityThread` via `systemMain()`.
   - Initializes `Looper.prepareMainLooper()`.
   - Injects a dummy `Application` object attached to the system context to satisfy `KeyStore.getApplicationContext()` checks.
   - Updates framework stubs to allow compilation of these hidden APIs.

2. Bypass Keystore Permission Checks via UID Spoofing:
   `KeyStoreService::generateKey` enforces the `P_INSERT` permission. Analysis of `permissions.cpp` reveals that UID 0 (Root) is explicitly denied this permission (granted only `P_GET`), whereas UID 1000 (System) holds all permissions (`~0`).
   
   To bypass this restriction, the binder interceptor now detects transactions originating from UID 0 and rewrites the `sender_euid` to 1000. This fools `KeyStoreService` into granting the request.
 
3. Refactor Execution Loop:
   Replaces the previous `Thread.sleep()` maintenance loop with `Looper.loop()`.
This commit is contained in:
JingMatrix
2026-01-26 14:07:06 +01:00
committed by GitHub
parent 205fda43ba
commit 151410c75e
4 changed files with 62 additions and 15 deletions
+9
View File
@@ -386,6 +386,15 @@ void inspectAndRewriteTransaction(binder_transaction_data *txn_data) {
}
if (hijack) {
// The kernel driver fills sender_euid. libbinder trusts this value
// to populate IPCThreadState. By changing it here, we fool the
// entire process (including the TEE implementation) into thinking
// the call came from system (1000).
if (txn_data->sender_euid == 0) {
LOGV("[Hook] Spoofing UID for transaction: 0 -> 1000");
txn_data->sender_euid = 1000;
}
uint64_t tx_id = ++g_transaction_id_counter;
info.transaction_id = tx_id;