Align page

This commit is contained in:
LoveSy 2022-11-27 01:47:12 +08:00
parent 43f688135b
commit b7fcd5c915
No known key found for this signature in database

View File

@ -15,6 +15,13 @@
#include "logging.hpp" #include "logging.hpp"
namespace { namespace {
inline auto PageStart(uintptr_t addr) { return reinterpret_cast<char *>(((addr)&PAGE_MASK)); }
inline auto PageEnd(uintptr_t addr) {
return reinterpret_cast<char *>(reinterpret_cast<uintptr_t>(PageStart(addr)) + PAGE_SIZE);
}
struct RegisterInfo { struct RegisterInfo {
ino_t inode; ino_t inode;
std::string symbol; std::string symbol;
@ -34,13 +41,10 @@ public:
static auto ScanHookInfo() { static auto ScanHookInfo() {
HookInfos info; HookInfos info;
for (auto &map : lsplt::MapInfo::Scan()) { for (auto &map : lsplt::MapInfo::Scan()) {
// we basically only care about r--p entry // we basically only care about r-?p entry
// and for offset == 0 it's an ELF header // and for offset == 0 it's an ELF header
// and for offset != 0 it's what we hook // and for offset != 0 it's what we hook
// if (perm[0] != 'r') continue;
if (!map.is_private) continue; if (!map.is_private) continue;
if (map.perms & PROT_EXEC) continue;
// if (off != 0) continue;
if (map.path.empty()) continue; if (map.path.empty()) continue;
if (map.path[0] == '[') continue; if (map.path[0] == '[') continue;
auto start = map.start; auto start = map.start;
@ -61,8 +65,9 @@ public:
} }
} }
if (matched) { if (matched) {
LOGV("Match hook info %s:%lu %" PRIxPTR " %" PRIxPTR "-%" PRIxPTR, iter->second.path.data(), LOGV("Match hook info %s:%lu %" PRIxPTR " %" PRIxPTR "-%" PRIxPTR,
iter->second.inode, iter->second.start, iter->second.end, iter->second.offset); iter->second.path.data(), iter->second.inode, iter->second.start,
iter->second.end, iter->second.offset);
++iter; ++iter;
} else { } else {
iter = erase(iter); iter = erase(iter);
@ -102,8 +107,8 @@ public:
new_addr == MAP_FAILED || new_addr != backup_addr) { new_addr == MAP_FAILED || new_addr != backup_addr) {
return false; return false;
} }
if (auto *new_addr = if (auto *new_addr = mmap(reinterpret_cast<void *>(info.start), len,
mmap(reinterpret_cast<void *>(info.start), len, PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE | info.perms,
MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0); MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);
new_addr == MAP_FAILED) { new_addr == MAP_FAILED) {
return false; return false;
@ -113,8 +118,11 @@ public:
} }
auto *the_addr = reinterpret_cast<uintptr_t *>(addr); auto *the_addr = reinterpret_cast<uintptr_t *>(addr);
auto the_backup = *the_addr; auto the_backup = *the_addr;
if (backup) *backup = the_backup; if (*the_addr != addr) {
*the_addr = callback; *the_addr = callback;
if (backup) *backup = the_backup;
__builtin___clear_cache(PageStart(addr), PageEnd(addr));
}
if (auto hook_iter = info.hooks.find(addr); hook_iter != info.hooks.end()) { if (auto hook_iter = info.hooks.find(addr); hook_iter != info.hooks.end()) {
if (hook_iter->second == callback) info.hooks.erase(hook_iter); if (hook_iter->second == callback) info.hooks.erase(hook_iter);
} else { } else {
@ -176,11 +184,11 @@ public:
info.hooks.clear(); info.hooks.clear();
continue; continue;
} }
if (!mprotect(reinterpret_cast<void *>(info.start), len, PROT_WRITE)) { if (!mprotect(PageStart(info.start), len, PROT_WRITE)) {
for (auto &[addr, backup] : info.hooks) { for (auto &[addr, backup] : info.hooks) {
*reinterpret_cast<uintptr_t *>(addr) = backup; *reinterpret_cast<uintptr_t *>(addr) = backup;
} }
mprotect(reinterpret_cast<void *>(info.start), len, info.perms); mprotect(PageStart(info.start), len, info.perms);
} }
info.hooks.clear(); info.hooks.clear();
info.backup = 0; info.backup = 0;