topjohnwu b278d07b05 Switch to Zygote ptrace-ing
No matter if we use the old, buggy, error prone am_proc_start monitoring,
or the new APK inotify method, both methods rely on MagiskHide 'reacting'
fast enough to hijack the process before any detection has been done.

However, this is not reliable and practical. There are apps that utilize
native libraries to start detects and register SIGCONT signal handlers
to mitigate all existing MagiskHide process monitoring mechanism. So
our only solution is to hijack an app BEFORE it is started.

All Android apps' process is forked from zygote, so it is easily the
target to be monitored. All forks will be notified, and subsequent
thread spawning (Android apps are heaviliy multithreaded) from children
are also closely monitored to find the earliest possible point to
identify what the process will eventually be (before am_proc_bound).

ptrace is extremely complicated and very difficult to get right. The
current code is heaviliy tested on a stock Android 9.0 Pixel system,
so in theory it should work fine on most devices, but more tests and
potentially fixes are expected to follow this commit.
2019-03-05 20:23:27 -05:00

92 lines
1.9 KiB
C++

/* daemon.h - Utility functions for daemon-client communication
*/
#ifndef _DAEMON_H_
#define _DAEMON_H_
#include <pthread.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <string>
#include <vector>
// Commands require connecting to daemon
enum {
DO_NOTHING = 0,
SUPERUSER,
CHECK_VERSION,
CHECK_VERSION_CODE,
POST_FS_DATA,
LATE_START,
BOOT_COMPLETE,
MAGISKHIDE,
SQLITE_CMD,
ZYGOTE_NOTIFY,
};
// Return codes for daemon
enum {
DAEMON_ERROR = -1,
DAEMON_SUCCESS = 0,
ROOT_REQUIRED,
DAEMON_LAST
};
// daemon.c
int connect_daemon(bool create = false);
int switch_mnt_ns(int pid);
// socket.c
socklen_t setup_sockaddr(struct sockaddr_un *sun, const char *name);
int create_rand_socket(struct sockaddr_un *sun);
int socket_accept(int sockfd, int timeout);
void get_client_cred(int fd, struct ucred *cred);
int recv_fd(int sockfd);
void send_fd(int sockfd, int fd);
int read_int(int fd);
int read_int_be(int fd);
void write_int(int fd, int val);
void write_int_be(int fd, int val);
char *read_string(int fd);
char *read_string_be(int fd);
void write_string(int fd, const char *val);
void write_string_be(int fd, const char *val);
void write_key_value(int fd, const char *key, const char *val);
void write_key_token(int fd, const char *key, int tok);
/***************
* Boot Stages *
***************/
void unlock_blocks();
void post_fs_data(int client);
void late_start(int client);
void boot_complete(int client);
/*************
* Scripting *
*************/
void exec_common_script(const char *stage);
void exec_module_script(const char *stage, const std::vector<std::string> &module_list);
void migrate_img(const char *img);
void install_apk(const char *apk);
/**************
* MagiskHide *
**************/
void magiskhide_handler(int client);
void zygote_notify(int client, struct ucred *cred);
void zygote_notify(int pid);
/*************
* Superuser *
*************/
void su_daemon_handler(int client, struct ucred *credential);
#endif