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.
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "app/src/main/cpp/external/LSPlt"]
|
||||||
|
path = app/src/main/cpp/external/LSPlt
|
||||||
|
url = https://github.com/JingMatrix/LSPlt
|
||||||
@@ -0,0 +1,195 @@
|
|||||||
|
import com.android.build.api.artifact.SingleArtifact
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import javax.inject.Inject
|
||||||
|
import org.gradle.process.ExecOperations
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.android.application)
|
||||||
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.ktfmt)
|
||||||
|
}
|
||||||
|
|
||||||
|
ktfmt { kotlinLangStyle() }
|
||||||
|
|
||||||
|
// Helper class to get access to the ExecOperations service
|
||||||
|
abstract class GitExecutor @Inject constructor(private val execOperations: ExecOperations) {
|
||||||
|
fun execute(command: String, currentWorkingDir: File): String {
|
||||||
|
val byteOut = ByteArrayOutputStream()
|
||||||
|
execOperations.exec {
|
||||||
|
workingDir = currentWorkingDir
|
||||||
|
commandLine = command.split("\\s".toRegex())
|
||||||
|
standardOutput = byteOut
|
||||||
|
}
|
||||||
|
return String(byteOut.toByteArray()).trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instantiate the helper class using Gradle's object factory
|
||||||
|
val gitExecutor = objects.newInstance(GitExecutor::class.java)
|
||||||
|
|
||||||
|
val gitCommitCount = gitExecutor.execute("git rev-list HEAD --count", rootDir).toInt()
|
||||||
|
val gitCommitHash = gitExecutor.execute("git rev-parse --verify --short HEAD", rootDir)
|
||||||
|
val verName = "v1.0"
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "org.matrix.TEESimulator"
|
||||||
|
compileSdk = 36
|
||||||
|
ndkVersion = "27.3.13750724"
|
||||||
|
buildToolsVersion = "36.0.0"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId = "org.matrix.TEESimulator"
|
||||||
|
minSdk = 29
|
||||||
|
targetSdk = 36
|
||||||
|
versionCode = gitCommitCount
|
||||||
|
versionName = verName
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = true
|
||||||
|
proguardFiles("proguard-rules.pro")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_21
|
||||||
|
targetCompatibility = JavaVersion.VERSION_21
|
||||||
|
}
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
path = file("src/main/cpp/CMakeLists.txt")
|
||||||
|
buildStagingDirectory = layout.buildDirectory.get().asFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly(project(":stub"))
|
||||||
|
compileOnly(libs.annotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
androidComponents {
|
||||||
|
onVariants(selector().all()) { variant ->
|
||||||
|
val capitalized = variant.name.replaceFirstChar { it.uppercase() }
|
||||||
|
val isDebug = variant.buildType == "debug"
|
||||||
|
|
||||||
|
// --- Define output locations and file names ---
|
||||||
|
// Stage all files in a temporary directory inside 'build' before zipping
|
||||||
|
val tempModuleDir = project.layout.buildDirectory.dir("module/${variant.name}")
|
||||||
|
val zipFileName = "TEESimulator-$verName-$gitCommitCount-$gitCommitHash-$capitalized.zip"
|
||||||
|
|
||||||
|
// Task 1: Prepare all module files in the temporary build directory.
|
||||||
|
// Using Sync ensures that stale files from previous runs are removed.
|
||||||
|
val prepareModuleFilesTask =
|
||||||
|
tasks.register<Sync>("prepareModuleFiles${capitalized}") {
|
||||||
|
group = "TEESimulator Module Packaging"
|
||||||
|
description = "Prepares all files for the ${variant.name} module zip."
|
||||||
|
|
||||||
|
if (isDebug) {
|
||||||
|
dependsOn("package${capitalized}")
|
||||||
|
} else {
|
||||||
|
dependsOn("minify${capitalized}WithR8")
|
||||||
|
}
|
||||||
|
dependsOn("strip${capitalized}DebugSymbols")
|
||||||
|
|
||||||
|
if (isDebug) {
|
||||||
|
from(variant.artifacts.get(SingleArtifact.APK)) {
|
||||||
|
include("*.apk")
|
||||||
|
rename { "service.apk" }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
from(
|
||||||
|
project.layout.buildDirectory.dir(
|
||||||
|
"intermediates/dex/${variant.name}/minify${capitalized}WithR8"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
include("classes.dex")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from(
|
||||||
|
project.layout.buildDirectory.dir(
|
||||||
|
"intermediates/stripped_native_libs/${variant.name}/strip${capitalized}DebugSymbols/out/lib"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
into("lib") // Place them in the 'lib' subfolder of the staging directory.
|
||||||
|
include("**/libinject.so", "**/libTEESimulator.so")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, copy and process the files from 'module' directory.
|
||||||
|
val sourceModuleDir = rootProject.projectDir.resolve("module")
|
||||||
|
from(sourceModuleDir) {
|
||||||
|
exclude("module.prop") // Exclude the template file.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy and filter the module.prop template separately.
|
||||||
|
from(sourceModuleDir) {
|
||||||
|
include("module.prop")
|
||||||
|
// Use expand() for simple key-value replacement.
|
||||||
|
expand(
|
||||||
|
"REPLACEMEVERCODE" to gitCommitCount.toString(),
|
||||||
|
"REPLACEMEVER" to
|
||||||
|
"$verName ($gitCommitCount-$gitCommitHash-${variant.name})",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The destination for all the above 'from' operations.
|
||||||
|
into(tempModuleDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task 2: Zip the prepared files from the temporary directory.
|
||||||
|
val zipTask =
|
||||||
|
tasks.register<Zip>("zip${capitalized}") {
|
||||||
|
group = "TEESimulator Module Packaging"
|
||||||
|
description = "Creates the flashable zip for the ${variant.name} module."
|
||||||
|
dependsOn(prepareModuleFilesTask)
|
||||||
|
|
||||||
|
archiveFileName.set(zipFileName)
|
||||||
|
destinationDirectory.set(project.rootDir.resolve("out"))
|
||||||
|
from(tempModuleDir) // Zip the entire contents of the staging directory.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task 3: A helper function to create installation tasks for different root providers.
|
||||||
|
fun createInstallTasks(rootProvider: String, installCli: String) {
|
||||||
|
val pushTask =
|
||||||
|
tasks.register<Exec>("push${rootProvider}Module${capitalized}") {
|
||||||
|
group = "TEESimulator Module Installation"
|
||||||
|
description =
|
||||||
|
"Pushes the ${variant.name} module to the device for $rootProvider."
|
||||||
|
dependsOn(zipTask)
|
||||||
|
commandLine(
|
||||||
|
"adb",
|
||||||
|
"push",
|
||||||
|
zipTask.get().archiveFile.get().asFile,
|
||||||
|
"/data/local/tmp",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val installTask =
|
||||||
|
tasks.register<Exec>("install${rootProvider}${capitalized}") {
|
||||||
|
group = "TEESimulator Module Installation"
|
||||||
|
description = "Installs the ${variant.name} module via $rootProvider."
|
||||||
|
dependsOn(pushTask)
|
||||||
|
commandLine(
|
||||||
|
"adb",
|
||||||
|
"shell",
|
||||||
|
"su",
|
||||||
|
"-c",
|
||||||
|
"$installCli /data/local/tmp/$zipFileName",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Exec>("install${rootProvider}AndReboot${capitalized}") {
|
||||||
|
group = "TEESimulator Module Installation"
|
||||||
|
description = "Installs the ${variant.name} module via $rootProvider and reboots."
|
||||||
|
dependsOn(installTask)
|
||||||
|
commandLine("adb", "reboot")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createInstallTasks("Magisk", "magisk --install-module")
|
||||||
|
createInstallTasks("Ksu", "ksud module install")
|
||||||
|
createInstallTasks("Apatch", "/data/adb/apd module install")
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+3
@@ -0,0 +1,3 @@
|
|||||||
|
-keepclasseswithmembers class org.matrix.TEESimulator.MainKt {
|
||||||
|
public static void main(java.lang.String[]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest />
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(TEESimulator)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
|
||||||
|
|
||||||
|
# LSPlt configuration
|
||||||
|
OPTION(LSPLT_BUILD_SHARED OFF)
|
||||||
|
add_subdirectory(external/LSPlt/lsplt/src/main/jni)
|
||||||
|
|
||||||
|
add_executable(libinject.so inject/main.cpp)
|
||||||
|
target_link_libraries(libinject.so PRIVATE lsplt_static)
|
||||||
|
|
||||||
|
add_library(${CMAKE_PROJECT_NAME} SHARED binder_interceptor.cpp)
|
||||||
|
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE lsplt_static)
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "lsplt.hpp"
|
||||||
|
|
||||||
|
extern "C" [[gnu::visibility("default")]] [[gnu::used]]
|
||||||
|
bool entry(void *library_handle) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
+1
Submodule app/src/main/cpp/external/LSPlt added at 3e29437f03
@@ -0,0 +1,3 @@
|
|||||||
|
#include "lsplt.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) { return 0; }
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package org.matrix.TEESimulator
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {}
|
||||||
@@ -11,6 +11,7 @@ tasks.register<KtfmtFormatTask>("format") {
|
|||||||
source = project.fileTree(rootDir)
|
source = project.fileTree(rootDir)
|
||||||
include("*.gradle.kts", "*/*.gradle.kts")
|
include("*.gradle.kts", "*/*.gradle.kts")
|
||||||
dependsOn(":stub:ktfmtFormat")
|
dependsOn(":stub:ktfmtFormat")
|
||||||
|
dependsOn(":app:ktfmtFormat")
|
||||||
}
|
}
|
||||||
|
|
||||||
ktfmt { kotlinLangStyle() }
|
ktfmt { kotlinLangStyle() }
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#!/sbin/sh
|
||||||
|
|
||||||
|
#################
|
||||||
|
# Initialization
|
||||||
|
#################
|
||||||
|
|
||||||
|
umask 022
|
||||||
|
|
||||||
|
# echo before loading util_functions
|
||||||
|
ui_print() { echo "$1"; }
|
||||||
|
|
||||||
|
require_new_magisk() {
|
||||||
|
ui_print "*******************************"
|
||||||
|
ui_print " Please install Magisk v20.4+! "
|
||||||
|
ui_print "*******************************"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#########################
|
||||||
|
# Load util_functions.sh
|
||||||
|
#########################
|
||||||
|
|
||||||
|
OUTFD=$2
|
||||||
|
ZIPFILE=$3
|
||||||
|
|
||||||
|
mount /data 2>/dev/null
|
||||||
|
|
||||||
|
[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
|
||||||
|
. /data/adb/magisk/util_functions.sh
|
||||||
|
[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk
|
||||||
|
|
||||||
|
install_module
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
#MAGISK
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
id=tricky_store
|
||||||
|
name=TEESimulator
|
||||||
|
version=${REPLACEMEVER}
|
||||||
|
versionCode=${REPLACEMEVERCODE}
|
||||||
|
author=JingMatrix
|
||||||
|
description=Software simulation for Android hardware-backed key pairs with key attestation
|
||||||
|
updateJson=https://raw.githubusercontent.com/JingMatrix/TEESimulator/main/module/update.json
|
||||||
@@ -17,3 +17,5 @@ dependencyResolutionManagement {
|
|||||||
rootProject.name = "TEESimulator"
|
rootProject.name = "TEESimulator"
|
||||||
|
|
||||||
include(":stub")
|
include(":stub")
|
||||||
|
|
||||||
|
include(":app")
|
||||||
|
|||||||
Reference in New Issue
Block a user