Commit Graph
22 Commits
Author SHA1 Message Date
JingMatrix 9146b86648 Preserve extension order and prevent duplicates
This commit refactors the attestation patching logic to improve stealth and ensure correctness by addressing potential detection vectors related to the ASN.1 structure of the certificate extension.

1. Preserve Extension Order: The original implementation rebuilt the entire certificate, which could alter the order of X.509 extensions. Some verification systems may be sensitive to this order. The logic is now updated to replace the attestation extension in-place, preserving the original order of all other extensions.

2. Avoid Duplicate Properties: The previous logic used an `ASN1EncodableVector` to assemble TEE-enforced properties. This could lead to duplicate entries if a property (e.g., `OS_VERSION`) was present in the original certificate and also added by the simulator. The code now uses a `MutableMap` keyed by the ASN.1 tag number. This ensures that any simulated properties overwrite the original ones, preventing duplicates and potential parsing errors.

3. Add Detailed Logging: A recursive ASN.1 formatting function has been added to provide clear and readable logs of the certificate data both before and after patching. This significantly improves debuggability.

By ensuring the patched certificate is structurally as close as possible to the original, these changes reduce the chances of the simulator being detected by attestation validation services.
2025-11-29 19:58:02 +01:00
JingMatrix 457a58da04 Patch certificate chain in generateKey reply
When an application generates a key with an attestation request, the `generateKey` method returns a `KeyMetadata` object which contains the full, unpatched certificate chain.

This leaves a potential detection vector open. A sophisticated application could inspect the returned data in its own process memory and discover the original, hardware-backed certificates before they are used for attestation, thus detecting the hooking framework.

This commit introduces a post-transaction hook for the `generateKey` transaction. After the genuine KeyStore service has executed the request, this hook intercepts the reply parcel. It extracts the certificate chain from the `KeyMetadata`, applies the patching routine, and then reconstructs the reply with the modified (patched) certificate chain.
2025-11-29 19:58:02 +01:00
JingMatrixandGitHub b2838ac04b Add support for Android 11 RefBase ABI (#29)
Implements a compatibility layer to allow the binary to run on
Android 11 (API 30) and older, which lack the `incStrongRequireStrong`
symbol in their `libutils.so`.

This is achieved by creating a runtime wrapper that checks the device's
SDK version.
- On Android 12 (API 31) and newer, it dynamically loads and calls the
  `incStrongRequireStrong` function using `dlsym`.
- On older versions, it safely falls back to the universally available
  `incStrong` method.

This resolves the fatal `dlopen` error "cannot locate symbol" when
injecting the library into processes on older Android versions.

See AOSP change
https://android-review.googlesource.com/c/platform/system/core/+/1660499
2025-11-29 19:29:48 +01:00
JingMatrixandGitHub a7534feac7 Fix software enforced list for certificates generation (#28)
Properly implement the `ATTESTATION_APPLICATION_ID` tag into key description.

Moreover, we add the `ATTESTATION_ID_SERIAL` tag to the TEE enforced list, and re-order all tags to remain consistent with the object `AttestationConstants`.
2025-11-29 14:20:58 +01:00
JingMatrix 4e67371193 Release TEESimulator v2.1 2025-11-28 20:00:07 +01:00
JingMatrixandGitHub 2ef89f15c6 Fix date format of vendor patch level (#24)
This was a mistake during the refactoring of TrickyStoreOSS.
After correcting it, we can obtain STRONG integrity (instead of DEVICE) with a valid keybox.

The correct format can be easily found using the `Key Attestation` app.
2025-11-28 19:45:53 +01:00
JingMatrixandGitHub 4f608247fe Set boot digest via resetprop (#22)
The stub method `SystemProperties.set` has wrong signature and is unable to set read-only system properties.
2025-11-28 13:11:54 +01:00
JingMatrixandGitHub 5afefba7bd Clean up cached keys on successful import (#18)
Generated and attestation keys are cached, and if a key is imported with the same name, the cached key would be returned instead of the newly imported one.

This change invalidates the cached key when a key is successfully imported with the same alias.
Close #17 as fixed.

The logging has also been improved to be more consistent across the different interceptors.
2025-11-27 15:43:56 +01:00
JingMatrix ba9578c59b Prepare to release TEESimulator 2.0
The following two bugs are fixed:
1. `zygisk.json` is renamed to `update.json`, which is indicated in `module.prop`.
2. To avoid over optimization of R8, we must keep certains packages, which are found after many experiments.
2025-11-26 18:34:08 +01:00
JingMatrixandGitHub 733e64c3cb Support key generation with attestation keys (#15)
This commit enhances the interception logic to correctly handle key
generation requests that specify an `attestationKey` (via
`setAttestKeyAlias`).

When an attestation key is used, the system signs the newly generated
key with it. A simple leaf certificate patch after the fact is
insufficient, as it breaks this cryptographic chain. To create a valid,
verifiable chain, we must now intercept these `generateKey` operations
and perform a full software-based key and certificate generation, even
when in patch mode.

This ensures that keys attested by other simulated keys are correctly
signed and chained together, bypassing more sophisticated detection
methods.

Fixes:
- Correctly use the `android.hardware.security.keymint.Tag` constants for
  building authorization lists, resolving a bug where internal ASN.1
  sequence indices were being used improperly.
2025-11-26 16:50:30 +01:00
JingMatrixandGitHub 7f94ba4b5b Improve logging to understand detection methods (#14)
Via extensive and detailed logging, we can inspect various detection techniques of target packages.
2025-11-26 11:43:53 +01:00
JingMatrixandGitHub fa1d9ecc56 Bypass detection by skipping imported keys (#12)
In patch mode, a key's origin provides a robust way to avoid modifying
user-imported keys, which is a well-known detection vector. This commit
implements a new strategy to check the `KeyOrigin` tag from the key's
metadata. If a key is marked as `IMPORTED` or `SECURELY_IMPORTED`, the
patching process is now skipped entirely.

This new origin-based check is more reliable and cleaner than the
previous fingerprinting implementation, which has been removed.

Additionally, this commit acknowledges a remaining detection vector in
patch mode: when an `attestationKey` is used, a key must be generated.
Purely software-generated keys are detectable. To address this in the
future, the full software "generate mode" must be implemented even for
devices without a broken TEE. The old key generation logic has been
stubbed with a TODO in preparation for this redesign.
2025-11-26 02:54:43 +01:00
JingMatrix eec9e77631 Add GitHub CI build config 2025-11-26 00:19:05 +01:00
JingMatrix d18692fbef Add module template files
Current AOSP keybox can be found at:
https://cs.android.com/android/platform/superproject/main/+/main:device/generic/trusty/keymaster_soft_wrapped_attestation_keys.xml

However, the support of parsing private keys in iecs format is not implemented yet.
2025-11-26 00:19:05 +01:00
JingMatrix 13b4786cd9 Restructure and overhaul entire Kotlin codebase
This commit introduces a complete architectural refactoring of the
Kotlin-based interception logic, based on the source of
1. https://github.com/5ec1cff/TrickyStore
2. https://github.com/beakthoven/TrickyStoreOSS

The primary purpose of this code is to intercept binder transactions to
the Android Keystore and KeyMint services. The overall workflow operates
in conjunction with a native library (injected via ptrace). The native
library hooks the binder's `transact` function and forwards pre- and
post-transaction events to the Kotlin side. This Kotlin code contains
all the high-level logic for parsing parameters, patching certificates,
and generating simulated keys.

The codebase is now organized into a clear, package-based architecture:

- attestation: Manages the creation and patching of ASN.1 attestation
  data structures.
- config: Handles loading and observing configuration files from disk.
- interception: Contains the core binder interception framework and its
  specific implementations for legacy Keystore (Android Q/R) and modern
  KeyMint/Keystore2 (Android S+).
- logging: Provides a centralized and consistent logging utility.
- pki: Manages Public Key Infrastructure, including certificate
  generation, parsing of key store XML files, and cryptographic helpers.
- util: Contains Android-specific utility functions for device properties.

This refactoring focuses on establishing a robust and extensible
architecture. The fine-tuning of the interception logic itself,
especially for corner cases in key generation and patching, is currently
under redesign and will be further refined in subsequent commits.
2025-11-26 00:19:01 +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 020a930a31 Add stub for AOSP Binder and utility components
The primary function of these stubs is to provide necessary interface definitions and that can be utilized by `binder_interceptor.cpp` during compilation (and runtime).

Crucially, `libTEESimulator.so` (which encapsulates these stubs) is dynamically loaded into the target process via `ptrace` after the system's official libraries, such as `/system/lib64/libbinder.so` and `/system/lib64/libutils.so`, have already been loaded and their symbols resolved by the dynamic linker.

Consequently, the dynamic linker will have already established bindings to the robust, canonical implementations within the system libraries for existing code paths. The dynamic linker does not automatically re-resolve or update these established symbol bindings when a new library with conflicting definitions is loaded later.

The AOSP files are downloaded via links:
1. https://android.googlesource.com/platform/frameworks/native/+/refs/heads/main/libs/binder/include/binder
2. https://android.googlesource.com/platform/system/core/+/refs/heads/main/libutils/binder/include/utils

The link for binder header in Android kernel is:
https://cs.android.com/android/kernel/superproject/+/common-android-mainline:common/include/uapi/linux/android/binder.h
2025-11-25 19:21:05 +01:00
JingMatrix 0c1937bd3e Implement shared library injection via ptrace
There are still many functions in the header `utils.hpp` not implemented yet, which are however not needed for our purpose.
2025-11-25 19:20:59 +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
JingMatrix ad4e772eb4 Introduce stub module and initial Gradle project setup
This commit establishes the foundational Gradle project structure and introduces a dedicated 'stub' module. This module provides skeletal implementations of internal Android framework interfaces and classes, which are critical for compiling the TEESimulator project.

Stub classes are minimal implementations of existing interfaces or classes, typically mirroring those found within the Android framework, particularly for internal or hidden APIs. Their methods usually contain no operational logic and instead throw RuntimeException or UnsupportedOperationException.

The primary reasons for using stub classes are:

1. Compilation Against Internal APIs: Android applications and libraries typically use public APIs exposed by the Android SDK. However, in scenarios requiring deeper system integration or emulation, interaction with internal or hidden Android framework APIs might be necessary. Directly linking against the full Android framework JAR can lead to bootclasspath conflicts or other build issues. Stub classes provide the necessary API signatures for compilation without including the actual implementations, allowing the build system to resolve references while deferring the actual functionality to the runtime environment (the Android OS itself).

2. API Consistency and Simulation: For TEESimulator, which aims to provide a software simulation for Android's hardware-backed key pairs (KeyMint/Keystore2), stub classes define the required API contract. They ensure that the simulator's components compile against the exact interface definitions of the Android system services, making the simulation functionally consistent with the expected system behavior without needing to bundle or depend on the entire Android framework at compile time. This ensures that the simulator correctly interacts with the defined KeyMint and Keystore2 API shapes.
2025-11-22 15:24:43 +01:00
JingMatrix 2ac2518216 Add GPL V3 licence 2025-11-22 10:34:59 +01:00
JingMatrix 79de0be122 Set-up the ultimate goal of TEESimulator
This project is based on TrickyStore and TrickyStoreOSS.
However, there is no detailed comments / docs in their source code, rendering it diffcult for welcoming new contributors.

A robust framework should has robust source code with clear documentation.
2025-11-22 10:15:46 +01:00