diff --git a/native/jni/zygisk/deny/utils.cpp b/native/jni/zygisk/deny/utils.cpp index a8008042d..6ed961737 100644 --- a/native/jni/zygisk/deny/utils.cpp +++ b/native/jni/zygisk/deny/utils.cpp @@ -14,24 +14,9 @@ using namespace std; -#define FIRST_APP_UID 10000 - -struct app_id_bitset : public dynamic_bitset_impl { - slot_bits::reference operator[] (size_t pos) { - return pos < FIRST_APP_UID ? get(0) : get(pos - FIRST_APP_UID); - } - bool operator[] (size_t pos) const { - return pos < FIRST_APP_UID || get(pos - FIRST_APP_UID); - } -}; - // For the following data structures: // If package name == ISOLATED_MAGIC, or app ID == -1, it means isolated service -// List of all discovered app IDs -static unique_ptr app_ids_seen_; -#define app_ids_seen (*app_ids_seen_) - // Package name -> list of process names static unique_ptr, StringCmp>> pkg_to_procs_; #define pkg_to_procs (*pkg_to_procs_) @@ -47,9 +32,24 @@ atomic denylist_enforced = false; #define do_kill (zygisk_enabled && denylist_enforced) +static unsigned long long pkg_xml_ino = 0; + static void rescan_apps() { + { + struct stat st{}; + stat("/data/system/packages.xml", &st); + if (pkg_xml_ino == st.st_ino) { + // Packages has not changed, do not rescan + return; + } + pkg_xml_ino = st.st_ino; + } + LOGD("denylist: rescanning apps\n"); + app_id_to_pkgs.clear(); + cached_manager_app_id = -1; + auto data_dir = xopen_dir(APP_DATA_DIR); if (!data_dir) return; @@ -67,7 +67,6 @@ static void rescan_apps() { // This app ID has been handled continue; } - app_ids_seen[app_id] = true; if (auto it = pkg_to_procs.find(entry->d_name); it != pkg_to_procs.end()) { app_id_to_pkgs[app_id].insert(it->first); } @@ -99,7 +98,6 @@ static void update_pkg_uid(const string &pkg, bool remove) { } } else { app_id_to_pkgs[app_id].insert(pkg); - app_ids_seen[app_id] = true; } break; } @@ -201,13 +199,12 @@ static auto add_hide_set(const char *pkg, const char *proc) { } static void clear_data() { - app_ids_seen_.reset(nullptr); pkg_to_procs_.reset(nullptr); app_id_to_pkgs_.reset(nullptr); } static bool ensure_data() { - if (app_ids_seen_) + if (pkg_to_procs_) return true; LOGI("denylist: initializing internal data structures\n"); @@ -219,7 +216,6 @@ static bool ensure_data() { }); db_err_cmd(err, goto error) - default_new(app_ids_seen_); default_new(app_id_to_pkgs_); rescan_apps(); @@ -404,6 +400,8 @@ bool is_deny_target(int uid, string_view process) { if (!ensure_data()) return false; + rescan_apps(); + int app_id = to_app_id(uid); if (app_id >= 90000) { if (auto it = pkg_to_procs.find(ISOLATED_MAGIC); it != pkg_to_procs.end()) { @@ -414,12 +412,6 @@ bool is_deny_target(int uid, string_view process) { } return false; } else { - if (!app_ids_seen[app_id]) { - // Found new app ID - cached_manager_app_id = -1; - rescan_apps(); - } - auto it = app_id_to_pkgs.find(app_id); if (it == app_id_to_pkgs.end()) return false; diff --git a/native/jni/zygisk/entry.cpp b/native/jni/zygisk/entry.cpp index 670bd9129..ce3ae7fd8 100644 --- a/native/jni/zygisk/entry.cpp +++ b/native/jni/zygisk/entry.cpp @@ -330,25 +330,22 @@ static void get_process_info(int client, const sock_cred *cred) { // This function is called on every single zygote process specialization, // so performance is critical. get_manager_app_id() is expensive as it goes // through a SQLite query and potentially multiple filesystem stats, so we - // really want to cache the app ID value. inotify will invalidate the app ID - // cache for us. + // really want to cache its app ID value. + if (is_deny_target(uid, process)) { + flags |= PROCESS_ON_DENYLIST; + } int manager_app_id = cached_manager_app_id; - if (manager_app_id < 0) { manager_app_id = get_manager_app_id(); cached_manager_app_id = manager_app_id; } - if (to_app_id(uid) == manager_app_id) { flags |= PROCESS_IS_MAGISK_APP; } if (denylist_enforced) { flags |= DENYLIST_ENFORCING; } - if (is_deny_target(uid, process)) { - flags |= PROCESS_ON_DENYLIST; - } if (uid_granted_root(uid)) { flags |= PROCESS_GRANTED_ROOT; }