Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
[submodule "external/dobby"]
path = external/dobby
url = https://github.com/chiteroman/Dobby.git
[submodule "external/lsplt"]
path = external/lsplt
url = https://github.com/LSPosed/LSPlt.git
[submodule "external/fmt"]
path = external/fmt
url = https://github.com/fmtlib/fmt.git
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ You can contribute translation [here](https://crowdin.com/project/lsposed_jingma
- [Magisk](https://github.com/topjohnwu/Magisk/): makes all these possible
- [Riru](https://github.com/RikkaApps/Riru): provides a way to inject code into zygote process
- [XposedBridge](https://github.com/rovo89/XposedBridge): the OG Xposed framework APIs
- [Dobby](https://github.com/chiteroman/Dobby): used for inline hooking
- [LSPlt](https://github.com/LSPosed/LSPlt): used for `libart` inline hooking
- [Dobby](https://github.com/chiteroman/Dobby): used for `native_api` inline hooking
- [LSPlant](https://github.com/JingMatrix/LSPlant): the core ART hooking framework
- [EdXposed](https://github.com/ElderDrivers/EdXposed): fork source
- ~[SandHook](https://github.com/ganyao114/SandHook/): ART hooking framework for SandHook variant~
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ add_library(${PROJECT_NAME} STATIC ${SRC_LIST})
target_include_directories(${PROJECT_NAME} PUBLIC include)
target_include_directories(${PROJECT_NAME} PRIVATE src)

target_link_libraries(${PROJECT_NAME} PUBLIC dobby_static lsplant_static log fmt-header-only)
target_link_libraries(${PROJECT_NAME} PUBLIC dobby_static lsplt_static lsplant_static log fmt-header-only)
target_link_libraries(${PROJECT_NAME} PRIVATE dex_builder_static)
104 changes: 63 additions & 41 deletions core/src/main/jni/include/native_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,30 @@
*/

#include <dlfcn.h>
#include "dobby.h"
#include <sys/mman.h>

#include "elf_util.h"
#include "lsplt.hpp"
#include "symbol_cache.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value"
#pragma once

#include <context.h>
#include "macros.h"
#include "utils/jni_helper.hpp"
#include "logging.h"
#include "config.h"

#include <cassert>

/* #include "../src/native_api.h" */
#include "config.h"
#include "config_bridge.h"
#include "logging.h"
#include "utils/jni_helper.hpp"

namespace lspd {

[[gnu::always_inline]]
inline bool RegisterNativeMethodsInternal(JNIEnv *env,
std::string_view class_name,
const JNINativeMethod *methods,
jint method_count) {

inline bool RegisterNativeMethodsInternal(JNIEnv *env, std::string_view class_name,
const JNINativeMethod *methods, jint method_count) {
auto clazz = Context::GetInstance()->FindClassFromCurrentLoader(env, class_name.data());
if (clazz.get() == nullptr) {
LOGF("Couldn't find class: {}", class_name.data());
Expand All @@ -50,51 +52,71 @@ inline bool RegisterNativeMethodsInternal(JNIEnv *env,
}

#if defined(__cplusplus)
#define _NATIVEHELPER_JNI_MACRO_CAST(to) \
reinterpret_cast<to>
#define _NATIVEHELPER_JNI_MACRO_CAST(to) reinterpret_cast<to>
#else
#define _NATIVEHELPER_JNI_MACRO_CAST(to) \
(to)
#define _NATIVEHELPER_JNI_MACRO_CAST(to) (to)
#endif

#ifndef LSP_NATIVE_METHOD
#define LSP_NATIVE_METHOD(className, functionName, signature) \
{ #functionName, \
signature, \
_NATIVEHELPER_JNI_MACRO_CAST(void*) (Java_org_lsposed_lspd_nativebridge_## className ## _ ## functionName) \
}
#define LSP_NATIVE_METHOD(className, functionName, signature) \
{#functionName, signature, \
_NATIVEHELPER_JNI_MACRO_CAST(void *)( \
Java_org_lsposed_lspd_nativebridge_##className##_##functionName)}
#endif

#define JNI_START [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz
#define JNI_START [[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass clazz

#ifndef LSP_DEF_NATIVE_METHOD
#define LSP_DEF_NATIVE_METHOD(ret, className, functionName, ...) \
extern "C" ret Java_org_lsposed_lspd_nativebridge_## className ## _ ## functionName (JNI_START, ## __VA_ARGS__)
#define LSP_DEF_NATIVE_METHOD(ret, className, functionName, ...) \
extern "C" ret Java_org_lsposed_lspd_nativebridge_##className##_##functionName(JNI_START, \
##__VA_ARGS__)
#endif

#define REGISTER_LSP_NATIVE_METHODS(class_name) \
RegisterNativeMethodsInternal(env, GetNativeBridgeSignature() + #class_name, gMethods, arraysize(gMethods))
#define REGISTER_LSP_NATIVE_METHODS(class_name) \
RegisterNativeMethodsInternal(env, GetNativeBridgeSignature() + #class_name, gMethods, \
arraysize(gMethods))

static dev_t dev = 0;
static ino_t inode = 0;
static std::vector<std::pair<const char *, void **>> plt_hook_saved = {};

inline int HookFunction(void *original, void *replace, void **backup) {
if constexpr (isDebug) {
Dl_info info;
if (dladdr(original, &info))
LOGD("Hooking {} ({}) from {} ({})",
info.dli_sname ? info.dli_sname : "(unknown symbol)", info.dli_saddr,
info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase);
inline int HookArtFunction(void *original, void *callback, void **backup, bool save = true) {
const char *symbol = reinterpret_cast<const char *>(original);
if (dev == 0 || inode == 0) {
auto libart_path = GetArt()->name();
for (auto map : lsplt::MapInfo::Scan()) {
if (map.path == libart_path) {
inode = map.inode;
dev = map.dev;
break;
}
}
}
return DobbyHook(original, reinterpret_cast<dobby_dummy_func_t>(replace), reinterpret_cast<dobby_dummy_func_t *>(backup));

auto result = lsplt::RegisterHook(dev, inode, symbol, callback, backup) && lsplt::CommitHook();
if (result && *backup != nullptr) {
if (save) plt_hook_saved.emplace_back(symbol, backup);
return 0;
/* } else if (auto addr = GetArt()->getSymbAddress(symbol); addr) { */
/* HookFunction(addr, callback, backup); */
} else if (*backup == nullptr && isDebug) {
LOGW("Failed to {} Art symbol {}", save ? "hook" : "unhook", symbol);
}
return 1;
}

inline int UnhookFunction(void *original) {
if constexpr (isDebug) {
Dl_info info;
if (dladdr(original, &info))
LOGD("Unhooking {} ({}) from {} ({})",
info.dli_sname ? info.dli_sname : "(unknown symbol)", info.dli_saddr,
info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase);
inline int UnhookArtFunction(void *original) {
std::string_view func_name = reinterpret_cast<const char *>(original);
auto hook_iter = std::find_if(plt_hook_saved.begin(), plt_hook_saved.end(),
[func_name](auto record) { return record.first == func_name; });

void *stub = nullptr;
if (hook_iter != plt_hook_saved.end() &&
HookArtFunction(original, *(hook_iter->second), &stub, false)) {
plt_hook_saved.erase(hook_iter);
return 0;
}
return DobbyDestroy(original);
return 1;
}

inline std::string GetNativeBridgeSignature() {
Expand All @@ -103,6 +125,6 @@ inline std::string GetNativeBridgeSignature() {
return signature;
}

} // namespace lspd
} // namespace lspd

#pragma clang diagnostic pop
4 changes: 1 addition & 3 deletions core/src/main/jni/src/native_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@
#include "logging.h"
#include "utils/hook_helper.hpp"
#include <sys/mman.h>
#include <dobby.h>
#include <list>
#include <dlfcn.h>
#include "native_util.h"
#include "elf_util.h"
#include "symbol_cache.h"

Expand Down Expand Up @@ -135,6 +133,6 @@ namespace lspd {
};

bool InstallNativeAPI(const lsplant::HookHandler & handler) {
return handler.hook(do_dlopen);
return handler.hook(do_dlopen, true);
}
}
27 changes: 27 additions & 0 deletions core/src/main/jni/src/native_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@
#define LSPOSED_NATIVE_API_H

#include <cstdint>
#include <dlfcn.h>
#include <string>
#include <dobby.h>

#include "config.h"
#include "utils/hook_helper.hpp"

typedef int (*HookFunType)(void *func, void *replace, void **backup);
Expand All @@ -48,6 +51,30 @@ namespace lspd {
bool InstallNativeAPI(const lsplant::HookHandler& handler);

void RegisterNativeLib(const std::string &library_name);

inline int HookFunction(void *original, void *replace, void **backup) {
if constexpr (isDebug) {
Dl_info info;
if (dladdr(original, &info))
LOGD("Dobby hooking {} ({}) from {} ({})",
info.dli_sname ? info.dli_sname : "(unknown symbol)",
info.dli_saddr ? info.dli_saddr : original,
info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase);
}
return DobbyHook(original, reinterpret_cast<dobby_dummy_func_t>(replace), reinterpret_cast<dobby_dummy_func_t *>(backup));
}

inline int UnhookFunction(void *original) {
if constexpr (isDebug) {
Dl_info info;
if (dladdr(original, &info))
LOGD("Dobby unhooking {} ({}) from {} ({})",
info.dli_sname ? info.dli_sname : "(unknown symbol)",
info.dli_saddr ? info.dli_saddr : original,
info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase);
}
return DobbyDestroy(original);
}
}

#endif //LSPOSED_NATIVE_API_H
1 change: 0 additions & 1 deletion core/src/main/jni/src/symbol_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#include "symbol_cache.h"
#include "elf_util.h"
#include <dobby.h>
#include "macros.h"
#include "config.h"
#include <vector>
Expand Down
2 changes: 1 addition & 1 deletion daemon/src/main/jni/logcat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ void Logcat::ProcessBuffer(struct log_msg *buf) {
shortcut = true;
}
if (verbose_ && (shortcut || buf->id() == log_id::LOG_ID_CRASH ||
entry.pid == my_pid_ || tag == "Magisk"sv || tag == "Dobby"sv ||
entry.pid == my_pid_ || tag == "Magisk"sv || tag == "LSPlt"sv ||
tag.starts_with("Riru"sv) || tag.starts_with("zygisk"sv) ||
tag == "LSPlant"sv || tag.starts_with("LSPosed"sv))) [[unlikely]] {
verbose_print_count_ += PrintLogLine(entry, verbose_file_.get());
Expand Down
4 changes: 3 additions & 1 deletion external/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ target_include_directories(cxx PRIVATE ${LIBCXX_INCLUDES} ${LIBCXXABI_INCLUDES})
link_libraries(cxx)

OPTION(LSPLANT_BUILD_SHARED OFF)
add_subdirectory(lsplant/lsplant/src/main/jni)
OPTION(LSPLT_BUILD_SHARED OFF)
add_subdirectory(dobby)
add_subdirectory(fmt)
add_subdirectory(lsplant/lsplant/src/main/jni)
add_subdirectory(lsplt/lsplt/src/main/jni)
target_compile_definitions(fmt-header-only INTERFACE FMT_STATIC_THOUSANDS_SEPARATOR=1 FMT_USE_FLOAT=0 FMT_USE_DOUBLE=0 FMT_USE_LONG_DOUBLE=0)
2 changes: 1 addition & 1 deletion external/lsplant
1 change: 1 addition & 0 deletions external/lsplt
Submodule lsplt added at cef80a
8 changes: 4 additions & 4 deletions magisk-loader/src/main/jni/src/magisk_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ namespace lspd {
lsplant::InitInfo initInfo{
.inline_hooker = [](auto t, auto r) {
void* bk = nullptr;
return HookFunction(t, r, &bk) == 0 ? bk : nullptr;
return HookArtFunction(t, r, &bk) == 0 ? bk : nullptr;
},
.inline_unhooker = [](auto t) {
return UnhookFunction(t) == 0 ;
return UnhookArtFunction(t) == 0 ;
},
.art_symbol_resolver = [](auto symbol) {
return GetArt()->getSymbAddress(symbol);
Expand Down Expand Up @@ -198,10 +198,10 @@ namespace lspd {
lsplant::InitInfo initInfo{
.inline_hooker = [](auto t, auto r) {
void* bk = nullptr;
return HookFunction(t, r, &bk) == 0 ? bk : nullptr;
return HookArtFunction(t, r, &bk) == 0 ? bk : nullptr;
},
.inline_unhooker = [](auto t) {
return UnhookFunction(t) == 0;
return UnhookArtFunction(t) == 0;
},
.art_symbol_resolver = [](auto symbol){
return GetArt()->getSymbAddress(symbol);
Expand Down
1 change: 0 additions & 1 deletion magisk-loader/src/main/jni/src/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
// Created by loves on 2/7/2021.
//

#include <dobby.h>
#include <thread>
#include <atomic>
#include <android/sharedmem.h>
Expand Down