forked from LSPosed/LSPosed
-
Notifications
You must be signed in to change notification settings - Fork 130
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hook dex2oat functions to remove LSPosed traces (#152)
We use the env LD_PRELOAD to hook the execution of `dex2oat`, which can be directly set to be a file descriptor.
- Loading branch information
1 parent
7cd98e6
commit c0478f5
Showing
10 changed files
with
166 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
#pragma once | ||
|
||
#include <errno.h> | ||
#include <android/log.h> | ||
|
||
#ifndef LOG_TAG | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include <dlfcn.h> | ||
|
||
#include <lsplt.hpp> | ||
#include <map> | ||
#include <string> | ||
#include <string_view> | ||
#include <vector> | ||
|
||
#include "logging.h" | ||
|
||
const std::string_view parameter_to_remove = " --inline-max-code-units=0"; | ||
|
||
#define DCL_HOOK_FUNC(ret, func, ...) \ | ||
ret (*old_##func)(__VA_ARGS__); \ | ||
ret new_##func(__VA_ARGS__) | ||
|
||
bool store_updated = false; | ||
|
||
void UpdateKeyValueStore(std::map<std::string, std::string>* key_value, uint8_t* store) { | ||
LOGD("updating KeyValueStore"); | ||
char* data_ptr = reinterpret_cast<char*>(store); | ||
if (key_value != nullptr) { | ||
auto it = key_value->begin(); | ||
auto end = key_value->end(); | ||
for (; it != end; ++it) { | ||
strlcpy(data_ptr, it->first.c_str(), it->first.length() + 1); | ||
data_ptr += it->first.length() + 1; | ||
strlcpy(data_ptr, it->second.c_str(), it->second.length() + 1); | ||
data_ptr += it->second.length() + 1; | ||
} | ||
} | ||
LOGD("KeyValueStore updated"); | ||
store_updated = true; | ||
} | ||
|
||
DCL_HOOK_FUNC(uint32_t, _ZNK3art9OatHeader20GetKeyValueStoreSizeEv, void* header) { | ||
uint32_t size = old__ZNK3art9OatHeader20GetKeyValueStoreSizeEv(header); | ||
if (store_updated) { | ||
LOGD("OatHeader::GetKeyValueStoreSize() called on object at %p\n", header); | ||
size = size - parameter_to_remove.size(); | ||
} | ||
return size; | ||
} | ||
|
||
DCL_HOOK_FUNC(uint8_t*, _ZNK3art9OatHeader16GetKeyValueStoreEv, void* header) { | ||
LOGD("OatHeader::GetKeyValueStore() called on object at %p\n", header); | ||
uint8_t* key_value_store_ = old__ZNK3art9OatHeader16GetKeyValueStoreEv(header); | ||
uint32_t key_value_store_size_ = old__ZNK3art9OatHeader20GetKeyValueStoreSizeEv(header); | ||
const char* ptr = reinterpret_cast<const char*>(key_value_store_); | ||
const char* end = ptr + key_value_store_size_; | ||
std::map<std::string, std::string> new_store = {}; | ||
|
||
LOGD("scanning [%p-%p] for oat headers", ptr, end); | ||
while (ptr < end) { | ||
// Scan for a closing zero. | ||
const char* str_end = reinterpret_cast<const char*>(memchr(ptr, 0, end - ptr)); | ||
if (str_end == nullptr) [[unlikely]] { | ||
LOGE("failed to find str_end"); | ||
return key_value_store_; | ||
} | ||
std::string_view key = std::string_view(ptr, str_end - ptr); | ||
const char* value_start = str_end + 1; | ||
const char* value_end = | ||
reinterpret_cast<const char*>(memchr(value_start, 0, end - value_start)); | ||
if (value_end == nullptr) [[unlikely]] { | ||
LOGE("failed to find value_end"); | ||
return key_value_store_; | ||
} | ||
std::string_view value = std::string_view(value_start, value_end - value_start); | ||
LOGV("header %s:%s", key.data(), value.data()); | ||
if (key == "dex2oat-cmdline") { | ||
value = value.substr(0, value.size() - parameter_to_remove.size()); | ||
} | ||
new_store.insert(std::make_pair(std::string(key), std::string(value))); | ||
// Different from key. Advance over the value. | ||
ptr = value_end + 1; | ||
} | ||
UpdateKeyValueStore(&new_store, key_value_store_); | ||
|
||
return key_value_store_; | ||
} | ||
|
||
#undef DCL_HOOK_FUNC | ||
|
||
void register_hook(dev_t dev, ino_t inode, const char* symbol, void* new_func, void** old_func) { | ||
LOGD("RegisterHook: %s, %p, %p", symbol, new_func, old_func); | ||
if (!lsplt::RegisterHook(dev, inode, symbol, new_func, old_func)) { | ||
LOGE("Failed to register plt_hook \"%s\"\n", symbol); | ||
return; | ||
} | ||
} | ||
|
||
#define PLT_HOOK_REGISTER_SYM(DEV, INODE, SYM, NAME) \ | ||
register_hook(DEV, INODE, SYM, reinterpret_cast<void*>(new_##NAME), \ | ||
reinterpret_cast<void**>(&old_##NAME)) | ||
|
||
#define PLT_HOOK_REGISTER(DEV, INODE, NAME) PLT_HOOK_REGISTER_SYM(DEV, INODE, #NAME, NAME) | ||
|
||
__attribute__((constructor)) static void initialize() { | ||
dev_t dev = 0; | ||
ino_t inode = 0; | ||
for (auto& info : lsplt::MapInfo::Scan()) { | ||
if (info.path.starts_with("/apex/com.android.art/bin/dex2oat")) { | ||
dev = info.dev; | ||
inode = info.inode; | ||
break; | ||
} | ||
} | ||
LOGD("dex2oat binary %lu:%lu", dev, inode); | ||
|
||
PLT_HOOK_REGISTER(dev, inode, _ZNK3art9OatHeader20GetKeyValueStoreSizeEv); | ||
PLT_HOOK_REGISTER(dev, inode, _ZNK3art9OatHeader16GetKeyValueStoreEv); | ||
if (lsplt::CommitHook()) { | ||
LOGD("lsplt hooks done"); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters