mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-06-12 21:27:41 +02:00
Verify app signature
This commit is contained in:
@ -20,6 +20,7 @@ using namespace std;
|
||||
static bool safe_mode = false;
|
||||
static int stub_fd = -1;
|
||||
bool zygisk_enabled = false;
|
||||
string APKCERT;
|
||||
|
||||
/*********
|
||||
* Setup *
|
||||
@ -124,6 +125,7 @@ static bool magisk_env() {
|
||||
LOGI("* Initializing Magisk environment\n");
|
||||
|
||||
string stub_path = MAGISKTMP + "/stub.apk";
|
||||
APKCERT = read_certificate(stub_path);
|
||||
stub_fd = xopen(stub_path.data(), O_RDONLY | O_CLOEXEC);
|
||||
unlink(stub_path.data());
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <db.hpp>
|
||||
#include <socket.hpp>
|
||||
#include <utils.hpp>
|
||||
#include <mincrypt/sha256.h>
|
||||
|
||||
#define DB_VERSION 12
|
||||
|
||||
@ -359,43 +360,89 @@ int get_db_strings(db_strings &str, int key) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_stub_trusted(const char *pkg, const char *trust_hash) {
|
||||
// TODO: Remove when next stable released
|
||||
if (trust_hash[0] == 0) {
|
||||
LOGW("su: skip check stub.apk signature\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
string cert = read_certificate(find_apk_path(pkg));
|
||||
if (cert.empty())
|
||||
return false;
|
||||
uint8_t hash[SHA256_DIGEST_SIZE];
|
||||
SHA256_hash(cert.data(), cert.length(), hash);
|
||||
char hash_hex[SHA256_DIGEST_SIZE * 2 + 1];
|
||||
char *ptr = &hash_hex[0];
|
||||
for (uint8_t i: hash) {
|
||||
ptr += sprintf(ptr, "%02x", i);
|
||||
}
|
||||
return strcmp(trust_hash, hash_hex) == 0;
|
||||
}
|
||||
|
||||
bool get_manager(int user_id, std::string *pkg, struct stat *st) {
|
||||
db_strings str;
|
||||
get_db_strings(str, SU_MANAGER);
|
||||
get_db_strings(str, CERT_DIGEST);
|
||||
char app_path[128];
|
||||
|
||||
if (APKCERT.empty())
|
||||
LOGW("su: skip check app signature\n");
|
||||
|
||||
if (!str[SU_MANAGER].empty()) {
|
||||
// App is repackaged
|
||||
sprintf(app_path, "%s/%d/%s", APP_DATA_DIR, user_id, str[SU_MANAGER].data());
|
||||
if (stat(app_path, st) == 0) {
|
||||
if (pkg)
|
||||
pkg->swap(str[SU_MANAGER]);
|
||||
return true;
|
||||
if (is_stub_trusted(str[SU_MANAGER].data(), str[CERT_DIGEST].data())) {
|
||||
strcpy(app_path, "/dyn/current.apk");
|
||||
if (!APKCERT.empty() && access(app_path, F_OK) == 0) {
|
||||
if (read_certificate(app_path) == APKCERT) {
|
||||
if (pkg)
|
||||
pkg->swap(str[SU_MANAGER]);
|
||||
return true;
|
||||
} else {
|
||||
LOGW("su: current.apk signature mismatch\n");
|
||||
}
|
||||
} else {
|
||||
if (pkg)
|
||||
pkg->swap(str[SU_MANAGER]);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
LOGW("su: stub.apk signature mismatch\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the official package name
|
||||
sprintf(app_path, "%s/%d/" JAVA_PACKAGE_NAME, APP_DATA_DIR, user_id);
|
||||
if (stat(app_path, st) == 0) {
|
||||
if (pkg)
|
||||
*pkg = JAVA_PACKAGE_NAME;
|
||||
return true;
|
||||
} else {
|
||||
LOGE("su: cannot find manager\n");
|
||||
memset(st, 0, sizeof(*st));
|
||||
if (pkg)
|
||||
pkg->clear();
|
||||
return false;
|
||||
string cert = read_certificate(find_apk_path(JAVA_PACKAGE_NAME));
|
||||
if (APKCERT.empty())
|
||||
cert.clear();
|
||||
if (cert == APKCERT) {
|
||||
if (pkg)
|
||||
*pkg = JAVA_PACKAGE_NAME;
|
||||
return true;
|
||||
} else {
|
||||
LOGW("su: app signature mismatch\n");
|
||||
}
|
||||
}
|
||||
|
||||
LOGE("su: cannot find trusted app\n");
|
||||
memset(st, 0, sizeof(*st));
|
||||
if (pkg)
|
||||
pkg->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool get_manager(string *pkg) {
|
||||
struct stat st;
|
||||
struct stat st{};
|
||||
return get_manager(0, pkg, &st);
|
||||
}
|
||||
|
||||
int get_manager_app_id() {
|
||||
struct stat st;
|
||||
struct stat st{};
|
||||
if (get_manager(0, nullptr, &st))
|
||||
return to_app_id(st.st_uid);
|
||||
return -1;
|
||||
|
@ -152,6 +152,7 @@ void exec_module_scripts(const char *stage, const vector<string_view> &modules)
|
||||
|
||||
constexpr char install_script[] = R"EOF(
|
||||
APK=%s
|
||||
log -t Magisk "apk_uninstall: $(pm uninstall %s 2>&1)"
|
||||
log -t Magisk "apk_install: $APK"
|
||||
log -t Magisk "apk_install: $(pm install -r $APK 2>&1)"
|
||||
rm -f $APK
|
||||
@ -163,7 +164,7 @@ void install_apk(const char *apk) {
|
||||
.fork = fork_no_orphan
|
||||
};
|
||||
char cmds[sizeof(install_script) + 4096];
|
||||
sprintf(cmds, install_script, apk);
|
||||
sprintf(cmds, install_script, apk, JAVA_PACKAGE_NAME);
|
||||
exec_command_sync(exec, "/system/bin/sh", "-c", cmds);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user