Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge #80

Merged
merged 11 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ jobs:
submodules: "recursive"
fetch-depth: 0

- name: Write key
if: ${{ ( github.event_name != 'pull_request' && github.ref == 'refs/heads/master' ) || github.ref_type == 'tag' }}
run: |
if [ ! -z "${{ secrets.PRIVATE_KEY }}" ]; then
echo '${{ secrets.PUBLIC_KEY }}' | base64 --decode > module/public_key
echo '${{ secrets.PRIVATE_KEY }}' | base64 --decode > module/private_key
fi

- name: Setup Java
uses: actions/setup-java@v3
with:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ Standalone implementation of Zygisk, providing Zygisk API support for KernelSU a
### KernelSU

+ Minimal KernelSU version: 10940
+ Minimal ksud version: 10942
+ Minimal ksud version: 11412
+ Kernel has full SELinux patch support

### Magisk

+ Minimal version: 26300
+ Minimal version: 26402
+ Built-in Zygisk turned off

## Compatibility
Expand Down
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ val verName by extra("v4-0.8.1")
val verCode by extra(gitCommitCount)
val commitHash by extra(gitCommitHash)
val minKsuVersion by extra(10940)
val minKsudVersion by extra(10942)
val minKsudVersion by extra(11412)
val maxKsuVersion by extra(20000)
val minMagiskVersion by extra(26300)
val minMagiskVersion by extra(26402)

val androidMinSdkVersion by extra(26)
val androidTargetSdkVersion by extra(34)
Expand Down
11 changes: 11 additions & 0 deletions loader/src/common/daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,15 @@ namespace zygiskd {
PLOGE("Failed to request ZygoteRestart");
}
}

void SystemServerStarted() {
UniqueFd fd = Connect(1);
if (fd == -1) {
PLOGE("Failed to report system server started");
} else {
if (!socket_utils::write_u8(fd, (uint8_t) SocketAction::SystemServerStarted)) {
PLOGE("Failed to report system server started");
}
}
}
}
8 changes: 5 additions & 3 deletions loader/src/include/daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
#endif

constexpr auto kCPSocketName = "/" LP_SELECT("cp32", "cp64") ".sock";
constexpr const auto MAGIC_PATH_ENV = "MAGIC_PATH";
constexpr const auto MAGIC_ENV = "MAGIC";
#define TMP_PATH "/debug_ramdisk/zygisksu"

class UniqueFd {
using Fd = int;
Expand Down Expand Up @@ -61,9 +60,10 @@ namespace zygiskd {
RequestCompanionSocket,
GetModuleDir,
ZygoteRestart,
SystemServerStarted,
};

void Init(const char *path);
void Init(const char *path = TMP_PATH);

bool PingHeartbeat();

Expand All @@ -78,4 +78,6 @@ namespace zygiskd {
int GetModuleDir(size_t index);

void ZygoteRestart();

void SystemServerStarted();
}
4 changes: 2 additions & 2 deletions loader/src/injector/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ using namespace std;
void *self_handle = nullptr;

extern "C" [[gnu::visibility("default")]]
void entry(void* handle, const char* path) {
void entry(void* handle) {
LOGI("Zygisk library injected, version %s", ZKSU_VERSION);
self_handle = handle;

zygiskd::Init(path);
zygiskd::Init();
if (!zygiskd::PingHeartbeat()) {
LOGE("Zygisk daemon is not running");
return;
Expand Down
8 changes: 7 additions & 1 deletion loader/src/injector/hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,12 @@ void ZygiskContext::run_modules_post() {
void ZygiskContext::app_specialize_pre() {
flags[APP_SPECIALIZE] = true;
info_flags = zygiskd::GetProcessFlags(g_ctx->args.app->uid);
run_modules_pre();
if ((info_flags & (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) == (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) {
LOGI("current uid %d is manager!", g_ctx->args.app->uid);
setenv("ZYGISK_ENABLED", "1", 1);
} else {
run_modules_pre();
}
}


Expand Down Expand Up @@ -629,6 +634,7 @@ void ZygiskContext::nativeForkSystemServer_pre() {
return;

run_modules_pre();
zygiskd::SystemServerStarted();

sanitize_fds();
}
Expand Down
1 change: 1 addition & 0 deletions loader/src/injector/module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ namespace {
PROCESS_GRANTED_ROOT = zygisk::StateFlag::PROCESS_GRANTED_ROOT,
PROCESS_ON_DENYLIST = zygisk::StateFlag::PROCESS_ON_DENYLIST,

PROCESS_IS_MANAGER = (1u << 28),
PROCESS_ROOT_IS_KSU = (1u << 29),
PROCESS_ROOT_IS_MAGISK = (1u << 30),
PROCESS_IS_SYS_UI = (1u << 31),
Expand Down
2 changes: 1 addition & 1 deletion loader/src/ptracer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ int main(int argc, char **argv) {
return 0;
} else if (argc >= 3 && argv[1] == "trace"sv) {
if (argc >= 4 && argv[3] == "--restart"sv) {
zygiskd::Init(getenv(MAGIC_PATH_ENV));
zygiskd::Init();
zygiskd::ZygoteRestart();
}
auto pid = strtol(argv[2], 0, 0);
Expand Down
1 change: 1 addition & 0 deletions loader/src/ptracer/main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum Command {
DAEMON32_SET_INFO = 7,
DAEMON64_SET_ERROR_INFO = 8,
DAEMON32_SET_ERROR_INFO = 9,
SYSTEM_SERVER_STARTED = 10
};

void send_control_command(Command cmd);
62 changes: 19 additions & 43 deletions loader/src/ptracer/monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,7 @@ enum TracingState {

std::string monitor_stop_reason;

constexpr char SOCKET_NAME[] = "init_monitor";

std::string GetControlSocketName() {
auto env = getenv(MAGIC_ENV);
if (env == nullptr) return SOCKET_NAME;
return std::string(SOCKET_NAME) + env;
}
constexpr char SOCKET_NAME[] = TMP_PATH "/init_monitor";

struct EventLoop;

Expand Down Expand Up @@ -114,6 +108,7 @@ struct EventLoop {
};

static TracingState tracing_state = TRACING;
static std::string prop_path;


struct Status {
Expand Down Expand Up @@ -141,9 +136,8 @@ struct SocketHandler : public EventHandler {
.sun_family = AF_UNIX,
.sun_path={0},
};
auto socket_name = GetControlSocketName();
strcpy(addr.sun_path + 1, socket_name.c_str());
socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path + 1) + 1;
strcpy(addr.sun_path, SOCKET_NAME);
socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path);
if (bind(sock_fd_, (struct sockaddr *) &addr, socklen) == -1) {
PLOGE("bind socket");
return false;
Expand Down Expand Up @@ -177,7 +171,7 @@ struct SocketHandler : public EventHandler {
LOGE("read %zu < %zu", nread, sizeof(Command));
continue;
}
if (msg.cmd >= Command::DAEMON64_SET_INFO) {
if (msg.cmd >= Command::DAEMON64_SET_INFO && msg.cmd != Command::SYSTEM_SERVER_STARTED) {
if (nread != sizeof(msg)) {
LOGE("cmd %d size %zu != %zu", msg.cmd, nread, sizeof(MsgHead));
continue;
Expand Down Expand Up @@ -260,6 +254,12 @@ struct SocketHandler : public EventHandler {
status32.daemon_error_info = std::string(msg.data);
updateStatus();
break;
case SYSTEM_SERVER_STARTED:
LOGD("system server started, mounting prop");
if (mount(prop_path.c_str(), "/data/adb/modules/zygisksu/module.prop", nullptr, MS_BIND, nullptr) == -1) {
PLOGE("failed to mount prop");
}
break;
}
}
}
Expand Down Expand Up @@ -289,17 +289,20 @@ bool should_stop_inject##abi() { \
CREATE_ZYGOTE_START_COUNTER(64)
CREATE_ZYGOTE_START_COUNTER(32)


static bool ensure_daemon_created(bool is_64bit) {
auto &status = is_64bit ? status64 : status32;
if (is_64bit) {
LOGD("new zygote started, unmounting prop ...");
umount2("/data/adb/modules/zygisksu/module.prop", MNT_DETACH);
}
status.zygote_injected = false;
if (status.daemon_pid == -1) {
auto pid = fork();
if (pid < 0) {
PLOGE("create daemon (64=%s)", is_64bit ? "true" : "false");
return false;
} else if (pid == 0) {
std::string daemon_name = "./bin/zygisk-cp";
std::string daemon_name = "./bin/zygiskd";
daemon_name += is_64bit ? "64" : "32";
execl(daemon_name.c_str(), daemon_name.c_str(), nullptr);
PLOGE("exec daemon %s failed", daemon_name.c_str());
Expand Down Expand Up @@ -487,7 +490,6 @@ struct SigChldHandler : public EventHandler {
}
};

static std::string prop_path;
static std::string pre_section;
static std::string post_section;

Expand Down Expand Up @@ -542,12 +544,7 @@ static void updateStatus() {
}

static bool prepare_environment() {
auto path = getenv(MAGIC_PATH_ENV);
if (path == nullptr) {
LOGE("path is null, is MAGIC_PATH_ENV specified?");
return false;
}
prop_path = std::string(path) + "/module.prop";
prop_path = TMP_PATH "/module.prop";
close(open(prop_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644));
auto orig_prop = xopen_file("./module.prop", "r");
if (orig_prop == nullptr) {
Expand All @@ -569,26 +566,6 @@ static bool prepare_environment() {
}
return true;
});
int old_ns;
char wd[128];
if (getcwd(wd, sizeof(wd)) == nullptr) {
PLOGE("get cwd");
return false;
}
if (!switch_mnt_ns(1, &old_ns)) return false;
if (chdir(wd) == -1) {
PLOGE("chdir %s", wd);
return false;
}
if (mount(prop_path.c_str(), "/data/adb/modules/zygisksu/module.prop", nullptr, MS_BIND, nullptr) == -1) {
PLOGE("failed to mount prop");
return false;
}
if (!switch_mnt_ns(0, &old_ns)) return false;
if (chdir(wd) == -1) {
PLOGE("chdir %s", wd);
return false;
}
updateStatus();
return true;
}
Expand Down Expand Up @@ -618,9 +595,8 @@ void send_control_command(Command cmd) {
.sun_family = AF_UNIX,
.sun_path={0},
};
auto socket_name = GetControlSocketName();
strcpy(addr.sun_path + 1, socket_name.c_str());
socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path + 1) + 1;
strcpy(addr.sun_path, SOCKET_NAME);
socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path);
auto nsend = sendto(sockfd, (void *) &cmd, sizeof(cmd), 0, (sockaddr *) &addr, socklen);
if (nsend == -1) {
err(EXIT_FAILURE, "send");
Expand Down
10 changes: 4 additions & 6 deletions loader/src/ptracer/ptracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <string>
#include "utils.hpp"

bool inject_on_main(int pid, const char *lib_path, const char* magic_path) {
bool inject_on_main(int pid, const char *lib_path) {
LOGI("injecting %s to zygote %d", lib_path, pid);
// parsing KernelArgumentBlock
// https://cs.android.com/android/platform/superproject/main/+/main:bionic/libc/private/KernelArgumentBlock.h;l=30;drc=6d1ee77ee32220e4202c3066f7e1f69572967ad8
Expand Down Expand Up @@ -145,8 +145,6 @@ bool inject_on_main(int pid, const char *lib_path, const char* magic_path) {
// call injector entry(handle, magic)
args.clear();
args.push_back(remote_handle);
str = push_string(pid, regs, magic_path);
args.push_back((long) str);
remote_call(pid, regs, injector_entry, (uintptr_t) libc_return_addr, args);

// reset pc to entry
Expand Down Expand Up @@ -180,9 +178,9 @@ bool trace_zygote(int pid) {
}
WAIT_OR_DIE
if (STOPPED_WITH(SIGSTOP, PTRACE_EVENT_STOP)) {
std::string magic_path = getenv(MAGIC_PATH_ENV);
std::string lib_path = magic_path + "/lib" LP_SELECT("", "64") "/libzygisk.so";
if (!inject_on_main(pid, lib_path.c_str(), magic_path.c_str())) {
std::string lib_path = TMP_PATH;
lib_path += "/lib" LP_SELECT("", "64") "/libzygisk.so";
if (!inject_on_main(pid, lib_path.c_str())) {
LOGE("failed to inject");
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions module/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
public_key
private_key
Loading