Adapt LSPlant upstream update

1. Remove the usage of `tstring` since it is removed in the upstream.
2. In commit aa98da5, the return value of android::ResStringPool::setup
was mistaken.
3. We should also set a proper symbol resolver for native_api.
This commit is contained in:
JingMatrix 2024-08-04 13:58:50 +02:00
parent d4e00eac40
commit c3782c9b3c
5 changed files with 29 additions and 46 deletions

View File

@ -142,31 +142,19 @@ namespace android {
using stringAtRet = expected<StringPiece16, NullOrIOError>;
CREATE_MEM_FUNC_SYMBOL_ENTRY(stringAtRet, stringAtS, void *thiz, size_t idx) {
if (stringAtSSym) {
return stringAtSSym(thiz, idx);
}
return {.var_ = unexpected<NullOrIOError>{.val_ = std::nullopt}};
inline static lsplant::MemberFunction<{"_ZNK7android13ResStringPool8stringAtEjPj",
"_ZNK7android13ResStringPool8stringAtEmPm"}, ResStringPool, stringAtRet (size_t)> stringAtS_;
};
CREATE_MEM_FUNC_SYMBOL_ENTRY(const char16_t*, stringAt, void *thiz, size_t idx,
size_t *u16len) {
if (stringAtSym) {
return stringAtSym(thiz, idx, u16len);
} else {
*u16len = 0u;
return nullptr;
}
};
inline static lsplant::MemberFunction<{"_ZNK7android13ResStringPool8stringAtEj",
"_ZNK7android13ResStringPool8stringAtEm"}, ResStringPool, const char16_t* (size_t, size_t *)> stringAt_;
StringPiece16 stringAt(size_t idx) const {
if (stringAtSym) {
if (stringAt_) {
size_t len;
const char16_t *str = stringAt(const_cast<ResStringPool *>(this), idx, &len);
const char16_t *str = stringAt_(const_cast<ResStringPool *>(this), idx, &len);
return {str, len};
} else if (stringAtSSym) {
auto str = stringAtS(const_cast<ResStringPool *>(this), idx);
} else if (stringAtS_) {
auto str = stringAtS_(const_cast<ResStringPool *>(this), idx);
if (str.has_value()) {
return {str->data_, str->length_};
}
@ -175,9 +163,7 @@ namespace android {
}
static bool setup(const lsplant::HookHandler &handler) {
RETRIEVE_MEM_FUNC_SYMBOL(stringAt, LP_SELECT("_ZNK7android13ResStringPool8stringAtEjPj", "_ZNK7android13ResStringPool8stringAtEmPm"));
RETRIEVE_MEM_FUNC_SYMBOL(stringAtS, LP_SELECT("_ZNK7android13ResStringPool8stringAtEj", "_ZNK7android13ResStringPool8stringAtEm"));
return !stringAtSym || !stringAtSSym;
return handler.dlsym(stringAt_) || handler.dlsym(stringAtS_);
}
};

View File

@ -78,10 +78,10 @@ inline bool RegisterNativeMethodsInternal(JNIEnv *env, std::string_view class_na
static dev_t dev = 0;
static ino_t inode = 0;
static std::vector<std::pair<std::string_view, void **>> plt_hook_saved = {};
static std::vector<std::pair<const char *, void **>> plt_hook_saved = {};
inline int HookArtFunction(void *art_symbol, void *callback, void **backup, bool save = true) {
auto symbol = *reinterpret_cast<std::string_view *>(art_symbol);
auto symbol = reinterpret_cast<const char *>(art_symbol);
if (GetArt()->isStripped()) {
if (dev == 0 || inode == 0) {
@ -105,7 +105,7 @@ 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 && info.dli_sname == symbol)
if (dladdr(addr, &info) && info.dli_sname != nullptr && strcmp(info.dli_sname, symbol) == 0)
HookFunction(addr, callback, backup);
} else if (*backup == nullptr && isDebug) {
LOGW("Failed to {} Art symbol {}", save ? "hook" : "unhook", symbol);
@ -119,8 +119,9 @@ inline int UnhookArtFunction(void *original) {
if (!dladdr(original, &info) || info.dli_sname != nullptr) return 1;
if (!GetArt()->isStripped()) return UnhookFunction(original);
auto hook_iter = std::find_if(plt_hook_saved.begin(), plt_hook_saved.end(),
[info](auto record) { return record.first == info.dli_sname; });
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)) {

View File

@ -75,7 +75,7 @@ namespace lspd {
"_ZNK7android12ResXMLParser18getAttributeNameIDEm")))) {
return false;
}
return android::ResStringPool::setup(HookHandler{
return android::ResStringPool::setup(lsplant::InitInfo {
.art_symbol_resolver = [&](auto s) {
return fw.template getSymbAddress(s);
}

View File

@ -29,6 +29,7 @@
#include <list>
#include <dlfcn.h>
#include "elf_util.h"
#include "symbol_cache.h"
/*
@ -67,11 +68,14 @@ namespace lspd {
void RegisterNativeLib(const std::string &library_name) {
static bool initialized = []() {
return InstallNativeAPI({
return InstallNativeAPI(lsplant::InitInfo {
.inline_hooker = [](auto t, auto r) {
void* bk = nullptr;
return HookFunction(t, r, &bk) == 0 ? bk : nullptr;
},
.art_symbol_resolver = [](auto symbol){
return GetLinker()->getSymbAddress(symbol);
},
});
}();
if (!initialized) [[unlikely]] return;
@ -87,11 +91,10 @@ namespace lspd {
return false;
}
CREATE_HOOK_STUB_ENTRY(
"__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv",
void*, do_dlopen, (const char* name, int flags, const void* extinfo,
const void* caller_addr), {
auto *handle = backup(name, flags, extinfo, caller_addr);
inline static lsplant::Hooker<"__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv",
void*(const char*, int, const void*, const void*)>
do_dlopen = +[](const char* name, int flags, const void* extinfo, const void* caller_addr) {
auto *handle = do_dlopen(name, flags, extinfo, caller_addr);
std::string ns;
if (name) {
ns = std::string(name);
@ -100,7 +103,7 @@ namespace lspd {
}
LOGD("native_api: do_dlopen({})", ns);
if (handle == nullptr) {
return nullptr;
return handle;
}
for (std::string_view module_lib: moduleNativeLibs) {
// the so is a module so
@ -127,16 +130,9 @@ namespace lspd {
callback(name, handle);
}
return handle;
});
};
bool InstallNativeAPI(const lsplant::HookHandler & handler) {
auto *do_dlopen_sym = SandHook::ElfImg("/linker").getSymbAddress(
"__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv");
LOGD("InstallNativeAPI: {}", do_dlopen_sym);
if (do_dlopen_sym) [[likely]] {
HookSymNoHandle(handler, do_dlopen_sym, do_dlopen);
return true;
}
return false;
return handler.hook(do_dlopen);
}
}

2
external/lsplant vendored

@ -1 +1 @@
Subproject commit 2009a1922c63e5838eaeff79eacf821d4f6b536f
Subproject commit 2a18d73b4d2150ca02b30938c0e82eb9aab1619e