Use large vector<bool> instead of set<pid>
vector<bool> uses bitsets, so we actually only use 12k memory to store all 3 possible PID info tables. PID checkup will be now become O(1) instead of O(logn). P.S. The reason why we don't use unordered_map is because including it will result in significant binary size increase (might be due to the complex hash table STL implementation? I really don't know).
This commit is contained in:
parent
a46e255709
commit
faf4d76388
@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mount.h>
|
||||
#include <vector>
|
||||
|
||||
#include <magisk.h>
|
||||
#include <utils.h>
|
||||
@ -34,9 +35,9 @@ static int inotify_fd = -1;
|
||||
static void term_thread(int sig = SIGTERMTHRD);
|
||||
static void new_zygote(int pid);
|
||||
|
||||
/************************
|
||||
* All the maps and sets
|
||||
************************/
|
||||
/**********************
|
||||
* All data structures
|
||||
**********************/
|
||||
|
||||
set<pair<string, string>> hide_set; /* set of <pkg, process> pair */
|
||||
static map<int, struct stat> zygote_map; /* zygote pid -> mnt ns */
|
||||
@ -44,9 +45,10 @@ static map<int, vector<string_view>> uid_proc_map; /* uid -> list of process */
|
||||
|
||||
pthread_mutex_t monitor_lock;
|
||||
|
||||
static set<int> attaches; /* A set of pid that should be attached */
|
||||
static set<int> detaches; /* A set of tid that should be detached */
|
||||
static set<int> unknown; /* A set of pid/tid that is unknown */
|
||||
#define PID_MAX 32768
|
||||
static vector<bool> attaches(PID_MAX); /* true if pid should be monitored */
|
||||
static vector<bool> detaches(PID_MAX); /* true if tid should be detached */
|
||||
static vector<bool> unknowns(PID_MAX); /* true if pid/tid is in unknown state */
|
||||
|
||||
/********
|
||||
* Utils
|
||||
@ -240,14 +242,12 @@ static void inotify_event(int) {
|
||||
// Workaround for the lack of pthread_cancel
|
||||
static void term_thread(int) {
|
||||
LOGD("proc_monitor: cleaning up\n");
|
||||
// Clear maps
|
||||
uid_proc_map.clear();
|
||||
zygote_map.clear();
|
||||
// Clear sets
|
||||
hide_set.clear();
|
||||
attaches.clear();
|
||||
detaches.clear();
|
||||
unknown.clear();
|
||||
std::fill(attaches.begin(), attaches.end(), false);
|
||||
std::fill(detaches.begin(), detaches.end(), false);
|
||||
std::fill(unknowns.begin(), unknowns.end(), false);
|
||||
// Misc
|
||||
hide_enabled = false;
|
||||
pthread_mutex_destroy(&monitor_lock);
|
||||
@ -282,7 +282,7 @@ static bool check_pid(int pid) {
|
||||
|
||||
/* This process is fully initialized, we will stop
|
||||
* tracing it no matter if it is a target or not. */
|
||||
attaches.erase(pid);
|
||||
attaches[pid] = false;
|
||||
|
||||
sprintf(path, "/proc/%d", pid);
|
||||
struct stat st;
|
||||
@ -324,8 +324,8 @@ static bool check_pid(int pid) {
|
||||
}
|
||||
|
||||
static void handle_unknown(int tid, int pid = -1) {
|
||||
if (unknown.count(tid)) {
|
||||
unknown.erase(tid);
|
||||
if (unknowns[pid]) {
|
||||
unknowns[pid] = false;
|
||||
tgkill(pid < 0 ? tid : pid, tid, SIGSTOP);
|
||||
}
|
||||
}
|
||||
@ -388,9 +388,9 @@ void proc_monitor() {
|
||||
if (pid < 0)
|
||||
continue;
|
||||
if (WIFSTOPPED(status)) {
|
||||
if (detaches.count(pid)) {
|
||||
if (detaches[pid]) {
|
||||
PTRACE_LOG("detach\n");
|
||||
detaches.erase(pid);
|
||||
detaches[pid] = false;
|
||||
xptrace(PTRACE_DETACH, pid);
|
||||
continue;
|
||||
}
|
||||
@ -403,7 +403,7 @@ void proc_monitor() {
|
||||
case PTRACE_EVENT_FORK:
|
||||
case PTRACE_EVENT_VFORK:
|
||||
PTRACE_LOG("zygote forked: [%d]\n", msg);
|
||||
attaches.insert(msg);
|
||||
attaches[msg] = true;
|
||||
handle_unknown(msg);
|
||||
break;
|
||||
case PTRACE_EVENT_EXIT:
|
||||
@ -419,15 +419,15 @@ void proc_monitor() {
|
||||
switch (WEVENT(status)) {
|
||||
case PTRACE_EVENT_CLONE:
|
||||
PTRACE_LOG("create new threads: [%d]\n", msg);
|
||||
detaches.insert(msg);
|
||||
detaches[msg] = true;
|
||||
handle_unknown(msg, pid);
|
||||
if (attaches.count(pid) && check_pid(pid))
|
||||
if (attaches[pid] && check_pid(pid))
|
||||
continue;
|
||||
break;
|
||||
case PTRACE_EVENT_EXIT:
|
||||
PTRACE_LOG("exited with status: [%d]\n", msg);
|
||||
attaches.erase(pid);
|
||||
unknown.erase(pid);
|
||||
attaches[pid] = false;
|
||||
unknowns[pid] = false;
|
||||
break;
|
||||
default:
|
||||
PTRACE_LOG("unknown event: %d\n", WEVENT(status));
|
||||
@ -436,12 +436,12 @@ void proc_monitor() {
|
||||
xptrace(PTRACE_CONT, pid);
|
||||
}
|
||||
} else if (WSTOPSIG(status) == SIGSTOP) {
|
||||
if (attaches.count(pid)) {
|
||||
if (attaches[pid]) {
|
||||
PTRACE_LOG("SIGSTOP from zygote child\n");
|
||||
xptrace(PTRACE_SETOPTIONS, pid, nullptr, PTRACE_O_TRACECLONE | PTRACE_O_TRACEEXIT);
|
||||
} else {
|
||||
PTRACE_LOG("SIGSTOP from unknown\n");
|
||||
unknown.insert(pid);
|
||||
unknowns[pid] = true;
|
||||
}
|
||||
xptrace(PTRACE_CONT, pid);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user