Use LSPlt only for Android 15
For non-stripped `libart.so` ELFs, their plt tables are too small for inline hook.
This commit is contained in:
parent
1d7de6c78e
commit
d4e00eac40
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue