mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 21:07:38 +00:00
Cleanup APIs
This commit is contained in:
parent
aa0a2f77cf
commit
636223b289
@ -228,21 +228,9 @@ struct Api {
|
|||||||
// will be set to nullptr.
|
// will be set to nullptr.
|
||||||
void hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods);
|
void hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods);
|
||||||
|
|
||||||
// For ELFs loaded in memory matching `regex`, replace function `symbol` with `newFunc`.
|
|
||||||
// If `oldFunc` is not nullptr, the original function pointer will be saved to `oldFunc`.
|
|
||||||
void pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc);
|
|
||||||
|
|
||||||
// For ELFs loaded in memory matching `regex`, exclude hooks registered for `symbol`.
|
|
||||||
// If `symbol` is nullptr, then all symbols will be excluded.
|
|
||||||
void pltHookExclude(const char *regex, const char *symbol);
|
|
||||||
|
|
||||||
// For ELFs loaded in memory matching `inode`, replace function `symbol` with `newFunc`.
|
// For ELFs loaded in memory matching `inode`, replace function `symbol` with `newFunc`.
|
||||||
// If `oldFunc` is not nullptr, the original function pointer will be saved to `oldFunc`.
|
// If `oldFunc` is not nullptr, the original function pointer will be saved to `oldFunc`.
|
||||||
void pltHookRegisterInode(ino_t inode, const char *symbol, void *newFunc, void **oldFunc);
|
void pltHookRegister(ino_t inode, const char *symbol, void *newFunc, void **oldFunc);
|
||||||
|
|
||||||
// For ELFs loaded in memory matching `inode`, exclude hooks registered for `symbol`.
|
|
||||||
// If `symbol` is nullptr, then all symbols will be excluded.
|
|
||||||
void pltHookExcludeInode(ino_t inode, const char *symbol);
|
|
||||||
|
|
||||||
// Commit all the hooks that was previously registered.
|
// Commit all the hooks that was previously registered.
|
||||||
// Returns false if an error occurred.
|
// Returns false if an error occurred.
|
||||||
@ -303,16 +291,13 @@ struct api_table {
|
|||||||
bool (*registerModule)(api_table *, module_abi *);
|
bool (*registerModule)(api_table *, module_abi *);
|
||||||
|
|
||||||
void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
|
void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
|
||||||
void (*pltHookRegister)(const char *, const char *, void *, void **);
|
void (*pltHookRegister)(ino_t, const char *, void *, void **);
|
||||||
void (*pltHookExclude)(const char *, const char *);
|
bool (*exemptFd)(int);
|
||||||
bool (*pltHookCommit)();
|
bool (*pltHookCommit)();
|
||||||
int (*connectCompanion)(void * /* impl */);
|
int (*connectCompanion)(void * /* impl */);
|
||||||
void (*setOption)(void * /* impl */, Option);
|
void (*setOption)(void * /* impl */, Option);
|
||||||
int (*getModuleDir)(void * /* impl */);
|
int (*getModuleDir)(void * /* impl */);
|
||||||
uint32_t (*getFlags)(void * /* impl */);
|
uint32_t (*getFlags)(void * /* impl */);
|
||||||
bool (*exemptFd)(int);
|
|
||||||
void (*pltHookRegisterInode)(ino_t, const char *, void *, void **);
|
|
||||||
void (*pltHookExcludeInode)(ino_t, const char *);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -342,20 +327,11 @@ inline uint32_t Api::getFlags() {
|
|||||||
inline bool Api::exemptFd(int fd) {
|
inline bool Api::exemptFd(int fd) {
|
||||||
return tbl->exemptFd != nullptr && tbl->exemptFd(fd);
|
return tbl->exemptFd != nullptr && tbl->exemptFd(fd);
|
||||||
}
|
}
|
||||||
inline void Api::pltHookRegisterInode(ino_t inode, const char *symbol, void *newFunc, void **oldFunc) {
|
|
||||||
if (tbl->pltHookExcludeInode) tbl->pltHookRegisterInode(inode, symbol, newFunc, oldFunc);
|
|
||||||
}
|
|
||||||
inline void Api::pltHookExcludeInode(ino_t inode, const char *symbol) {
|
|
||||||
if (tbl->pltHookExcludeInode) tbl->pltHookExcludeInode(inode, symbol);
|
|
||||||
}
|
|
||||||
inline void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
|
inline void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
|
||||||
if (tbl->hookJniNativeMethods) tbl->hookJniNativeMethods(env, className, methods, numMethods);
|
if (tbl->hookJniNativeMethods) tbl->hookJniNativeMethods(env, className, methods, numMethods);
|
||||||
}
|
}
|
||||||
inline void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) {
|
inline void Api::pltHookRegister(ino_t inode, const char *symbol, void *newFunc, void **oldFunc) {
|
||||||
if (tbl->pltHookRegister) tbl->pltHookRegister(regex, symbol, newFunc, oldFunc);
|
if (tbl->pltHookRegister) tbl->pltHookRegister(inode, symbol, newFunc, oldFunc);
|
||||||
}
|
|
||||||
inline void Api::pltHookExclude(const char *regex, const char *symbol) {
|
|
||||||
if (tbl->pltHookExclude) tbl->pltHookExclude(regex, symbol);
|
|
||||||
}
|
}
|
||||||
inline bool Api::pltHookCommit() {
|
inline bool Api::pltHookCommit() {
|
||||||
return tbl->pltHookCommit != nullptr && tbl->pltHookCommit();
|
return tbl->pltHookCommit != nullptr && tbl->pltHookCommit();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <android/dlext.h>
|
#include <android/dlext.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <regex.h>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
@ -63,7 +64,25 @@ struct HookContext {
|
|||||||
bitset<MAX_FD_SIZE> allowed_fds;
|
bitset<MAX_FD_SIZE> allowed_fds;
|
||||||
vector<int> exempted_fds;
|
vector<int> exempted_fds;
|
||||||
|
|
||||||
HookContext() : env(nullptr), args{nullptr}, process(nullptr), pid(-1), info_flags(0) {}
|
struct RegisterInfo {
|
||||||
|
regex_t regex;
|
||||||
|
string symbol;
|
||||||
|
void *callback;
|
||||||
|
void **backup;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IgnoreInfo {
|
||||||
|
regex_t regex;
|
||||||
|
string symbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
pthread_mutex_t hook_info_lock;
|
||||||
|
vector<RegisterInfo> register_info;
|
||||||
|
vector<IgnoreInfo> ignore_info;
|
||||||
|
|
||||||
|
HookContext() :
|
||||||
|
env(nullptr), args{nullptr}, process(nullptr), pid(-1), info_flags(0),
|
||||||
|
hook_info_lock(PTHREAD_MUTEX_INITIALIZER) {}
|
||||||
|
|
||||||
void run_modules_pre(const vector<int> &fds);
|
void run_modules_pre(const vector<int> &fds);
|
||||||
void run_modules_post();
|
void run_modules_post();
|
||||||
@ -76,12 +95,19 @@ struct HookContext {
|
|||||||
void unload_zygisk();
|
void unload_zygisk();
|
||||||
void sanitize_fds();
|
void sanitize_fds();
|
||||||
bool exempt_fd(int fd);
|
bool exempt_fd(int fd);
|
||||||
|
|
||||||
|
// Compatibility shim
|
||||||
|
void plt_hook_register(const char *regex, const char *symbol, void *fn, void **backup);
|
||||||
|
void plt_hook_exclude(const char *regex, const char *symbol);
|
||||||
|
void plt_hook_process_regex();
|
||||||
|
|
||||||
|
bool plt_hook_commit();
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef DCL_PRE_POST
|
#undef DCL_PRE_POST
|
||||||
|
|
||||||
// Global variables
|
// Global variables
|
||||||
vector<tuple<ino_t, const char *, void **>> *xhook_list;
|
vector<tuple<ino_t, const char *, void **>> *plt_hook_list;
|
||||||
map<string, vector<JNINativeMethod>, StringCmp> *jni_hook_list;
|
map<string, vector<JNINativeMethod>, StringCmp> *jni_hook_list;
|
||||||
hash_map<xstring, tree_map<xstring, tree_map<xstring, void *>>> *jni_method_map;
|
hash_map<xstring, tree_map<xstring, tree_map<xstring, void *>>> *jni_method_map;
|
||||||
|
|
||||||
@ -325,77 +351,64 @@ bool ZygiskModule::RegisterModuleImpl(ApiTable *api, long *module) {
|
|||||||
api->base.impl->mod = { module };
|
api->base.impl->mod = { module };
|
||||||
|
|
||||||
// Fill in API accordingly with module API version
|
// Fill in API accordingly with module API version
|
||||||
switch (api_version) {
|
if (api_version >= 1) {
|
||||||
case 4:
|
|
||||||
api->v4.exemptFd = [](int fd) { return g_ctx != nullptr && g_ctx->exempt_fd(fd); };
|
|
||||||
api->v4.pltHookRegisterInode = PltHookRegister;
|
|
||||||
api->v4.pltHookExcludeInode = PltHookExclude;
|
|
||||||
[[fallthrough]];
|
|
||||||
case 3:
|
|
||||||
case 2:
|
|
||||||
api->v2.getModuleDir = [](ZygiskModule *m) { return m->getModuleDir(); };
|
|
||||||
api->v2.getFlags = [](auto) { return ZygiskModule::getFlags(); };
|
|
||||||
[[fallthrough]];
|
|
||||||
case 1:
|
|
||||||
api->v1.hookJniNativeMethods = hookJniNativeMethods;
|
api->v1.hookJniNativeMethods = hookJniNativeMethods;
|
||||||
api->v1.pltHookRegister = PltHookRegister;
|
api->v1.pltHookRegister = [](auto a, auto b, auto c, auto d) {
|
||||||
api->v1.pltHookExclude = PltHookExclude;
|
if (g_ctx) g_ctx->plt_hook_register(a, b, c, d);
|
||||||
api->v1.pltHookCommit = CommitPltHook;
|
};
|
||||||
|
api->v1.pltHookExclude = [](auto a, auto b) {
|
||||||
|
if (g_ctx) g_ctx->plt_hook_exclude(a, b);
|
||||||
|
};
|
||||||
|
api->v1.pltHookCommit = []() { return g_ctx && g_ctx->plt_hook_commit(); };
|
||||||
api->v1.connectCompanion = [](ZygiskModule *m) { return m->connectCompanion(); };
|
api->v1.connectCompanion = [](ZygiskModule *m) { return m->connectCompanion(); };
|
||||||
api->v1.setOption = [](ZygiskModule *m, auto opt) { m->setOption(opt); };
|
api->v1.setOption = [](ZygiskModule *m, auto opt) { m->setOption(opt); };
|
||||||
break;
|
}
|
||||||
default:
|
if (api_version >= 2) {
|
||||||
// Unknown version number
|
api->v2.getModuleDir = [](ZygiskModule *m) { return m->getModuleDir(); };
|
||||||
return false;
|
api->v2.getFlags = [](auto) { return ZygiskModule::getFlags(); };
|
||||||
|
}
|
||||||
|
if (api_version >= 4) {
|
||||||
|
api->v4.pltHookRegister = [](ino_t inode, const char *symbol, void *fn, void **backup) {
|
||||||
|
if (inode == 0 || symbol == nullptr || fn == nullptr)
|
||||||
|
return;
|
||||||
|
lsplt::RegisterHook(inode, symbol, fn, backup);
|
||||||
|
};
|
||||||
|
api->v4.exemptFd = [](int fd) { return g_ctx && g_ctx->exempt_fd(fd); };
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZygiskModule::PltHookRegister(const char* regex, const char *symbol, void *callback, void **backup) {
|
void HookContext::plt_hook_register(const char *regex, const char *symbol, void *fn, void **backup) {
|
||||||
if (regex == nullptr || symbol == nullptr || callback == nullptr)
|
if (regex == nullptr || symbol == nullptr || fn == nullptr)
|
||||||
return;
|
return;
|
||||||
regex_t re;
|
regex_t re;
|
||||||
if (regcomp(&re, regex, REG_NOSUB) != 0)
|
if (regcomp(&re, regex, REG_NOSUB) != 0)
|
||||||
return;
|
return;
|
||||||
mutex_guard lock(hook_lock);
|
mutex_guard lock(hook_info_lock);
|
||||||
register_info.emplace_back(RegisterInfo{re, 0, symbol, callback, backup});
|
register_info.emplace_back(RegisterInfo{re, symbol, fn, backup});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZygiskModule::PltHookRegister(ino_t inode, const char *symbol, void *callback, void **backup) {
|
void HookContext::plt_hook_exclude(const char *regex, const char *symbol) {
|
||||||
if (inode == 0 || symbol == nullptr || callback == nullptr)
|
|
||||||
return;
|
|
||||||
mutex_guard lock(hook_lock);
|
|
||||||
register_info.emplace_back(RegisterInfo{{}, inode, symbol, callback, backup});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZygiskModule::PltHookExclude(const char* regex, const char *symbol) {
|
|
||||||
if (!regex) return;
|
if (!regex) return;
|
||||||
regex_t re;
|
regex_t re;
|
||||||
if (regcomp(&re, regex, REG_NOSUB) != 0)
|
if (regcomp(&re, regex, REG_NOSUB) != 0)
|
||||||
return;
|
return;
|
||||||
mutex_guard lock(hook_lock);
|
mutex_guard lock(hook_info_lock);
|
||||||
ignore_info.emplace_back(IgnoreInfo{re, 0, symbol ? symbol : ""});
|
ignore_info.emplace_back(IgnoreInfo{re, symbol ?: ""});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZygiskModule::PltHookExclude(ino_t inode, const char *symbol) {
|
void HookContext::plt_hook_process_regex() {
|
||||||
if (inode == 0) return;
|
if (register_info.empty())
|
||||||
mutex_guard lock(hook_lock);
|
return;
|
||||||
ignore_info.emplace_back(IgnoreInfo{{}, inode, symbol ? symbol : ""});
|
for (auto &map : lsplt::MapInfo::Scan()) {
|
||||||
}
|
|
||||||
|
|
||||||
bool ZygiskModule::CommitPltHook() {
|
|
||||||
mutex_guard lock(hook_lock);
|
|
||||||
for (auto &map: lsplt::MapInfo::Scan()) {
|
|
||||||
if (map.offset != 0 || !map.is_private || !(map.perms & PROT_READ)) continue;
|
if (map.offset != 0 || !map.is_private || !(map.perms & PROT_READ)) continue;
|
||||||
for (auto ®: register_info) {
|
for (auto ®: register_info) {
|
||||||
if ((reg.inode != 0 && reg.inode != map.inode)||
|
if (regexec(®.regex, map.path.data(), 0, nullptr, 0) != 0)
|
||||||
(reg.inode == 0 && regexec(®.regex, map.path.c_str(), 0, nullptr, 0) != 0))
|
|
||||||
continue;
|
continue;
|
||||||
bool ignored = false;
|
bool ignored = false;
|
||||||
for (auto &ign: ignore_info) {
|
for (auto &ign: ignore_info) {
|
||||||
if ((ign.inode != 0 && ign.inode != map.inode) ||
|
if (regexec(&ign.regex, map.path.data(), 0, nullptr, 0) != 0)
|
||||||
(ign.inode == 0 && regexec(&ign.regex, map.path.c_str(), 0, nullptr, 0) != 0))
|
|
||||||
continue;
|
continue;
|
||||||
if (ign.symbol.empty() || ign.symbol == reg.symbol) {
|
if (ign.symbol.empty() || ign.symbol == reg.symbol) {
|
||||||
ignored = true;
|
ignored = true;
|
||||||
@ -407,8 +420,15 @@ bool ZygiskModule::CommitPltHook() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
register_info.clear();
|
}
|
||||||
ignore_info.clear();
|
|
||||||
|
bool HookContext::plt_hook_commit() {
|
||||||
|
{
|
||||||
|
mutex_guard lock(hook_info_lock);
|
||||||
|
plt_hook_process_regex();
|
||||||
|
register_info.clear();
|
||||||
|
ignore_info.clear();
|
||||||
|
}
|
||||||
return lsplt::CommitHook();
|
return lsplt::CommitHook();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,31 +768,31 @@ void HookContext::nativeForkAndSpecialize_post() {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
static bool hook_refresh() {
|
static bool hook_commit() {
|
||||||
if (lsplt::CommitHook()) {
|
if (lsplt::CommitHook()) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ZLOGE("xhook failed\n");
|
ZLOGE("plt_hook failed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hook_register(ino_t inode, const char *symbol, void *new_func, void **old_func) {
|
static void hook_register(ino_t inode, const char *symbol, void *new_func, void **old_func) {
|
||||||
if (!lsplt::RegisterHook(inode, symbol, new_func, old_func)) {
|
if (!lsplt::RegisterHook(inode, symbol, new_func, old_func)) {
|
||||||
ZLOGE("Failed to register hook \"%s\"\n", symbol);
|
ZLOGE("Failed to register plt_hook \"%s\"\n", symbol);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xhook_list->emplace_back(inode, symbol, old_func);
|
plt_hook_list->emplace_back(inode, symbol, old_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define XHOOK_REGISTER_SYM(PATH_REGEX, SYM, NAME) \
|
#define PLT_HOOK_REGISTER_SYM(PATH_REGEX, SYM, NAME) \
|
||||||
hook_register(PATH_REGEX, SYM, (void*) new_##NAME, (void **) &old_##NAME)
|
hook_register(PATH_REGEX, SYM, (void*) new_##NAME, (void **) &old_##NAME)
|
||||||
|
|
||||||
#define XHOOK_REGISTER(PATH_REGEX, NAME) \
|
#define PLT_HOOK_REGISTER(PATH_REGEX, NAME) \
|
||||||
XHOOK_REGISTER_SYM(PATH_REGEX, #NAME, NAME)
|
PLT_HOOK_REGISTER_SYM(PATH_REGEX, #NAME, NAME)
|
||||||
|
|
||||||
void hook_functions() {
|
void hook_functions() {
|
||||||
default_new(xhook_list);
|
default_new(plt_hook_list);
|
||||||
default_new(jni_hook_list);
|
default_new(jni_hook_list);
|
||||||
default_new(jni_method_map);
|
default_new(jni_method_map);
|
||||||
|
|
||||||
@ -784,26 +804,26 @@ void hook_functions() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XHOOK_REGISTER(android_runtime_inode, fork);
|
PLT_HOOK_REGISTER(android_runtime_inode, fork);
|
||||||
XHOOK_REGISTER(android_runtime_inode, unshare);
|
PLT_HOOK_REGISTER(android_runtime_inode, unshare);
|
||||||
XHOOK_REGISTER(android_runtime_inode, jniRegisterNativeMethods);
|
PLT_HOOK_REGISTER(android_runtime_inode, jniRegisterNativeMethods);
|
||||||
XHOOK_REGISTER(android_runtime_inode, selinux_android_setcontext);
|
PLT_HOOK_REGISTER(android_runtime_inode, selinux_android_setcontext);
|
||||||
XHOOK_REGISTER_SYM(android_runtime_inode, "__android_log_close", android_log_close);
|
PLT_HOOK_REGISTER_SYM(android_runtime_inode, "__android_log_close", android_log_close);
|
||||||
hook_refresh();
|
hook_commit();
|
||||||
|
|
||||||
// Remove unhooked methods
|
// Remove unhooked methods
|
||||||
xhook_list->erase(
|
plt_hook_list->erase(
|
||||||
std::remove_if(xhook_list->begin(), xhook_list->end(),
|
std::remove_if(plt_hook_list->begin(), plt_hook_list->end(),
|
||||||
[](auto &t) { return *std::get<2>(t) == nullptr;}),
|
[](auto &t) { return *std::get<2>(t) == nullptr;}),
|
||||||
xhook_list->end());
|
plt_hook_list->end());
|
||||||
|
|
||||||
if (old_jniRegisterNativeMethods == nullptr) {
|
if (old_jniRegisterNativeMethods == nullptr) {
|
||||||
ZLOGD("jniRegisterNativeMethods not hooked, using fallback\n");
|
ZLOGD("jniRegisterNativeMethods not hooked, using fallback\n");
|
||||||
struct stat self_stat{};
|
struct stat self_stat{};
|
||||||
stat("/proc/self/exe", &self_stat);
|
stat("/proc/self/exe", &self_stat);
|
||||||
// android::AndroidRuntime::setArgv0(const char*, bool)
|
// android::AndroidRuntime::setArgv0(const char*, bool)
|
||||||
XHOOK_REGISTER_SYM(self_stat.st_ino, "_ZN7android14AndroidRuntime8setArgv0EPKcb", setArgv0);
|
PLT_HOOK_REGISTER_SYM(self_stat.st_ino, "_ZN7android14AndroidRuntime8setArgv0EPKcb", setArgv0);
|
||||||
hook_refresh();
|
hook_commit();
|
||||||
|
|
||||||
// We still need old_jniRegisterNativeMethods as other code uses it
|
// We still need old_jniRegisterNativeMethods as other code uses it
|
||||||
// android::AndroidRuntime::registerNativeMethods(_JNIEnv*, const char*, const JNINativeMethod*, int)
|
// android::AndroidRuntime::registerNativeMethods(_JNIEnv*, const char*, const JNINativeMethod*, int)
|
||||||
@ -835,16 +855,16 @@ static bool unhook_functions() {
|
|||||||
}
|
}
|
||||||
delete jni_hook_list;
|
delete jni_hook_list;
|
||||||
|
|
||||||
// Unhook xhook
|
// Unhook plt_hook
|
||||||
for (const auto &[inode, sym, old_func] : *xhook_list) {
|
for (const auto &[inode, sym, old_func] : *plt_hook_list) {
|
||||||
if (!lsplt::RegisterHook(inode, sym, *old_func, nullptr)) {
|
if (!lsplt::RegisterHook(inode, sym, *old_func, nullptr)) {
|
||||||
ZLOGE("Failed to register xhook [%s]\n", sym);
|
ZLOGE("Failed to register plt_hook [%s]\n", sym);
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete xhook_list;
|
delete plt_hook_list;
|
||||||
if (!hook_refresh()) {
|
if (!hook_commit()) {
|
||||||
ZLOGE("Failed to restore xhook\n");
|
ZLOGE("Failed to restore plt_hook\n");
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "api.hpp"
|
#include "api.hpp"
|
||||||
#include <list>
|
|
||||||
#include <regex.h>
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@ -126,24 +124,28 @@ struct api_abi_base {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct api_abi_v1 : public api_abi_base {
|
struct api_abi_v1 : public api_abi_base {
|
||||||
void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
|
/* 0 */ void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
|
||||||
void (*pltHookRegister)(const char *, const char *, void *, void **);
|
/* 1 */ void (*pltHookRegister)(const char *, const char *, void *, void **);
|
||||||
void (*pltHookExclude)(const char *, const char *);
|
/* 2 */ void (*pltHookExclude)(const char *, const char *);
|
||||||
bool (*pltHookCommit)();
|
/* 3 */ bool (*pltHookCommit)();
|
||||||
|
/* 4 */ int (*connectCompanion)(ZygiskModule *);
|
||||||
int (*connectCompanion)(ZygiskModule *);
|
/* 5 */ void (*setOption)(ZygiskModule *, zygisk::Option);
|
||||||
void (*setOption)(ZygiskModule *, zygisk::Option);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct api_abi_v2 : public api_abi_v1 {
|
struct api_abi_v2 : public api_abi_v1 {
|
||||||
int (*getModuleDir)(ZygiskModule *);
|
/* 6 */ int (*getModuleDir)(ZygiskModule *);
|
||||||
uint32_t (*getFlags)(ZygiskModule *);
|
/* 7 */ uint32_t (*getFlags)(ZygiskModule *);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct api_abi_v4 : public api_abi_v2 {
|
struct api_abi_v4 : public api_abi_base {
|
||||||
bool (*exemptFd)(int);
|
/* 0 */ void (*hookJniNativeMethods)(JNIEnv *, const char *, JNINativeMethod *, int);
|
||||||
void (*pltHookRegisterInode)(ino_t, const char *, void *, void **);
|
/* 1 */ void (*pltHookRegister)(ino_t, const char *, void *, void **);
|
||||||
void (*pltHookExcludeInode)(ino_t, const char *);
|
/* 2 */ bool (*exemptFd)(int);
|
||||||
|
/* 3 */ bool (*pltHookCommit)();
|
||||||
|
/* 4 */ int (*connectCompanion)(ZygiskModule *);
|
||||||
|
/* 5 */ void (*setOption)(ZygiskModule *, zygisk::Option);
|
||||||
|
/* 6 */ int (*getModuleDir)(ZygiskModule *);
|
||||||
|
/* 7 */ uint32_t (*getFlags)(ZygiskModule *);
|
||||||
};
|
};
|
||||||
|
|
||||||
union ApiTable {
|
union ApiTable {
|
||||||
@ -214,29 +216,6 @@ private:
|
|||||||
long *api_version;
|
long *api_version;
|
||||||
module_abi_v1 *v1;
|
module_abi_v1 *v1;
|
||||||
} mod;
|
} mod;
|
||||||
|
|
||||||
struct RegisterInfo {
|
|
||||||
regex_t regex;
|
|
||||||
ino_t inode;
|
|
||||||
std::string symbol;
|
|
||||||
void *callback;
|
|
||||||
void **backup;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IgnoreInfo {
|
|
||||||
regex_t regex;
|
|
||||||
ino_t inode;
|
|
||||||
std::string symbol;
|
|
||||||
};
|
|
||||||
inline static pthread_mutex_t hook_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
inline static std::list<RegisterInfo> register_info {};
|
|
||||||
inline static std::list<IgnoreInfo> ignore_info {};
|
|
||||||
|
|
||||||
static void PltHookRegister(const char *lib, const char *symbol, void *callback, void **backup);
|
|
||||||
static void PltHookRegister(ino_t inode, const char *symbol, void *callback, void **backup);
|
|
||||||
static void PltHookExclude(const char *lib, const char *symbol);
|
|
||||||
static void PltHookExclude(ino_t inode, const char *symbol);
|
|
||||||
static bool CommitPltHook();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user