fix compatibility on lower android version

This commit is contained in:
5ec1cff
2023-11-13 15:04:23 +08:00
parent 3e541ece3a
commit fd6a454275
6 changed files with 52 additions and 13 deletions

View File

@@ -172,6 +172,8 @@ struct SocketHandler : public EventHandler {
}
};
constexpr auto MAX_RETRY_COUNT = 2;
struct timespec last_zygote64{.tv_sec = 0, .tv_nsec = 0};
int count_zygote64 = 0;
bool should_stop_inject64() {
@@ -183,7 +185,7 @@ bool should_stop_inject64() {
count_zygote64 = 0;
}
last_zygote64 = now;
return count_zygote64 >= 5;
return count_zygote64 >= MAX_RETRY_COUNT;
}
struct timespec last_zygote32{.tv_sec = 0, .tv_nsec = 0};
@@ -197,7 +199,7 @@ bool should_stop_inject32() {
count_zygote32 = 0;
}
last_zygote32 = now;
return count_zygote32 >= 5;
return count_zygote32 >= MAX_RETRY_COUNT;
}
struct PtraceHandler : public EventHandler {

View File

@@ -88,7 +88,8 @@ bool inject_on_main(int pid, const char *lib_path) {
memcpy(&backup, &regs, sizeof(regs));
map = MapInfo::Scan(std::to_string(pid));
auto local_map = MapInfo::Scan();
auto libc_base = find_module_base(map, "libc.so");
auto libc_return_addr = find_module_return_addr(map, "libc.so");
LOGD("libc return addr %p", libc_return_addr);
// call dlopen
auto dlopen_addr = find_func_addr(local_map, map, "libdl.so", "dlopen");
@@ -98,10 +99,34 @@ bool inject_on_main(int pid, const char *lib_path) {
args.clear();
args.push_back((long) str);
args.push_back((long) RTLD_NOW);
auto remote_handle = remote_call(pid, regs, (uintptr_t) dlopen_addr, (uintptr_t) libc_base, args);
auto remote_handle = remote_call(pid, regs, (uintptr_t) dlopen_addr, (uintptr_t) libc_return_addr, args);
LOGD("remote handle %p", (void *) remote_handle);
if (remote_handle == 0) {
LOGE("handle is null");
// call dlerror
auto dlerror_addr = find_func_addr(local_map, map, "libdl.so", "dlerror");
if (dlerror_addr == nullptr) {
LOGE("find dlerror");
return false;
}
args.clear();
auto dlerror_str_addr = remote_call(pid, regs, (uintptr_t) dlerror_addr, (uintptr_t) libc_return_addr, args);
LOGD("dlerror str %p", (void*) dlerror_str_addr);
if (dlerror_str_addr == 0) return false;
auto strlen_addr = find_func_addr(local_map, map, "libc.so", "strlen");
if (strlen_addr == nullptr) {
LOGE("find strlen");
return false;
}
args.clear();
args.push_back(dlerror_str_addr);
auto dlerror_len = remote_call(pid, regs, (uintptr_t) strlen_addr, (uintptr_t) libc_return_addr, args);
LOGD("dlerror len %ld", dlerror_len);
if (dlerror_len <= 0) return false;
std::string err;
err.resize(dlerror_len + 1, 0);
read_proc(pid, (uintptr_t*) dlerror_str_addr, err.data(), dlerror_len);
LOGE("dlerror info %s", err.c_str());
return false;
}
@@ -112,7 +137,7 @@ bool inject_on_main(int pid, const char *lib_path) {
str = push_string(pid, regs, "entry");
args.push_back(remote_handle);
args.push_back((long) str);
auto injector_entry = remote_call(pid, regs, (uintptr_t) dlsym_addr, (uintptr_t) libc_base, args);
auto injector_entry = remote_call(pid, regs, (uintptr_t) dlsym_addr, (uintptr_t) libc_return_addr, args);
LOGD("injector entry %p", (void*) injector_entry);
if (injector_entry == 0) {
LOGE("injector entry is null");
@@ -122,7 +147,7 @@ bool inject_on_main(int pid, const char *lib_path) {
// call injector entry(handle)
args.clear();
args.push_back(remote_handle);
remote_call(pid, regs, injector_entry, (uintptr_t) libc_base, args);
remote_call(pid, regs, injector_entry, (uintptr_t) libc_return_addr, args);
// reset pc to entry
backup.REG_IP = (long) entry_addr;

View File

@@ -152,6 +152,16 @@ std::string get_addr_mem_region(std::vector<MapInfo> &info, void *addr) {
return "<unknown>";
}
void *find_module_return_addr(std::vector<MapInfo> &info, std::string_view suffix) {
for (auto &map: info) {
if ((map.perms & PROT_EXEC) == 0 && map.path.ends_with(suffix)) {
return (void *) map.start;
}
}
return nullptr;
}
void *find_module_base(std::vector<MapInfo> &info, std::string_view suffix) {
for (auto &map: info) {
if (map.offset == 0 && map.path.ends_with(suffix)) {
@@ -301,18 +311,18 @@ uintptr_t remote_call(int pid, struct user_regs_struct &regs, uintptr_t func_add
if (waitpid(pid, &status, __WALL) == -1) {
PLOGE("wait");
}
if (!get_regs(pid, regs)) {
LOGE("failed to get regs after call");
return 0;
}
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSEGV) {
if (!get_regs(pid, regs)) {
LOGE("failed to get regs after call");
return 0;
}
if (regs.REG_IP != return_addr) {
LOGE("wrong return addr %p", (void *) regs.REG_IP);
return 0;
}
return regs.REG_RET;
} else {
LOGE("stopped by other reason %s", parse_status(status).c_str());
LOGE("stopped by other reason %s at addr %p", parse_status(status).c_str(), (void*) regs.REG_IP);
}
return 0;
}

View File

@@ -117,4 +117,5 @@ inline const char* sigabbrev_np(int sig) {
}
std::string get_program(int pid);
void *find_module_return_addr(std::vector<MapInfo> &info, std::string_view suffix);

View File

@@ -31,13 +31,13 @@ create_sys_perm /dev/zygisk
if [ -f $MODDIR/lib64/libzygisk.so ];then
create_sys_perm /dev/zygisk/lib64
cp $MODDIR/lib64/libzygisk.so /dev/zygisk/lib64/libzygisk.so
chcon u:object_r:system_lib_file:s0 /dev/zygisk/lib64/libzygisk.so
chcon u:object_r:system_file:s0 /dev/zygisk/lib64/libzygisk.so
fi
if [ -f $MODDIR/lib/libzygisk.so ];then
create_sys_perm /dev/zygisk/lib
cp $MODDIR/lib/libzygisk.so /dev/zygisk/lib/libzygisk.so
chcon u:object_r:system_lib_file:s0 /dev/zygisk/lib/libzygisk.so
chcon u:object_r:system_file:s0 /dev/zygisk/lib/libzygisk.so
fi
unshare -m sh -c "./bin/zygisk-ptrace64 monitor &"

View File

@@ -17,3 +17,4 @@ allow zygote mnt_vendor_file dir search
allow zygote system_file dir mounton
allow zygote labeledfs filesystem mount
allow zygote fs_type filesystem unmount
allow zygote zygote process execmem