mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 09:47:40 +00:00
Support setting more options
This commit is contained in:
parent
ffb5d9ea9c
commit
4194ac894c
@ -30,16 +30,18 @@ class ExampleModule : public zygisk::ModuleBase {
|
|||||||
public:
|
public:
|
||||||
void onLoad(zygisk::Api *api, JNIEnv *env) override {
|
void onLoad(zygisk::Api *api, JNIEnv *env) override {
|
||||||
this->api = api;
|
this->api = api;
|
||||||
|
this->env = env;
|
||||||
}
|
}
|
||||||
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
|
void preAppSpecialize(zygisk::AppSpecializeArgs *args) override {
|
||||||
JNINativeMethod methods[] = {
|
JNINativeMethod methods[] = {
|
||||||
{ "logger_entry_max_payload_native", "()I", (void*) my_logger_entry_max },
|
{ "logger_entry_max_payload_native", "()I", (void*) my_logger_entry_max },
|
||||||
};
|
};
|
||||||
api->hookJniNativeMethods("android/util/Log", methods, 1);
|
api->hookJniNativeMethods(env, "android/util/Log", methods, 1);
|
||||||
*(void **) &orig_logger_entry_max = methods[0].fnPtr;
|
*(void **) &orig_logger_entry_max = methods[0].fnPtr;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
zygisk::Api *api;
|
zygisk::Api *api;
|
||||||
|
JNIEnv *env;
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_ZYGISK_MODULE(ExampleModule)
|
REGISTER_ZYGISK_MODULE(ExampleModule)
|
||||||
@ -129,6 +131,27 @@ struct api_table;
|
|||||||
template <class T> void entry_impl(api_table *, JNIEnv *);
|
template <class T> void entry_impl(api_table *, JNIEnv *);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// These values are used in Api::setOption(Option)
|
||||||
|
enum Option : int {
|
||||||
|
// Force Magisk's denylist unmount routines to run on this process.
|
||||||
|
//
|
||||||
|
// Setting this option only makes sense in preAppSpecialize.
|
||||||
|
// The actual unmounting happens during app process specialization.
|
||||||
|
//
|
||||||
|
// Processes added to Magisk's denylist will have all Magisk and its modules' files unmounted
|
||||||
|
// from its mount namespace. In addition, all Zygisk code will be unloaded from memory, which
|
||||||
|
// also implies that no Zygisk modules (including yours) are loaded.
|
||||||
|
//
|
||||||
|
// However, if for any reason your module still wants the unmount part of the denylist
|
||||||
|
// operation to be enabled EVEN IF THE PROCESS IS NOT ON THE DENYLIST, set this option.
|
||||||
|
FORCE_DENYLIST_UNMOUNT = 0,
|
||||||
|
|
||||||
|
// When this option is set, your module's library will be dlclose-ed after post[XXX]Specialize.
|
||||||
|
// Be aware that after dlclose-ing your module, all of your code will be unmapped.
|
||||||
|
// YOU SHOULD NOT ENABLE THIS OPTION AFTER HOOKING ANY FUNCTION IN THE PROCESS.
|
||||||
|
DLCLOSE_MODULE_LIBRARY = 1,
|
||||||
|
};
|
||||||
|
|
||||||
struct Api {
|
struct Api {
|
||||||
|
|
||||||
// Connect to a root companion process and get a Unix domain socket for IPC.
|
// Connect to a root companion process and get a Unix domain socket for IPC.
|
||||||
@ -145,22 +168,10 @@ struct Api {
|
|||||||
// 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();
|
||||||
|
|
||||||
// Force Magisk's denylist unmount routines to run on this process.
|
// Set various options for your module.
|
||||||
//
|
// Please note that this function accepts one single option at a time.
|
||||||
// This API only works in preAppSpecialize.
|
// Check zygisk::Option for the full list of options available.
|
||||||
//
|
void setOption(Option opt);
|
||||||
// Processes added to Magisk's denylist will have all Magisk and its modules' files unmounted
|
|
||||||
// from its mount namespace. In addition, all Zygisk code will be unloaded from memory, which
|
|
||||||
// also implies that no Zygisk modules (including yours) are loaded.
|
|
||||||
//
|
|
||||||
// However, if for any reason your module still wants the unmount part of the denylist
|
|
||||||
// operation to be enabled EVEN IF THE PROCESS IS NOT ON THE DENYLIST, call this function.
|
|
||||||
// No code will be unloaded from memory (including your module) because there is no way to
|
|
||||||
// guarantee no crashes will occur.
|
|
||||||
//
|
|
||||||
// The unmounting does not happen immediately after the function is called. It is actually
|
|
||||||
// done during app process specialization.
|
|
||||||
void forceDenyListUnmount();
|
|
||||||
|
|
||||||
// Hook JNI native methods for a class
|
// Hook JNI native methods for a class
|
||||||
//
|
//
|
||||||
@ -244,7 +255,7 @@ struct api_table {
|
|||||||
|
|
||||||
// Zygisk functions
|
// Zygisk functions
|
||||||
int (*connectCompanion)(void * /* _this */);
|
int (*connectCompanion)(void * /* _this */);
|
||||||
void (*forceDenyListUnmount)(void * /* _this */);
|
void (*setOption)(void * /* _this */, Option);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -262,8 +273,8 @@ void entry_impl(api_table *table, JNIEnv *env) {
|
|||||||
int Api::connectCompanion() {
|
int Api::connectCompanion() {
|
||||||
return impl->connectCompanion(impl->_this);
|
return impl->connectCompanion(impl->_this);
|
||||||
}
|
}
|
||||||
void Api::forceDenyListUnmount() {
|
void Api::setOption(Option opt) {
|
||||||
impl->forceDenyListUnmount(impl->_this);
|
impl->setOption(impl->_this, opt);
|
||||||
}
|
}
|
||||||
void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
|
void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
|
||||||
impl->hookJniNativeMethods(env, className, methods, numMethods);
|
impl->hookJniNativeMethods(env, className, methods, numMethods);
|
||||||
|
@ -282,7 +282,7 @@ bool ZygiskModule::registerModule(ApiTable *table, long *module) {
|
|||||||
};
|
};
|
||||||
table->v1.pltHookCommit = []() { return xhook_refresh(0) == 0; };
|
table->v1.pltHookCommit = []() { return xhook_refresh(0) == 0; };
|
||||||
table->v1.connectCompanion = [](ZygiskModule *m) { return m->connectCompanion(); };
|
table->v1.connectCompanion = [](ZygiskModule *m) { return m->connectCompanion(); };
|
||||||
table->v1.forceDenyListUnmount = [](auto) { ZygiskModule::forceDenyListUnmount(); };
|
table->v1.setOption = [](ZygiskModule *m, auto opt) { m->setOption(opt); };
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -297,10 +297,17 @@ int ZygiskModule::connectCompanion() const {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZygiskModule::forceDenyListUnmount() {
|
void ZygiskModule::setOption(zygisk::Option opt) {
|
||||||
if (g_ctx == nullptr)
|
if (g_ctx == nullptr)
|
||||||
return;
|
return;
|
||||||
g_ctx->toggle_unmount();
|
switch (opt) {
|
||||||
|
case zygisk::FORCE_DENYLIST_UNMOUNT:
|
||||||
|
g_ctx->toggle_unmount();
|
||||||
|
break;
|
||||||
|
case zygisk::DLCLOSE_MODULE_LIBRARY:
|
||||||
|
unload = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HookContext::run_modules_pre(const vector<int> &fds) {
|
void HookContext::run_modules_pre(const vector<int> &fds) {
|
||||||
@ -311,7 +318,7 @@ void HookContext::run_modules_pre(const vector<int> &fds) {
|
|||||||
void (*module_entry)(void *, void *);
|
void (*module_entry)(void *, void *);
|
||||||
*(void **) &module_entry = dlsym(h, "zygisk_module_entry");
|
*(void **) &module_entry = dlsym(h, "zygisk_module_entry");
|
||||||
if (module_entry) {
|
if (module_entry) {
|
||||||
modules.emplace_back(i);
|
modules.emplace_back(i, h);
|
||||||
auto api = new ApiTable(&modules.back());
|
auto api = new ApiTable(&modules.back());
|
||||||
module_entry(api, env);
|
module_entry(api, env);
|
||||||
}
|
}
|
||||||
@ -334,6 +341,9 @@ void HookContext::run_modules_post() {
|
|||||||
} else if (flags[SERVER_SPECIALIZE]) {
|
} else if (flags[SERVER_SPECIALIZE]) {
|
||||||
m.postServerSpecialize(server_args);
|
m.postServerSpecialize(server_args);
|
||||||
}
|
}
|
||||||
|
if (m.unload) {
|
||||||
|
dlclose(m.handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +82,13 @@ struct ZygiskModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int connectCompanion() const;
|
int connectCompanion() const;
|
||||||
static void forceDenyListUnmount();
|
void setOption(zygisk::Option opt);
|
||||||
static bool registerModule(ApiTable *table, long *module);
|
static bool registerModule(ApiTable *table, long *module);
|
||||||
|
|
||||||
ZygiskModule(int id) : id(id) {}
|
ZygiskModule(int id, void *handle) : handle(handle), id(id) {}
|
||||||
|
|
||||||
|
void * const handle;
|
||||||
|
bool unload = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int id;
|
int id;
|
||||||
@ -108,7 +111,7 @@ struct ApiTable {
|
|||||||
bool (*pltHookCommit)();
|
bool (*pltHookCommit)();
|
||||||
|
|
||||||
int (*connectCompanion)(ZygiskModule *);
|
int (*connectCompanion)(ZygiskModule *);
|
||||||
void (*forceDenyListUnmount)(ZygiskModule *);
|
void (*setOption)(ZygiskModule *, zygisk::Option);
|
||||||
} v1;
|
} v1;
|
||||||
};
|
};
|
||||||
ApiTable(ZygiskModule *m) : module(m), registerModule(&ZygiskModule::registerModule) {}
|
ApiTable(ZygiskModule *m) : module(m), registerModule(&ZygiskModule::registerModule) {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user