#include #include #include "zygisk.hpp" #include using namespace std; static vector find_maps(const char *name) { auto maps = lsplt::MapInfo::Scan(); for (auto iter = maps.begin(); iter != maps.end();) { if (iter->path != name) { iter = maps.erase(iter); } else { ++iter; } } return maps; } std::pair find_map_range(const char *name, unsigned long inode) { auto maps = find_maps(name); uintptr_t start = 0u; uintptr_t end = 0u; for (const auto &map : maps) { if (map.inode == inode) { if (start == 0) { start = map.start; end = map.end; } else if (map.start == end) { end = map.end; } } } LOGD("found map %s with start = %zx, end = %zx\n", name, start, end); return make_pair(reinterpret_cast(start), end - start); } void unmap_all(const char *name) { auto maps = find_maps(name); for (auto &info : maps) { void *addr = reinterpret_cast(info.start); size_t size = info.end - info.start; if (info.perms & PROT_READ) { // Make sure readable pages are still readable void *dummy = xmmap(nullptr, size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); mremap(dummy, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, addr); } else { munmap(addr, size); } } } void remap_all(const char *name) { auto maps = find_maps(name); for (auto &info : maps) { void *addr = reinterpret_cast(info.start); size_t size = info.end - info.start; void *copy = xmmap(nullptr, size, PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if ((info.perms & PROT_READ) == 0) { mprotect(addr, size, PROT_READ); } memcpy(copy, addr, size); mremap(copy, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, addr); mprotect(addr, size, info.perms); } } uintptr_t get_function_off(int pid, uintptr_t addr, char *lib) { for (auto &info : lsplt::MapInfo::Scan()) { if (addr >= info.start && addr < info.end) { if (lib) strcpy(lib, info.path.data()); return addr - info.start + info.offset; } } return 0; } uintptr_t get_function_addr(int pid, const char *lib, uintptr_t off) { for (auto &info : lsplt::MapInfo::Scan()) { if (info.path == lib && (info.perms & PROT_EXEC)) { return info.start - info.offset + off; } } return 0; }