Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

Commit

Permalink
Allow specify target application to inject
Browse files Browse the repository at this point in the history
Let companion read target app list and send to apps. Default
app is Key Attestation.
  • Loading branch information
aviraxp committed Jul 14, 2024
1 parent 7a5df37 commit 610ff2c
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 12 deletions.
60 changes: 53 additions & 7 deletions app/src/main/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
#include <sys/system_properties.h>
#include <string>
#include <vector>
#include <sstream>
#include <unistd.h>
#include "zygisk.hpp"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "PIF", __VA_ARGS__)

#define CLASSES_DEX "/data/adb/modules/keystoreinjection/classes.dex"

#define KEYBOX_FILE_PATH "/data/adb/keybox.xml"
#define APPLIST_FILE_PATH "/data/adb/keystoreinjection/targetlist"
#define KEYBOX_FILE_PATH "/data/adb/keystoreinjection/keybox.xml"

ssize_t xread(int fd, void *buffer, size_t count) {
ssize_t total = 0;
Expand Down Expand Up @@ -37,6 +38,18 @@ ssize_t xwrite(int fd, void *buffer, size_t count) {
return total;
}

std::vector<std::string> split(const std::string &strTotal) {
std::vector<std::string> vecResult;
std::istringstream iss(strTotal);
std::string token;

while (std::getline(iss, token, '\n')) {
vecResult.push_back("/" + token);
}

return std::move(vecResult);
}

class KeystoreInjection : public zygisk::ModuleBase {
public:
void onLoad(zygisk::Api *api, JNIEnv *env) override {
Expand All @@ -55,13 +68,41 @@ class KeystoreInjection : public zygisk::ModuleBase {

std::string dir(rawDir);
env->ReleaseStringUTFChars(args->app_data_dir, rawDir);
if (!dir.ends_with("/io.github.vvb2060.keyattestation")) {

int fd = api->connectCompanion();

// Check target app and return earlier if not related
long applistSize = 0;
xread(fd, &applistSize, sizeof(long));

if (applistSize < 1) {
close(fd);
return;
}

long dexSize = 0, xmlSize = 0;
std::vector<uint8_t> applistVector;
applistVector.resize(applistSize);
xread(fd, applistVector.data(), applistSize);

// Generate split app list
std::string applist(applistVector.begin(), applistVector.end());
std::vector<std::string> splitlist= split(applist);

// Find target app
bool found = false;
for (const std::string& app : splitlist) {
if (dir.ends_with(app)) {
found = true;
break;
}
}

int fd = api->connectCompanion();
if (!found) {
close(fd);
return;
}

long dexSize = 0, xmlSize = 0;

xread(fd, &dexSize, sizeof(long));
xread(fd, &xmlSize, sizeof(long));
Expand Down Expand Up @@ -153,15 +194,20 @@ static std::vector<uint8_t> readFile(const char *path) {
}

static void companion(int fd) {
std::vector<uint8_t> applistVector, dexVector, xmlVector;

std::vector<uint8_t> dexVector, xmlVector;

applistVector = readFile(APPLIST_FILE_PATH);
dexVector = readFile(CLASSES_DEX);
xmlVector = readFile(KEYBOX_FILE_PATH);

long applistSize = applistVector.size();
long dexSize = dexVector.size();
long xmlSize = xmlVector.size();

xwrite(fd, &applistSize, sizeof(long));
// Write applist earlier, so we can avoid reading dex for unrelated apps
xwrite(fd, applistVector.data(), applistSize);

xwrite(fd, &dexSize, sizeof(long));
xwrite(fd, &xmlSize, sizeof(long));

Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
buildscript {
val agp_version by extra("8.5.0")
val agp_version by extra("8.5.1")
}
plugins {
id("com.android.application") version "8.5.0" apply false
id("com.android.application") version "8.5.1" apply false
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#Thu Apr 18 12:59:17 CEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
15 changes: 14 additions & 1 deletion module/customize.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
LIST="/data/adb/keystoreinjection/targetlist"

# Error on < Android 14.
if [ "$API" -lt 30]; then
if [ "$API" -lt 30 ]; then
abort "- !!! You can't use this module on Android < 11"
fi

mkdir -p /data/adb/keystoreinjection
if [ ! -e "$LIST" ]; then
echo "io.github.vvb2060.keyattestation" > "$LIST"
fi

ui_print "***********************************************************************"
ui_print "- Please move keybox to /data/adb/keystoreinjection/keybox.xml"
ui_print "- Please define target apps in /data/adb/keystoreinjection/targetlist"
ui_print "- Format: one app per line"
ui_print "***********************************************************************"
2 changes: 1 addition & 1 deletion module/module.prop
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ name=Keystore Injection
version=v0.1.0
versionCode=10
author=aviraxp
description=Generate a valid certificate chain by injecting custom Keystore provider.
description=Generate a valid certificate chain from scratch by injecting custom Keystore provider.

0 comments on commit 610ff2c

Please sign in to comment.