mirror of
https://github.com/LSPosed/LSPlant.git
synced 2025-05-04 20:42:02 +08:00
Update interface to v2 to support prefix resolver
This commit is contained in:
parent
9c63dcecf3
commit
050348fd08
@ -250,7 +250,7 @@ public:
|
||||
if (sdk_int < __ANDROID_API_Q__) kAccFastInterpreterToInterpreterInvoke = 0;
|
||||
|
||||
if (!RETRIEVE_FUNC_SYMBOL(GetMethodShorty,
|
||||
"_ZN3artL15GetMethodShortyEP7_JNIEnvP10_jmethodID") &&
|
||||
"_ZN3artL15GetMethodShortyEP7_JNIEnvP10_jmethodID", true) &&
|
||||
!RETRIEVE_FUNC_SYMBOL(GetMethodShorty,
|
||||
"_ZN3art15GetMethodShortyEP7_JNIEnvP10_jmethodID")) {
|
||||
LOGE("Failed to find GetMethodShorty");
|
||||
|
@ -103,9 +103,9 @@ public:
|
||||
static bool Init(JNIEnv* env, const HookHandler& handler) {
|
||||
auto sdk_int = GetAndroidApiLevel();
|
||||
if (sdk_int >= __ANDROID_API_P__) [[likely]] {
|
||||
if (!RETRIEVE_FUNC_SYMBOL(
|
||||
DexFile_setTrusted,
|
||||
"_ZN3artL18DexFile_setTrustedEP7_JNIEnvP7_jclassP8_jobject")) {
|
||||
if (!RETRIEVE_FUNC_SYMBOL(DexFile_setTrusted,
|
||||
"_ZN3artL18DexFile_setTrustedEP7_JNIEnvP7_jclassP8_jobject",
|
||||
true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
/// \namespace namespace of LSPlant
|
||||
namespace lsplant {
|
||||
|
||||
inline namespace v1 {
|
||||
inline namespace v2 {
|
||||
/// \struct InitInfo
|
||||
/// \brief Information and configuration that are needed to call #Init()
|
||||
struct InitInfo {
|
||||
@ -31,6 +31,14 @@ struct InitInfo {
|
||||
/// \note It should be able to resolve symbols from both .dynsym and .symtab.
|
||||
using ArtSymbolResolver = std::function<void *(std::string_view symbol_name)>;
|
||||
|
||||
/// \brief Type of prefix symbol resolver to \p libart.so.
|
||||
/// In \ref std::function form so that user can use lambda expression with capture list.<br>
|
||||
/// \p symbol_prefix is the symbol prefix that needs to retrieve.<br>
|
||||
/// \p return is the first absolute address in the memory that points to the target symbol.
|
||||
/// It should be null if the symbol cannot be found. <br>
|
||||
/// \note It should be able to resolve symbols from both .dynsym and .symtab.
|
||||
using ArtSymbolPrefixResolver = std::function<void *(std::string_view symbol_prefix)>;
|
||||
|
||||
/// \brief The inline hooker function. Must not be null.
|
||||
InlineHookFunType inline_hooker;
|
||||
/// \brief The inline unhooker function. Must not be null.
|
||||
@ -38,6 +46,9 @@ struct InitInfo {
|
||||
/// \brief The symbol resolver to \p libart.so. Must not be null.
|
||||
ArtSymbolResolver art_symbol_resolver;
|
||||
|
||||
/// \brief The symbol prefix resolver to \p libart.so. May be null.
|
||||
ArtSymbolPrefixResolver art_symbol_prefix_resolver;
|
||||
|
||||
/// \brief The generated class name. Must not be empty. It contains a field and a method
|
||||
/// and they could be set by \p generated_field_name and \p generated_method_name respectively.
|
||||
std::string_view generated_class_name = "LSPHooker_";
|
||||
|
@ -77,8 +77,13 @@ inline constexpr auto operator+(const tstring<as...> &, const std::string &b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
inline void *Dlsym(const HookHandler &handle, const char *name) {
|
||||
return handle.art_symbol_resolver(name);
|
||||
inline void *Dlsym(const HookHandler &handle, const char *name, bool match_prefix = false) {
|
||||
if (auto match = handle.art_symbol_resolver(name); match) {
|
||||
return match;
|
||||
} else if (match_prefix && handle.art_symbol_prefix_resolver) {
|
||||
return handle.art_symbol_prefix_resolver(name);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename Class, typename Return, typename T, typename... Args>
|
||||
|
@ -527,7 +527,7 @@ bool DoUnHook(ArtMethod *target, ArtMethod *backup) {
|
||||
|
||||
} // namespace
|
||||
|
||||
inline namespace v1 {
|
||||
inline namespace v2 {
|
||||
|
||||
using ::lsplant::IsHooked;
|
||||
|
||||
@ -712,7 +712,7 @@ using ::lsplant::IsHooked;
|
||||
if (!cookie) return false;
|
||||
return DexFile::SetTrusted(env, cookie);
|
||||
}
|
||||
} // namespace v1
|
||||
} // namespace v2
|
||||
|
||||
} // namespace lsplant
|
||||
|
||||
|
@ -5,8 +5,8 @@ pluginManagement {
|
||||
mavenCentral()
|
||||
}
|
||||
plugins {
|
||||
id("com.android.application") version "7.1.2"
|
||||
id("com.android.library") version "7.1.2"
|
||||
id("com.android.application") version "7.1.3"
|
||||
id("com.android.library") version "7.1.3"
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
|
@ -166,9 +166,8 @@ ElfW(Addr) ElfImg::GnuLookup(std::string_view name, uint32_t hash) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ElfW(Addr) ElfImg::LinearLookup(std::string_view name) const {
|
||||
void ElfImg::MayInitLinearMap() const {
|
||||
if (symtabs_.empty()) {
|
||||
symtabs_.reserve(symtab_count);
|
||||
if (symtab_start != nullptr && symstr_offset_for_symtab != 0) {
|
||||
for (ElfW(Off) i = 0; i < symtab_count; i++) {
|
||||
unsigned int st_type = ELF_ST_TYPE(symtab_start[i].st_info);
|
||||
@ -180,6 +179,11 @@ ElfW(Addr) ElfImg::LinearLookup(std::string_view name) const {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ElfW(Addr) ElfImg::LinearLookup(std::string_view name) const {
|
||||
MayInitLinearMap();
|
||||
if (auto i = symtabs_.find(name); i != symtabs_.end()) {
|
||||
return i->second->st_value;
|
||||
} else {
|
||||
@ -187,6 +191,16 @@ ElfW(Addr) ElfImg::LinearLookup(std::string_view name) const {
|
||||
}
|
||||
}
|
||||
|
||||
ElfW(Addr) ElfImg::PrefixLookupFirst(std::string_view prefix) const {
|
||||
MayInitLinearMap();
|
||||
if (auto i = symtabs_.lower_bound(prefix); i != symtabs_.end() && i->first.starts_with(prefix)) {
|
||||
LOGD("found prefix %s of %s %p in %s in symtab by linear lookup", prefix.data(),
|
||||
i->first.data(), reinterpret_cast<void *>(i->second->st_value), elf.data());
|
||||
return i->second->st_value;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ElfImg::~ElfImg() {
|
||||
//open elf file local
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define SANDHOOK_ELF_UTIL_H
|
||||
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <linux/elf.h>
|
||||
#include <sys/types.h>
|
||||
#include <string>
|
||||
@ -35,23 +35,26 @@ namespace SandHook {
|
||||
|
||||
ElfImg(std::string_view elf);
|
||||
|
||||
constexpr ElfW(Addr) getSymbOffset(std::string_view name) const {
|
||||
return getSymbOffset(name, GnuHash(name), ElfHash(name));
|
||||
}
|
||||
|
||||
constexpr ElfW(Addr) getSymbAddress(std::string_view name) const {
|
||||
ElfW(Addr) offset = getSymbOffset(name);
|
||||
template<typename T = void*>
|
||||
requires(std::is_pointer_v<T>)
|
||||
constexpr const T getSymbAddress(std::string_view name) const {
|
||||
auto offset = getSymbOffset(name, GnuHash(name), ElfHash(name));
|
||||
if (offset > 0 && base != nullptr) {
|
||||
return static_cast<ElfW(Addr)>((uintptr_t) base + offset - bias);
|
||||
return reinterpret_cast<T>(static_cast<ElfW(Addr)>((uintptr_t) base + offset - bias));
|
||||
} else {
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename T = void*>
|
||||
requires(std::is_pointer_v<T>)
|
||||
constexpr T getSymbAddress(std::string_view name) const {
|
||||
return reinterpret_cast<T>(getSymbAddress(name));
|
||||
constexpr const T getSymbPrefixFirstOffset(std::string_view prefix) const {
|
||||
auto offset = PrefixLookupFirst(prefix);
|
||||
if (offset > 0 && base != nullptr) {
|
||||
return reinterpret_cast<T>(static_cast<ElfW(Addr)>((uintptr_t) base + offset - bias));
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
@ -73,12 +76,16 @@ namespace SandHook {
|
||||
|
||||
ElfW(Addr) LinearLookup(std::string_view name) const;
|
||||
|
||||
ElfW(Addr) PrefixLookupFirst(std::string_view prefix) const;
|
||||
|
||||
constexpr static uint32_t ElfHash(std::string_view name);
|
||||
|
||||
constexpr static uint32_t GnuHash(std::string_view name);
|
||||
|
||||
bool findModuleBase();
|
||||
|
||||
void MayInitLinearMap() const;
|
||||
|
||||
std::string elf;
|
||||
void *base = nullptr;
|
||||
char *buffer = nullptr;
|
||||
@ -111,7 +118,7 @@ namespace SandHook {
|
||||
uint32_t *gnu_bucket_;
|
||||
uint32_t *gnu_chain_;
|
||||
|
||||
mutable std::unordered_map<std::string_view, ElfW(Sym) *> symtabs_;
|
||||
mutable std::map<std::string_view, ElfW(Sym) *> symtabs_;
|
||||
};
|
||||
|
||||
constexpr uint32_t ElfImg::ElfHash(std::string_view name) {
|
||||
|
@ -60,9 +60,11 @@ JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
.inline_hooker = InlineHooker,
|
||||
.inline_unhooker = InlineUnhooker,
|
||||
.art_symbol_resolver = [&art](std::string_view symbol) -> void* {
|
||||
auto* out = reinterpret_cast<void*>(art.getSymbAddress(symbol));
|
||||
return out;
|
||||
}
|
||||
return art.getSymbAddress(symbol);
|
||||
},
|
||||
.art_symbol_prefix_resolver = [&art](auto symbol) {
|
||||
return art.getSymbPrefixFirstOffset(symbol);
|
||||
},
|
||||
};
|
||||
init_result = lsplant::Init(env, initInfo);
|
||||
return JNI_VERSION_1_6;
|
||||
|
Loading…
x
Reference in New Issue
Block a user