2024-04-28 01:24:16 +08:00
|
|
|
#include <jni.h>
|
2022-02-18 11:01:39 +08:00
|
|
|
#include <dobby.h>
|
|
|
|
#include <sys/mman.h>
|
2024-06-05 10:29:23 +08:00
|
|
|
#include <string_view>
|
2022-02-18 12:03:08 +08:00
|
|
|
#include "logging.h"
|
2022-02-18 11:01:39 +08:00
|
|
|
|
2024-04-28 01:24:16 +08:00
|
|
|
import lsplant;
|
2024-06-05 10:29:23 +08:00
|
|
|
import lsparself;
|
2024-04-28 01:24:16 +08:00
|
|
|
|
2022-02-18 11:01:39 +08:00
|
|
|
#define _uintval(p) reinterpret_cast<uintptr_t>(p)
|
|
|
|
#define _ptr(p) reinterpret_cast<void *>(p)
|
|
|
|
#define _align_up(x, n) (((x) + ((n) - 1)) & ~((n) - 1))
|
|
|
|
#define _align_down(x, n) ((x) & -(n))
|
|
|
|
#define _page_size 4096
|
|
|
|
#define _page_align(n) _align_up(static_cast<uintptr_t>(n), _page_size)
|
|
|
|
#define _ptr_align(x) _ptr(_align_down(reinterpret_cast<uintptr_t>(x), _page_size))
|
|
|
|
#define _make_rwx(p, n) ::mprotect(_ptr_align(p), \
|
|
|
|
_page_align(_uintval(p) + n) != _page_align(_uintval(p)) ? _page_align(n) + _page_size : _page_align(n), \
|
|
|
|
PROT_READ | PROT_WRITE | PROT_EXEC)
|
|
|
|
|
|
|
|
bool init_result;
|
|
|
|
|
|
|
|
void* InlineHooker(void* target, void* hooker) {
|
|
|
|
_make_rwx(target, _page_size);
|
|
|
|
void* origin_call;
|
|
|
|
if (DobbyHook(target, hooker, &origin_call) == RS_SUCCESS) {
|
|
|
|
return origin_call;
|
|
|
|
} else {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InlineUnhooker(void* func) {
|
|
|
|
return DobbyDestroy(func) == RT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
JNIEXPORT jboolean JNICALL
|
|
|
|
Java_org_lsposed_lsplant_LSPTest_initHooker(JNIEnv*, jclass) {
|
|
|
|
return init_result;
|
|
|
|
}
|
|
|
|
|
2022-02-18 15:35:53 +08:00
|
|
|
extern "C"
|
|
|
|
JNIEXPORT jobject JNICALL
|
2022-02-18 16:43:41 +08:00
|
|
|
Java_org_lsposed_lsplant_Hooker_doHook(JNIEnv* env, jobject thiz, jobject target, jobject callback) {
|
|
|
|
return lsplant::Hook(env, target, thiz, callback);
|
2022-02-18 15:35:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
JNIEXPORT jboolean JNICALL
|
2022-02-18 16:43:41 +08:00
|
|
|
Java_org_lsposed_lsplant_Hooker_doUnhook(JNIEnv* env, jobject, jobject target) {
|
|
|
|
return lsplant::UnHook(env, target);
|
2022-02-18 15:35:53 +08:00
|
|
|
}
|
|
|
|
|
2022-02-18 11:01:39 +08:00
|
|
|
JNIEXPORT jint JNICALL
|
|
|
|
JNI_OnLoad(JavaVM* vm, void* reserved) {
|
|
|
|
JNIEnv* env;
|
|
|
|
if (vm->GetEnv((void**) &env, JNI_VERSION_1_6) != JNI_OK) {
|
|
|
|
return JNI_ERR;
|
|
|
|
}
|
2024-02-17 17:09:10 +08:00
|
|
|
lsparself::Elf art("/libart.so");
|
2022-02-18 11:01:39 +08:00
|
|
|
lsplant::InitInfo initInfo{
|
|
|
|
.inline_hooker = InlineHooker,
|
|
|
|
.inline_unhooker = InlineUnhooker,
|
2022-02-18 12:03:08 +08:00
|
|
|
.art_symbol_resolver = [&art](std::string_view symbol) -> void* {
|
2022-04-27 10:58:11 +08:00
|
|
|
return art.getSymbAddress(symbol);
|
|
|
|
},
|
|
|
|
.art_symbol_prefix_resolver = [&art](auto symbol) {
|
2024-02-17 17:09:10 +08:00
|
|
|
return art.getSymbPrefixFirstAddress(symbol);
|
2022-04-27 10:58:11 +08:00
|
|
|
},
|
2022-02-18 11:01:39 +08:00
|
|
|
};
|
|
|
|
init_result = lsplant::Init(env, initInfo);
|
|
|
|
return JNI_VERSION_1_6;
|
|
|
|
}
|