mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-20 00:48:28 +00:00
Make zygiskd ABI aware
This commit is contained in:
parent
4194ac894c
commit
7496d51580
@ -34,3 +34,6 @@ void exec_common_scripts(const char *stage);
|
|||||||
void exec_module_scripts(const char *stage, const std::vector<std::string_view> &modules);
|
void exec_module_scripts(const char *stage, const std::vector<std::string_view> &modules);
|
||||||
void install_apk(const char *apk);
|
void install_apk(const char *apk);
|
||||||
[[noreturn]] void install_module(const char *file);
|
[[noreturn]] void install_module(const char *file);
|
||||||
|
|
||||||
|
// Zygisk companion entrypoint
|
||||||
|
[[noreturn]] void zygiskd(int socket);
|
||||||
|
@ -39,6 +39,7 @@ Advanced Options (Internal APIs):
|
|||||||
--sqlite SQL exec SQL commands to Magisk database
|
--sqlite SQL exec SQL commands to Magisk database
|
||||||
--path print Magisk tmpfs mount path
|
--path print Magisk tmpfs mount path
|
||||||
--denylist ARGS denylist config CLI
|
--denylist ARGS denylist config CLI
|
||||||
|
--companion FD start zygisk root companion
|
||||||
|
|
||||||
Available applets:
|
Available applets:
|
||||||
)EOF");
|
)EOF");
|
||||||
@ -127,6 +128,8 @@ int magisk_main(int argc, char *argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
} else if (argc >= 3 && argv[1] == "--install-module"sv) {
|
} else if (argc >= 3 && argv[1] == "--install-module"sv) {
|
||||||
install_module(argv[2]);
|
install_module(argv[2]);
|
||||||
|
} else if (argc >= 3 && argv[1] == "--companion"sv) {
|
||||||
|
zygiskd(parse_int(argv[2]));
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
/* Entry point for testing stuffs */
|
/* Entry point for testing stuffs */
|
||||||
|
@ -138,10 +138,10 @@ void set_nice_name(const char *name) {
|
|||||||
* Bionic's atoi runs through strtol().
|
* Bionic's atoi runs through strtol().
|
||||||
* Use our own implementation for faster conversion.
|
* Use our own implementation for faster conversion.
|
||||||
*/
|
*/
|
||||||
int parse_int(const char *s) {
|
int parse_int(string_view s) {
|
||||||
int val = 0;
|
int val = 0;
|
||||||
char c;
|
for (char c : s) {
|
||||||
while ((c = *(s++))) {
|
if (!c) break;
|
||||||
if (c > '9' || c < '0')
|
if (c > '9' || c < '0')
|
||||||
return -1;
|
return -1;
|
||||||
val = val * 10 + c - '0';
|
val = val * 10 + c - '0';
|
||||||
|
@ -79,9 +79,7 @@ public:
|
|||||||
bool operator!=(const stateless_allocator&) { return false; }
|
bool operator!=(const stateless_allocator&) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
int parse_int(const char *s);
|
int parse_int(std::string_view s);
|
||||||
static inline int parse_int(const std::string &s) { return parse_int(s.data()); }
|
|
||||||
static inline int parse_int(std::string_view s) { return parse_int(s.data()); }
|
|
||||||
|
|
||||||
using thread_entry = void *(*)(void *);
|
using thread_entry = void *(*)(void *);
|
||||||
int new_daemon_thread(thread_entry entry, void *arg = nullptr);
|
int new_daemon_thread(thread_entry entry, void *arg = nullptr);
|
||||||
|
@ -164,6 +164,9 @@ struct Api {
|
|||||||
// Another good use case for a companion process is that if you want to share some resources
|
// Another good use case for a companion process is that if you want to share some resources
|
||||||
// across multiple processes, hold the resources in the companion process and pass it over.
|
// across multiple processes, hold the resources in the companion process and pass it over.
|
||||||
//
|
//
|
||||||
|
// The root companion process is ABI aware; that is, when calling this function from a 32-bit
|
||||||
|
// process, you will be connected to a 32-bit companion process, and vice versa for 64-bit.
|
||||||
|
//
|
||||||
// Returns a file descriptor to a socket that is connected to the socket passed to your
|
// Returns a file descriptor to a socket that is connected to the socket passed to your
|
||||||
// module's companion request handler. Returns -1 if the connection attempt failed.
|
// module's companion request handler. Returns -1 if the connection attempt failed.
|
||||||
int connectCompanion();
|
int connectCompanion();
|
||||||
|
@ -4,26 +4,30 @@
|
|||||||
#include <utils.hpp>
|
#include <utils.hpp>
|
||||||
#include <socket.hpp>
|
#include <socket.hpp>
|
||||||
#include <daemon.hpp>
|
#include <daemon.hpp>
|
||||||
|
#include <magisk.hpp>
|
||||||
|
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static int zygiskd_socket = -1;
|
void zygiskd(int socket) {
|
||||||
|
if (getuid() != 0 || fcntl(socket, F_GETFD) < 0)
|
||||||
|
exit(-1);
|
||||||
|
android_logging();
|
||||||
|
|
||||||
[[noreturn]] static void zygiskd(int socket) {
|
#if defined(__LP64__)
|
||||||
set_nice_name("zygiskd");
|
set_nice_name("zygiskd64");
|
||||||
LOGI("* Launching zygiskd\n");
|
LOGI("* Launching zygiskd64\n");
|
||||||
|
#else
|
||||||
|
set_nice_name("zygiskd32");
|
||||||
|
LOGI("* Launching zygiskd32\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Load modules
|
// Load modules
|
||||||
using comp_entry = void(*)(int);
|
using comp_entry = void(*)(int);
|
||||||
vector<comp_entry> modules;
|
vector<comp_entry> modules;
|
||||||
{
|
{
|
||||||
#if defined(__LP64__)
|
vector<int> module_fds = recv_fds(socket);
|
||||||
vector<int> module_fds = zygisk_module_fds(true);
|
|
||||||
#else
|
|
||||||
vector<int> module_fds = zygisk_module_fds(false);
|
|
||||||
#endif
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
for (int fd : module_fds) {
|
for (int fd : module_fds) {
|
||||||
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
|
snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
|
||||||
@ -35,6 +39,9 @@ static int zygiskd_socket = -1;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ack
|
||||||
|
write_int(socket, 0);
|
||||||
|
|
||||||
// Start accepting requests
|
// Start accepting requests
|
||||||
pollfd pfd = { socket, POLLIN, 0 };
|
pollfd pfd = { socket, POLLIN, 0 };
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -68,7 +75,10 @@ static int zygiskd_socket = -1;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_companion(int client) {
|
static int zygiskd_sockets[] = { -1, -1 };
|
||||||
|
#define zygiskd_socket zygiskd_sockets[is_64_bit]
|
||||||
|
|
||||||
|
void connect_companion(int client, bool is_64_bit) {
|
||||||
if (zygiskd_socket >= 0) {
|
if (zygiskd_socket >= 0) {
|
||||||
// Make sure the socket is still valid
|
// Make sure the socket is still valid
|
||||||
pollfd pfd = { zygiskd_socket, 0, 0 };
|
pollfd pfd = { zygiskd_socket, 0, 0 };
|
||||||
@ -84,7 +94,20 @@ void start_companion(int client) {
|
|||||||
socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
|
socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
|
||||||
zygiskd_socket = fds[0];
|
zygiskd_socket = fds[0];
|
||||||
if (fork_dont_care() == 0) {
|
if (fork_dont_care() == 0) {
|
||||||
zygiskd(fds[1]);
|
string exe = MAGISKTMP + "/magisk" + (is_64_bit ? "64" : "32");
|
||||||
|
// This fd has to survive exec
|
||||||
|
fcntl(fds[1], F_SETFD, 0);
|
||||||
|
char buf[16];
|
||||||
|
snprintf(buf, sizeof(buf), "%d", fds[1]);
|
||||||
|
execlp(exe.data(), "magisk", "--companion", buf, (char *) nullptr);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
close(fds[1]);
|
||||||
|
vector<int> module_fds = zygisk_module_fds(is_64_bit);
|
||||||
|
send_fds(zygiskd_socket, module_fds.data(), module_fds.size());
|
||||||
|
// Wait for ack
|
||||||
|
if (read_int(zygiskd_socket) != 0) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send_fd(zygiskd_socket, client);
|
send_fd(zygiskd_socket, client);
|
||||||
|
@ -243,12 +243,16 @@ int remote_request_unmount() {
|
|||||||
|
|
||||||
// The following code runs in magiskd
|
// The following code runs in magiskd
|
||||||
|
|
||||||
|
static bool get_exe(int pid, char *buf, size_t sz) {
|
||||||
|
snprintf(buf, sz, "/proc/%d/exe", pid);
|
||||||
|
return xreadlink(buf, buf, sz) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void setup_files(int client, const sock_cred *cred) {
|
static void setup_files(int client, const sock_cred *cred) {
|
||||||
LOGD("zygisk: setup files for pid=[%d]\n", cred->pid);
|
LOGD("zygisk: setup files for pid=[%d]\n", cred->pid);
|
||||||
|
|
||||||
char buf[256];
|
char buf[256];
|
||||||
snprintf(buf, sizeof(buf), "/proc/%d/exe", cred->pid);
|
if (!get_exe(cred->pid, buf, sizeof(buf))) {
|
||||||
if (xreadlink(buf, buf, sizeof(buf)) < 0) {
|
|
||||||
write_int(client, 1);
|
write_int(client, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -308,8 +312,7 @@ static void get_process_info(int client, const sock_cred *cred) {
|
|||||||
|
|
||||||
if (!info.on_denylist) {
|
if (!info.on_denylist) {
|
||||||
char buf[256];
|
char buf[256];
|
||||||
snprintf(buf, sizeof(buf), "/proc/%d/exe", cred->pid);
|
get_exe(cred->pid, buf, sizeof(buf));
|
||||||
xreadlink(buf, buf, sizeof(buf));
|
|
||||||
vector<int> fds = zygisk_module_fds(str_ends(buf, "64"));
|
vector<int> fds = zygisk_module_fds(str_ends(buf, "64"));
|
||||||
send_fds(client, fds.data(), fds.size());
|
send_fds(client, fds.data(), fds.size());
|
||||||
}
|
}
|
||||||
@ -336,6 +339,7 @@ static void send_log_pipe(int fd) {
|
|||||||
|
|
||||||
void zygisk_handler(int client, const sock_cred *cred) {
|
void zygisk_handler(int client, const sock_cred *cred) {
|
||||||
int code = read_int(client);
|
int code = read_int(client);
|
||||||
|
char buf[256];
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case ZYGISK_SETUP:
|
case ZYGISK_SETUP:
|
||||||
setup_files(client, cred);
|
setup_files(client, cred);
|
||||||
@ -349,8 +353,9 @@ void zygisk_handler(int client, const sock_cred *cred) {
|
|||||||
case ZYGISK_GET_LOG_PIPE:
|
case ZYGISK_GET_LOG_PIPE:
|
||||||
send_log_pipe(client);
|
send_log_pipe(client);
|
||||||
break;
|
break;
|
||||||
case ZYGISK_START_COMPANION:
|
case ZYGISK_CONNECT_COMPANION:
|
||||||
start_companion(client);
|
get_exe(cred->pid, buf, sizeof(buf));
|
||||||
|
connect_companion(client, str_ends(buf, "64"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
close(client);
|
close(client);
|
||||||
|
@ -290,7 +290,7 @@ bool ZygiskModule::registerModule(ApiTable *table, long *module) {
|
|||||||
int ZygiskModule::connectCompanion() const {
|
int ZygiskModule::connectCompanion() const {
|
||||||
if (int fd = connect_daemon(); fd >= 0) {
|
if (int fd = connect_daemon(); fd >= 0) {
|
||||||
write_int(fd, ZYGISK_REQUEST);
|
write_int(fd, ZYGISK_REQUEST);
|
||||||
write_int(fd, ZYGISK_START_COMPANION);
|
write_int(fd, ZYGISK_CONNECT_COMPANION);
|
||||||
write_int(fd, id);
|
write_int(fd, id);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ enum : int {
|
|||||||
ZYGISK_GET_INFO,
|
ZYGISK_GET_INFO,
|
||||||
ZYGISK_UNMOUNT,
|
ZYGISK_UNMOUNT,
|
||||||
ZYGISK_GET_LOG_PIPE,
|
ZYGISK_GET_LOG_PIPE,
|
||||||
ZYGISK_START_COMPANION,
|
ZYGISK_CONNECT_COMPANION,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__LP64__)
|
#if defined(__LP64__)
|
||||||
@ -47,4 +47,4 @@ void hook_functions();
|
|||||||
bool unhook_functions();
|
bool unhook_functions();
|
||||||
std::vector<int> remote_get_info(int uid, const char *process, AppInfo *info);
|
std::vector<int> remote_get_info(int uid, const char *process, AppInfo *info);
|
||||||
int remote_request_unmount();
|
int remote_request_unmount();
|
||||||
void start_companion(int client);
|
void connect_companion(int client, bool is_64_bit);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user