Skip to content

Commit

Permalink
Use LSPlt only for Android 15
Browse files Browse the repository at this point in the history
For non-stripped `libart.so` ELFs, their plt tables are too small for
inline hook.
  • Loading branch information
JingMatrix committed Aug 31, 2024
1 parent 30043e2 commit b42e3b4
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +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
- [LSPlt](https://github.com/LSPosed/LSPlt): used for `libart` inline hooking
- [Dobby](https://github.com/chiteroman/Dobby): used for `native_api` inline hooking
- [LSPlt](https://github.com/LSPosed/LSPlt): used for (Android 15) `libart` inline hooking
- [Dobby](https://github.com/chiteroman/Dobby): used for fallback and `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
4 changes: 4 additions & 0 deletions core/src/main/jni/include/elf_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ namespace SandHook {
return base != nullptr;
}

bool isStripped() const {
return debugdata_offset != 0 && debugdata_size != 0;
}

const std::string name() const {
return elf;
}
Expand Down
42 changes: 26 additions & 16 deletions core/src/main/jni/include/native_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,23 +80,30 @@ static dev_t dev = 0;
static ino_t inode = 0;
static std::vector<std::pair<std::string_view, void **>> plt_hook_saved = {};

inline int HookArtFunction(void *original, void *callback, void **backup, bool save = true) {
auto symbol = *reinterpret_cast<std::string_view *>(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;
inline int HookArtFunction(void *art_symbol, void *callback, void **backup, bool save = true) {
auto symbol = *reinterpret_cast<std::string_view *>(art_symbol);

if (GetArt()->isStripped()) {
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;
}
}
}

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;
}
}

auto result = lsplt::RegisterHook(dev, inode, symbol, callback, backup) && lsplt::CommitHook();
if (result && *backup != nullptr) {
if (save) plt_hook_saved.emplace_back(symbol, backup);
} else if (auto addr = GetArt()->getSymbAddress(symbol); addr) {
if (auto addr = GetArt()->getSymbAddress(symbol); addr) {
Dl_info info;
if (dladdr(addr, &info) && info.dli_sname != nullptr && info.dli_sname == symbol)
HookFunction(addr, callback, backup);
Expand All @@ -107,10 +114,13 @@ inline int HookArtFunction(void *original, void *callback, void **backup, bool s
}

inline int UnhookArtFunction(void *original) {
std::string_view func_name = *reinterpret_cast<std::string_view *>(original);
auto hook_iter = std::find_if(plt_hook_saved.begin(), plt_hook_saved.end(),
[func_name](auto record) { return record.first == func_name; });
Dl_info info;

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; });
void *stub = nullptr;
if (hook_iter != plt_hook_saved.end() &&
HookArtFunction(original, *(hook_iter->second), &stub, false)) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/jni/src/elf_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ ElfImg::ElfImg(std::string_view base_name) : elf(base_name) {

close(fd);
parse(header);
if (debugdata_offset != 0 && debugdata_size != 0) {
if (isStripped()) {
if (xzdecompress()) {
header_debugdata = reinterpret_cast<ElfW(Ehdr) *>(elf_debugdata.data());
parse(header_debugdata);
Expand Down

0 comments on commit b42e3b4

Please sign in to comment.