Update elf util & lsplant to support A13B1 arm (#1894)

This commit is contained in:
LoveSy 2022-04-27 11:29:32 +08:00 committed by GitHub
parent 177c2cd0c4
commit 7d5778a01c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 49 additions and 23 deletions

View File

@ -10,7 +10,7 @@ A Riru / Zygisk module trying to provide an ART hooking framework which delivers
## Supported Versions ## Supported Versions
Android 8.1 ~ 13 DP2 Android 8.1 ~ 13 Beta 1
## Install ## Install

View File

@ -21,7 +21,7 @@
#define SANDHOOK_ELF_UTIL_H #define SANDHOOK_ELF_UTIL_H
#include <string_view> #include <string_view>
#include <unordered_map> #include <map>
#include <linux/elf.h> #include <linux/elf.h>
#include <sys/types.h> #include <sys/types.h>
#include <link.h> #include <link.h>
@ -35,23 +35,26 @@ namespace SandHook {
ElfImg(std::string_view elf); ElfImg(std::string_view elf);
constexpr ElfW(Addr) getSymbOffset(std::string_view name) const { template<typename T = void*>
return getSymbOffset(name, GnuHash(name), ElfHash(name)); requires(std::is_pointer_v<T>)
} constexpr const T getSymbAddress(std::string_view name) const {
auto offset = getSymbOffset(name, GnuHash(name), ElfHash(name));
constexpr ElfW(Addr) getSymbAddress(std::string_view name) const {
ElfW(Addr) offset = getSymbOffset(name);
if (offset > 0 && base != nullptr) { 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 { } else {
return 0; return nullptr;
} }
} }
template<typename T> template<typename T = void*>
requires(std::is_pointer_v<T>) requires(std::is_pointer_v<T>)
constexpr T getSymbAddress(std::string_view name) const { constexpr const T getSymbPrefixFirstOffset(std::string_view prefix) const {
return reinterpret_cast<T>(getSymbAddress(name)); 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 { bool isValid() const {
@ -73,12 +76,16 @@ namespace SandHook {
ElfW(Addr) LinearLookup(std::string_view name) const; 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 ElfHash(std::string_view name);
constexpr static uint32_t GnuHash(std::string_view name); constexpr static uint32_t GnuHash(std::string_view name);
bool findModuleBase(); bool findModuleBase();
void MayInitLinearMap() const;
std::string elf; std::string elf;
void *base = nullptr; void *base = nullptr;
char *buffer = nullptr; char *buffer = nullptr;
@ -111,7 +118,7 @@ namespace SandHook {
uint32_t *gnu_bucket_; uint32_t *gnu_bucket_;
uint32_t *gnu_chain_; 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) { constexpr uint32_t ElfImg::ElfHash(std::string_view name) {

View File

@ -166,9 +166,8 @@ ElfW(Addr) ElfImg::GnuLookup(std::string_view name, uint32_t hash) const {
return 0; return 0;
} }
ElfW(Addr) ElfImg::LinearLookup(std::string_view name) const { void ElfImg::MayInitLinearMap() const {
if (symtabs_.empty()) { if (symtabs_.empty()) {
symtabs_.reserve(symtab_count);
if (symtab_start != nullptr && symstr_offset_for_symtab != 0) { if (symtab_start != nullptr && symstr_offset_for_symtab != 0) {
for (ElfW(Off) i = 0; i < symtab_count; i++) { for (ElfW(Off) i = 0; i < symtab_count; i++) {
unsigned int st_type = ELF_ST_TYPE(symtab_start[i].st_info); unsigned int st_type = ELF_ST_TYPE(symtab_start[i].st_info);
@ -180,6 +179,10 @@ 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()) { if (auto i = symtabs_.find(name); i != symtabs_.end()) {
return i->second->st_value; return i->second->st_value;
} else { } else {
@ -187,6 +190,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 {} of {} {:#x} in {} in symtab by linear lookup", prefix, i->first, i->second->st_value, elf);
return i->second->st_value;
} else {
return 0;
}
}
ElfImg::~ElfImg() { ElfImg::~ElfImg() {
//open elf file local //open elf file local

View File

@ -77,7 +77,7 @@ namespace lspd {
} }
return android::ResStringPool::setup(HookHandler{ return android::ResStringPool::setup(HookHandler{
.art_symbol_resolver = [&](auto s) { .art_symbol_resolver = [&](auto s) {
return fw.template getSymbAddress<void*>(s); return fw.template getSymbAddress(s);
} }
}); });
} }

View File

@ -47,7 +47,7 @@ namespace lspd {
bool FindLibArt() { bool FindLibArt() {
auto &art = GetArt(); auto &art = GetArt();
if (!art->isValid()) return false; if (!art->isValid()) return false;
return symbol_cache->setTableOverride = art->getSymbAddress<void *>( return symbol_cache->setTableOverride = art->getSymbAddress(
"_ZN3art9JNIEnvExt16SetTableOverrideEPK18JNINativeInterface"); "_ZN3art9JNIEnvExt16SetTableOverrideEPK18JNINativeInterface");
} }
@ -60,7 +60,7 @@ namespace lspd {
return; return;
} }
auto ok = FindLibArt(); auto ok = FindLibArt();
symbol_cache->do_dlopen = SandHook::ElfImg("/linker").getSymbAddress<void *>( symbol_cache->do_dlopen = SandHook::ElfImg("/linker").getSymbAddress(
"__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv"); "__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv");
if (!ok) [[unlikely]] { if (!ok) [[unlikely]] {
GetArt(true); GetArt(true);

2
external/lsplant vendored

@ -1 +1 @@
Subproject commit 9c63dcecf38f0ae34c4a67c4f1fb3bd8bd377f0f Subproject commit 050348fd08325321c7a67ce6355ddcd51bcace57

View File

@ -3,5 +3,5 @@ name=${api} - LSPosed
version=${versionName} (${versionCode}) version=${versionName} (${versionCode})
versionCode=${versionCode} versionCode=${versionCode}
author=${authorList} author=${authorList}
description=Another enhanced implementation of Xposed Framework. Supports Android 8.1 ~ 13 DP2. ${requirement}. description=Another enhanced implementation of Xposed Framework. Supports Android 8.1 ~ 13 Beta 1. ${requirement}.
updateJson=${updateJson} updateJson=${updateJson}

View File

@ -128,7 +128,10 @@ namespace lspd {
return UnhookFunction(t) == RT_SUCCESS ; return UnhookFunction(t) == RT_SUCCESS ;
}, },
.art_symbol_resolver = [](auto symbol) { .art_symbol_resolver = [](auto symbol) {
return GetArt()->getSymbAddress<void*>(symbol); return GetArt()->getSymbAddress(symbol);
},
.art_symbol_prefix_resolver = [](auto symbol) {
return GetArt()->getSymbPrefixFirstOffset(symbol);
}, },
}; };
InitHooks(env, initInfo); InitHooks(env, initInfo);
@ -199,7 +202,10 @@ namespace lspd {
return UnhookFunction(t) == RT_SUCCESS; return UnhookFunction(t) == RT_SUCCESS;
}, },
.art_symbol_resolver = [](auto symbol){ .art_symbol_resolver = [](auto symbol){
return GetArt()->getSymbAddress<void*>(symbol); return GetArt()->getSymbAddress(symbol);
},
.art_symbol_prefix_resolver = [](auto symbol) {
return GetArt()->getSymbPrefixFirstOffset(symbol);
}, },
}; };
auto [dex_fd, size] = instance->RequestLSPDex(env, binder); auto [dex_fd, size] = instance->RequestLSPDex(env, binder);