Commit Graph
11 Commits
Author SHA1 Message Date
Enginex0 954478b89b perf(interception): optimize ioctl hook hot path for ping latency
Strip LOGV from the buffer parse loop and add a fast pre-check that
peeks at the first binder command before entering the full parser.
Pings, ref ops, and looper management produce no BR_TRANSACTION, so
their buffers can be skipped entirely. Adds __builtin_expect hint
on the transaction branch for better pipeline prediction.

Drops G2 binder ping ratio from 3.95x to 1.17x in debug builds.
2026-03-26 01:59:32 +01:00
Enginex0 191085087b fix(interception): route oversized transactions to software gen
The 256KB native size guard skipped interception entirely for oversized
transactions, causing them to reach the real TEE which returns different
attestation values. This inconsistency is exactly what G10 detects.

Oversized requests now flow through to the Kotlin layer where they hit
doSoftwareKeyGen via the forceGenerate flag. Software gen produces
consistent attestation without forwarding to the real TEE, preserving
the anti-amplification defense that the original guard intended.
2026-03-26 01:30:07 +01:00
Enginex0 aa4917e623 feat(interception): add binder tx code filtering and keystore2 service compliance
Native binder_interceptor now accepts a filtered_codes vector per
registration, skipping JNI round-trip for non-intercepted transaction
codes. Keystore2Interceptor adds getNumberOfEntries software key counting,
deleteKey KEY_ID domain resolution, patchAuthorizations for OS/VENDOR/BOOT
patch levels, importedKeys tracking to prevent stale attest-key overrides,
and nspace consistency fix in the attest-key override path.

InterceptorUtils gains createServiceSpecificErrorReply for AIDL-compliant
error serialization and patchAuthorizations for authorization array patching.
2026-03-19 07:33:11 +01:00
Enginex0 bee73eb39b perf(binder): skip interception for system transaction codes
AIDL methods use codes 1..0x00ffffff. System transactions like
PING_TRANSACTION (0x5f4e4750) fall above that range. Intercepting
pings forces a full JNI round-trip to Java and back, adding enough
latency for timing detectors to flag the ratio (3.85x vs 3.0x
threshold). Early-return for codes above LAST_CALL_TRANSACTION
eliminates this overhead while preserving all AIDL interception.
2026-03-10 16:37:50 +01:00
Enginex0 c332f8ad0d Cap interceptable binder payload size at 256KB
Prevents thread starvation from flood attacks targeting the
binder interceptor with oversized payloads.
2026-02-07 00:47:42 +01:00
Enginex0 34ad97366e feat(module): add supervisor daemon with leak-safe restart and lifecycle scripts
Fork-based supervisor ensures the interceptor process survives crashes.
pingBinder() liveness check on pre-transact returns DEAD_OBJECT to
callers when interceptor is down, preventing real TEE state from leaking
during the restart window.

action.sh clears persistent key storage via KSU Action button.
uninstall.sh kills daemon processes and removes module artifacts while
preserving target.txt and keybox configuration.
2026-02-07 00:47:04 +01:00
JingMatrixandGitHub 5e68cb5f4b Resolve reference leak and warnings in binder interception (#122)
This merge addresses a critical strong reference leak in the ioctl hook that occurred during binder transaction interception. The leak was caused by a double increment of the reference count—once manually and once by a smart pointer's constructor—with only a single corresponding decrement. The fix ensures a balanced increment and decrement, preventing the leak and subsequent crashes.

Additionally, this change:
-   Reverts a now-unnecessary compatibility layer for the Android 11 RefBase ABI.
-   Implements `getInterfaceDescriptor` in the `BinderStub` to silence framework warnings that appeared after the primary leak was fixed.
2026-02-04 09:03:51 +01:00
JingMatrix 1bbc50d138 Prevent recursion when configured to intercept system UID (#100)
When the TEESimulator is configured to intercept UID 1000, accessing the `lazy` `bootKey` property causes a StackOverflowError.

The property's initializer sends a key generation request (UID 0) to probe real hardware. Previously, the C++ layer hijacked this request and spoofed it to UID 1000. This sent the request back to the Kotlin interceptor (if configured so), which attempted to access `bootKey` again to build the response, creating an infinite loop.

This change spoofs UID 0 requests to 1000 (to pass Keystore permissions) but explicitly bypasses hijacking, ensuring the probe request hits the real hardware.
2026-01-28 22:15:27 +01:00
JingMatrixandGitHub 9f77771e7b 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()`.
2026-01-26 14:07:06 +01:00
JingMatrix 612de6cdf2 Add binder transaction interception framework
This commit introduces a comprehensive framework for intercepting and manipulating binder transactions on Android at the `ioctl` level. It provides a man-in-the-middle layer between the binder driver and user-space `libbinder`, enabling detailed analysis and control over IPC.

The core mechanism works by hooking the `ioctl` system call within the context of a target process. It specifically intercepts the `BINDER_WRITE_READ` command's return buffer from the kernel.

Key components of the framework:

- IOCTL Hook: Intercepts `BR_TRANSACTION` commands delivered by the binder driver to the process.
- Transaction Rewriting: If a transaction is intended for a monitored service, its destination is rewritten in-memory to a local `BinderStub`. The original transaction details are saved in a thread-local context.
- BinderStub: A fake binder service that receives the hijacked transaction. It retrieves the original context and delegates processing to the `BinderInterceptor`.
- BinderInterceptor: The central management class. It maintains a registry of monitored binders and their associated callback interfaces. It orchestrates the pre-transact and post-transact hooks.
- Callback Protocol: Defines a clear protocol for a remote tool to:
    - Register and unregister binders for interception.
    - Receive pre-transaction notifications and choose to: continue, modify data, skip the transaction, or provide an immediate fake reply.
    - Receive post-transaction notifications with the final result and modify the reply.
2025-11-25 19:21:05 +01:00
JingMatrix 95262d4b58 Feat: Add 'app' subproject and integrate LSPlt submodule
This commit introduces the main application subproject, 'app', and sets up the necessary infrastructure for the TEESimulator.

Key changes:
*   'app' Subproject Setup: Added the new :app module with its initial structure, including build files, manifest, and Kotlin main entry point.
*   LSPlt Integration: Added the LSPlt hooking framework as a Git submodule in app/src/main/cpp/external/ and configured its use in CMake.
*   Native Build Configuration: Configured the C++ build to use LSPlt statically and compile two essential native libraries: libinject.so (for injection) and libTEESimulator.so (for interception/logic).
*   Module Packaging: Implemented complex Gradle logic within app/build.gradle.kts to automate the creation of a flashable zip module (supporting Magisk, Ksu, and Apatch) with versioning based on Git information.
*   Initial Module Files: Added the template files (module.prop, update-binary, updater-script) for the flashable module structure.
2025-11-22 16:22:27 +01:00