Indicate plt hook explicitly

The file magisk_loader.cpp is reformatted using clangd
This commit is contained in:
JingMatrix 2024-09-12 14:07:16 +02:00
parent c2c4e5207f
commit e28e194682
5 changed files with 190 additions and 202 deletions

View File

@ -80,7 +80,7 @@ static dev_t dev = 0;
static ino_t inode = 0;
static std::vector<std::pair<const char *, void **>> plt_hook_saved = {};
inline int HookArtFunction(void *art_symbol, void *callback, void **backup, bool save = true) {
inline int HookPLT(void *art_symbol, void *callback, void **backup, bool save = true) {
auto symbol = reinterpret_cast<const char *>(art_symbol);
if (GetArt()->isStripped()) {
@ -106,25 +106,25 @@ inline int HookArtFunction(void *art_symbol, void *callback, void **backup, bool
if (auto addr = GetArt()->getSymbAddress(symbol); addr) {
Dl_info info;
if (dladdr(addr, &info) && info.dli_sname != nullptr && strcmp(info.dli_sname, symbol) == 0)
HookFunction(addr, callback, backup);
HookInline(addr, callback, backup);
} else if (*backup == nullptr && isDebug) {
LOGW("Failed to {} Art symbol {}", save ? "hook" : "unhook", symbol);
}
return *backup == nullptr;
}
inline int UnhookArtFunction(void *original) {
inline int UnhookPLT(void *original) {
Dl_info info;
if (!dladdr(original, &info) || info.dli_sname != nullptr) return 1;
if (!GetArt()->isStripped()) return UnhookFunction(original);
if (!GetArt()->isStripped()) return UnhookInline(original);
auto hook_iter =
std::find_if(plt_hook_saved.begin(), plt_hook_saved.end(),
[info](auto record) { return strcmp(record.first, info.dli_sname) == 0; });
void *stub = nullptr;
if (hook_iter != plt_hook_saved.end() &&
HookArtFunction(original, *(hook_iter->second), &stub, false)) {
HookPLT(original, *(hook_iter->second), &stub, false)) {
plt_hook_saved.erase(hook_iter);
return 0;
}

View File

@ -58,8 +58,8 @@ namespace lspd {
const auto[entries] = []() {
auto *entries = new(protected_page.get()) NativeAPIEntries{
.version = 2,
.hookFunc = &HookFunction,
.unhookFunc = &UnhookFunction,
.hookFunc = &HookInline,
.unhookFunc = &UnhookInline,
};
mprotect(protected_page.get(), 4096, PROT_READ);
@ -71,7 +71,7 @@ namespace lspd {
return InstallNativeAPI(lsplant::InitInfo {
.inline_hooker = [](auto t, auto r) {
void* bk = nullptr;
return HookFunction(t, r, &bk) == 0 ? bk : nullptr;
return HookInline(t, r, &bk) == 0 ? bk : nullptr;
},
.art_symbol_resolver = [](auto symbol){
return GetLinker()->getSymbAddress(symbol);

View File

@ -52,7 +52,7 @@ namespace lspd {
void RegisterNativeLib(const std::string &library_name);
inline int HookFunction(void *original, void *replace, void **backup) {
inline int HookInline(void *original, void *replace, void **backup) {
if constexpr (isDebug) {
Dl_info info;
if (dladdr(original, &info))
@ -64,7 +64,7 @@ namespace lspd {
return DobbyHook(original, reinterpret_cast<dobby_dummy_func_t>(replace), reinterpret_cast<dobby_dummy_func_t *>(backup));
}
inline int UnhookFunction(void *original) {
inline int UnhookInline(void *original) {
if constexpr (isDebug) {
Dl_info info;
if (dladdr(original, &info))

2
external/lsplant vendored

@ -1 +1 @@
Subproject commit 2a18d73b4d2150ca02b30938c0e82eb9aab1619e
Subproject commit d73aa7f9742b3c13084bb719962cfcd9358dd0f3

View File

@ -18,6 +18,8 @@
* Copyright (C) 2021 - 2022 LSPosed Contributors
*/
#include "magisk_loader.h"
#include <fcntl.h>
#include <linux/fs.h>
#include <sys/mman.h>
@ -25,7 +27,6 @@
#include "config_impl.h"
#include "elf_util.h"
#include "loader.h"
#include "magisk_loader.h"
#include "native_util.h"
#include "service.h"
#include "symbol_cache.h"
@ -36,23 +37,23 @@ using namespace lsplant;
static_assert(FS_IOC_SETFLAGS == LP_SELECT(0x40046602, 0x40086602));
namespace lspd {
extern int *allowUnload;
jboolean is_parasitic_manager = JNI_FALSE;
extern int *allowUnload;
jboolean is_parasitic_manager = JNI_FALSE;
constexpr int FIRST_ISOLATED_UID = 99000;
constexpr int LAST_ISOLATED_UID = 99999;
constexpr int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000;
constexpr int LAST_APP_ZYGOTE_ISOLATED_UID = 98999;
constexpr int SHARED_RELRO_UID = 1037;
constexpr int PER_USER_RANGE = 100000;
constexpr int FIRST_ISOLATED_UID = 99000;
constexpr int LAST_ISOLATED_UID = 99999;
constexpr int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000;
constexpr int LAST_APP_ZYGOTE_ISOLATED_UID = 98999;
constexpr int SHARED_RELRO_UID = 1037;
constexpr int PER_USER_RANGE = 100000;
static constexpr uid_t kAidInjected = INJECTED_AID;
static constexpr uid_t kAidInet = 3003;
static constexpr uid_t kAidInjected = INJECTED_AID;
static constexpr uid_t kAidInet = 3003;
void MagiskLoader::LoadDex(JNIEnv *env, PreloadedDex &&dex) {
void MagiskLoader::LoadDex(JNIEnv *env, PreloadedDex &&dex) {
auto classloader = JNI_FindClass(env, "java/lang/ClassLoader");
auto getsyscl_mid = JNI_GetStaticMethodID(
env, classloader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
auto getsyscl_mid = JNI_GetStaticMethodID(env, classloader, "getSystemClassLoader",
"()Ljava/lang/ClassLoader;");
auto sys_classloader = JNI_CallStaticObjectMethod(env, classloader, getsyscl_mid);
if (!sys_classloader) [[unlikely]] {
LOGE("getSystemClassLoader failed!!!");
@ -63,8 +64,8 @@ namespace lspd {
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
auto byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer");
auto dex_buffer = env->NewDirectByteBuffer(dex.data(), dex.size());
if (auto my_cl = JNI_NewObject(env, in_memory_classloader, initMid,
dex_buffer, sys_classloader)) {
if (auto my_cl =
JNI_NewObject(env, in_memory_classloader, initMid, dex_buffer, sys_classloader)) {
inject_class_loader_ = JNI_NewGlobalRef(env, my_cl);
} else {
LOGE("InMemoryDexClassLoader creation failed!!!");
@ -72,29 +73,26 @@ namespace lspd {
}
env->DeleteLocalRef(dex_buffer);
}
}
std::string GetEntryClassName() {
std::string GetEntryClassName() {
const auto &obfs_map = ConfigBridge::GetInstance()->obfuscation_map();
static auto signature = obfs_map.at("org.lsposed.lspd.core.") + "Main";
return signature;
}
}
void MagiskLoader::SetupEntryClass(JNIEnv *env) {
if (auto entry_class = FindClassFromLoader(env, GetCurrentClassLoader(),
GetEntryClassName())) {
void MagiskLoader::SetupEntryClass(JNIEnv *env) {
if (auto entry_class = FindClassFromLoader(env, GetCurrentClassLoader(), GetEntryClassName())) {
entry_class_ = JNI_NewGlobalRef(env, entry_class);
}
}
}
void
MagiskLoader::OnNativeForkSystemServerPre(JNIEnv *env) {
void MagiskLoader::OnNativeForkSystemServerPre(JNIEnv *env) {
Service::instance()->InitService(env);
setAllowUnload(skip_);
}
}
void
MagiskLoader::OnNativeForkSystemServerPost(JNIEnv *env) {
void MagiskLoader::OnNativeForkSystemServerPost(JNIEnv *env) {
if (!skip_) {
auto *instance = Service::instance();
auto system_server_binder = instance->RequestSystemServerBinder(env);
@ -103,7 +101,8 @@ namespace lspd {
return;
}
auto application_binder = instance->RequestApplicationBinderFromSystemServer(env, system_server_binder);
auto application_binder =
instance->RequestApplicationBinderFromSystemServer(env, system_server_binder);
// Call application_binder directly if application binder is available,
// or we proxy the request from system server binder
@ -117,35 +116,29 @@ namespace lspd {
// always inject into system server
lsplant::InitInfo initInfo{
.inline_hooker = [](auto t, auto r) {
void* bk = nullptr;
return HookArtFunction(t, r, &bk) == 0 ? bk : nullptr;
.inline_hooker =
[](auto t, auto r) {
void *bk = nullptr;
return HookPLT(t, r, &bk) == 0 ? bk : nullptr;
},
.inline_unhooker = [](auto t) {
return UnhookArtFunction(t) == 0 ;
},
.art_symbol_resolver = [](auto symbol) {
return GetArt()->getSymbAddress(symbol);
},
.art_symbol_prefix_resolver = [](auto symbol) {
return GetArt()->getSymbPrefixFirstAddress(symbol);
},
};
.inline_unhooker = [](auto t) { return UnhookPLT(t) == 0; },
.art_symbol_resolver = [](auto symbol) { return GetArt()->getSymbAddress(symbol); },
.art_symbol_prefix_resolver =
[](auto symbol) { return GetArt()->getSymbPrefixFirstAddress(symbol); },
.is_plt_hook = true};
InitArtHooker(env, initInfo);
InitHooks(env);
SetupEntryClass(env);
FindAndCall(env, "forkCommon",
"(ZLjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V",
JNI_TRUE, JNI_NewStringUTF(env, "system"), nullptr, application_binder, is_parasitic_manager);
"(ZLjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V", JNI_TRUE,
JNI_NewStringUTF(env, "system"), nullptr, application_binder,
is_parasitic_manager);
GetArt(true);
}
}
}
void MagiskLoader::OnNativeForkAndSpecializePre(JNIEnv *env,
jint uid,
jintArray &gids,
jstring &nice_name,
jboolean is_child_zygote,
void MagiskLoader::OnNativeForkAndSpecializePre(JNIEnv *env, jint uid, jintArray &gids,
jstring &nice_name, jboolean is_child_zygote,
jstring app_data_dir) {
jboolean is_manager = JNI_FALSE;
if (uid == kAidInjected) {
@ -177,39 +170,34 @@ namespace lspd {
LOGD("skip injecting into {} because it's a child zygote", process_name.get());
}
if (!skip_ && ((app_id >= FIRST_ISOLATED_UID && app_id <= LAST_ISOLATED_UID) ||
(app_id >= FIRST_APP_ZYGOTE_ISOLATED_UID &&
app_id <= LAST_APP_ZYGOTE_ISOLATED_UID) ||
if (!skip_ &&
((app_id >= FIRST_ISOLATED_UID && app_id <= LAST_ISOLATED_UID) ||
(app_id >= FIRST_APP_ZYGOTE_ISOLATED_UID && app_id <= LAST_APP_ZYGOTE_ISOLATED_UID) ||
app_id == SHARED_RELRO_UID)) {
skip_ = true;
LOGI("skip injecting into {} because it's isolated", process_name.get());
}
setAllowUnload(skip_);
}
}
void
MagiskLoader::OnNativeForkAndSpecializePost(JNIEnv *env, jstring nice_name, jstring app_dir) {
void MagiskLoader::OnNativeForkAndSpecializePost(JNIEnv *env, jstring nice_name, jstring app_dir) {
const JUTFString process_name(env, nice_name);
auto *instance = Service::instance();
if (is_parasitic_manager) nice_name = JNI_NewStringUTF(env, "org.lsposed.manager").release();
auto binder = skip_ ? ScopedLocalRef<jobject>{env, nullptr}
: instance->RequestBinder(env, nice_name);
auto binder =
skip_ ? ScopedLocalRef<jobject>{env, nullptr} : instance->RequestBinder(env, nice_name);
if (binder) {
lsplant::InitInfo initInfo{
.inline_hooker = [](auto t, auto r) {
void* bk = nullptr;
return HookArtFunction(t, r, &bk) == 0 ? bk : nullptr;
.inline_hooker =
[](auto t, auto r) {
void *bk = nullptr;
return HookPLT(t, r, &bk) == 0 ? bk : nullptr;
},
.inline_unhooker = [](auto t) {
return UnhookArtFunction(t) == 0;
},
.art_symbol_resolver = [](auto symbol){
return GetArt()->getSymbAddress(symbol);
},
.art_symbol_prefix_resolver = [](auto symbol) {
return GetArt()->getSymbPrefixFirstAddress(symbol);
},
};
.inline_unhooker = [](auto t) { return UnhookPLT(t) == 0; },
.art_symbol_resolver = [](auto symbol) { return GetArt()->getSymbAddress(symbol); },
.art_symbol_prefix_resolver =
[](auto symbol) { return GetArt()->getSymbPrefixFirstAddress(symbol); },
.is_plt_hook = true};
auto [dex_fd, size] = instance->RequestLSPDex(env, binder);
auto obfs_map = instance->RequestObfuscationMap(env, binder);
ConfigBridge::GetInstance()->obfuscation_map(std::move(obfs_map));
@ -220,8 +208,8 @@ namespace lspd {
SetupEntryClass(env);
LOGD("Done prepare");
FindAndCall(env, "forkCommon",
"(ZLjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V",
JNI_FALSE, nice_name, app_dir, binder);
"(ZLjava/lang/String;Ljava/lang/String;Landroid/os/IBinder;)V", JNI_FALSE,
nice_name, app_dir, binder);
LOGD("injected xposed into {}", process_name.get());
setAllowUnload(false);
GetArt(true);
@ -232,11 +220,11 @@ namespace lspd {
LOGD("skipped {}", process_name.get());
setAllowUnload(true);
}
}
}
void MagiskLoader::setAllowUnload(bool unload) {
void MagiskLoader::setAllowUnload(bool unload) {
if (allowUnload) {
*allowUnload = unload ? 1 : 0;
}
}
}
} // namespace lspd