[core] Refine native api [breaking change] (#522)

* [core] Refine native api [breaking change]

* abi

* mprotect
This commit is contained in:
LoveSy 2021-04-28 01:01:19 +08:00 committed by GitHub
parent 3241697028
commit a462d603c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 25 deletions

View File

@ -110,12 +110,12 @@ namespace lspd {
}; };
[[gnu::always_inline]] [[gnu::always_inline]]
static void *Dlsym(void *handle, const char *name) { inline void *Dlsym(void *handle, const char *name) {
return dlsym(handle, name); return dlsym(handle, name);
} }
template<class T, class ... Args> template<class T, class ... Args>
static void *Dlsym(void *handle, T first, Args... last) { inline void *Dlsym(void *handle, T first, Args... last) {
auto ret = Dlsym(handle, first); auto ret = Dlsym(handle, first);
if (ret) { if (ret) {
return ret; return ret;
@ -123,9 +123,27 @@ namespace lspd {
return Dlsym(handle, last...); return Dlsym(handle, last...);
} }
static void HookFunction(void *original, void *replace, void **backup) { inline int HookFunction(void *original, void *replace, void **backup) {
_make_rwx(original, _page_size); _make_rwx(original, _page_size);
hook_func(original, replace, backup); if constexpr (isDebug) {
Dl_info info;
dladdr(original, &info);
LOGD("Hooking %s (%p) from %s (%p)",
info.dli_sname ? info.dli_sname : "(unknown symbol)", info.dli_saddr,
info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase);
}
return DobbyHook(original, replace, backup);
}
inline int UnhookFunction(void *original) {
if constexpr (isDebug) {
Dl_info info;
dladdr(original, &info);
LOGD("Unhooking %s (%p) from %s (%p)",
info.dli_sname ? info.dli_sname : "(unknown symbol)", info.dli_saddr,
info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase);
}
return DobbyDestroy(original);
} }
template<class, template<class, class...> class> template<class, template<class, class...> class>

View File

@ -44,18 +44,22 @@
*/ */
namespace lspd { namespace lspd {
std::vector<LsposedNativeOnModuleLoaded> moduleLoadedCallbacks; std::vector<NativeOnModuleLoaded> moduleLoadedCallbacks;
std::vector<std::string> moduleNativeLibs; std::vector<std::string> moduleNativeLibs;
std::unique_ptr<void, std::function<void(void *)>> protected_page(
mmap(nullptr, _page_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0),
[](void *ptr) { munmap(ptr, _page_size); });
LsposedNativeAPIEntriesV1 init(LsposedNativeOnModuleLoaded onModuleLoaded) { const auto[entries] = []() {
if (onModuleLoaded != nullptr) moduleLoadedCallbacks.push_back(onModuleLoaded); auto *entries = new(protected_page.get()) NativeAPIEntries{
.version = 2,
LsposedNativeAPIEntriesV1 ret{ .hookFunc = HookFunction,
.version = 1, .unhookFunc = UnhookFunction
.inlineHookFunc = HookFunction
}; };
return ret;
} mprotect(protected_page.get(), _page_size, PROT_READ);
return std::make_tuple(entries);
}();
void RegisterNativeLib(const std::string &library_name) { void RegisterNativeLib(const std::string &library_name) {
static bool initialized = []() { static bool initialized = []() {
@ -102,12 +106,17 @@ namespace lspd {
break; break;
} }
auto native_init = reinterpret_cast<NativeInit>(native_init_sym); auto native_init = reinterpret_cast<NativeInit>(native_init_sym);
native_init(reinterpret_cast<void *>(init)); auto *callback = native_init(entries);
if (callback) {
moduleLoadedCallbacks.push_back(callback);
// return directly to avoid module interaction
return handle;
}
} }
} }
// Callbacks // Callbacks
for (LsposedNativeOnModuleLoaded callback: moduleLoadedCallbacks) { for (auto &callback: moduleLoadedCallbacks) {
callback(name, handle); callback(name, handle);
} }
return handle; return handle;

View File

@ -29,17 +29,24 @@
#include <string> #include <string>
#include <base/object.h> #include <base/object.h>
// typedef int (*HookFunType)(void *, void *, void **); // For portability typedef int (*HookFunType)(void *func, void *replace, void **backup);
typedef void (*LsposedNativeOnModuleLoaded) (const char* name, void* handle);
typedef void (*NativeInit)(void * init_func); typedef int (*UnhookFunType)(void *func);
struct LsposedNativeAPIEntriesV1 {
typedef void (*NativeOnModuleLoaded)(const char *name, void *handle);
typedef struct {
uint32_t version; uint32_t version;
lspd::HookFunType inlineHookFunc; HookFunType hookFunc;
}; UnhookFunType unhookFunc;
} NativeAPIEntries;
typedef NativeOnModuleLoaded (*NativeInit)(const NativeAPIEntries *entries);
namespace lspd { namespace lspd {
void InstallNativeAPI(); void InstallNativeAPI();
void RegisterNativeLib(const std::string& library_name);
void RegisterNativeLib(const std::string &library_name);
} }
#endif //LSPOSED_NATIVE_API_H #endif //LSPOSED_NATIVE_API_H

View File

@ -42,7 +42,6 @@
#include "art/runtime/gc/scoped_gc_critical_section.h" #include "art/runtime/gc/scoped_gc_critical_section.h"
namespace lspd { namespace lspd {
static volatile bool installed = false; static volatile bool installed = false;
static volatile bool art_hooks_installed = false; static volatile bool art_hooks_installed = false;

View File

@ -19,11 +19,10 @@
*/ */
#pragma once #pragma once
#include <dobby.h> #include <dobby.h>
namespace lspd { namespace lspd {
typedef void (*HookFunType)(void *, void *, void **);
static HookFunType hook_func = reinterpret_cast<HookFunType>(DobbyHook);
void InstallInlineHooks(); void InstallInlineHooks();
} }