diff --git a/lsplt/src/main/jni/lsplt.cc b/lsplt/src/main/jni/lsplt.cc index ac2bd92..dc3bbe3 100644 --- a/lsplt/src/main/jni/lsplt.cc +++ b/lsplt/src/main/jni/lsplt.cc @@ -113,7 +113,6 @@ public: } bool DoHook(uintptr_t addr, uintptr_t callback, uintptr_t *backup) { - static bool kSkipRemap = false; using PAGE = std::array; LOGV("Hooking %p", reinterpret_cast(addr)); auto iter = lower_bound(addr); @@ -122,7 +121,7 @@ public: auto &info = iter->second; if (info.end <= addr) return false; const auto len = info.end - info.start; - while (!info.backup && !info.self && !kSkipRemap) { + if (!info.backup && !info.self) { // let os find a suitable address auto *backup_addr = sys_mmap(nullptr, len, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0); LOGD("Backup %p to %p", reinterpret_cast(addr), backup_addr); @@ -130,8 +129,7 @@ public: if (auto *new_addr = sys_mremap(reinterpret_cast(info.start), len, len, MREMAP_FIXED | MREMAP_MAYMOVE, backup_addr); new_addr == MAP_FAILED || new_addr != backup_addr) { - kSkipRemap = true; - break; + return false; } if (auto *new_addr = sys_mmap(reinterpret_cast(info.start), len, PROT_READ | PROT_WRITE | info.perms, @@ -146,9 +144,8 @@ public: *reinterpret_cast(dest) = *reinterpret_cast(src); } info.backup = reinterpret_cast(backup_addr); - break; } - if (info.self || !info.backup) { + if (info.self) { // self hooking, no need backup since we are always dirty if (!(info.perms & PROT_WRITE)) { info.perms |= PROT_WRITE; @@ -167,9 +164,11 @@ public: } else { info.hooks.emplace(addr, the_backup); } - if (info.hooks.empty() && !info.self && info.backup) { + if (info.hooks.empty() && !info.self) { LOGD("Restore %p from %p", reinterpret_cast(info.start), reinterpret_cast(info.backup)); + // Note that we have to always use sys_mremap here, + // see https://cs.android.com/android/_/android/platform/bionic/+/4200e260d266fd0c176e71fbd720d0bab04b02db if (auto *new_addr = sys_mremap(reinterpret_cast(info.backup), len, len, MREMAP_FIXED | MREMAP_MAYMOVE, reinterpret_cast(info.start));