add: maps hiding (#13)

This commit adds maps hiding. This commit is taken from Reveny's PR, for more information, see #9.

solves #9
This commit is contained in:
Pedro.js
2024-06-26 19:38:34 -03:00
committed by GitHub
parent 4aa8b2f828
commit af96b85a91
6 changed files with 563 additions and 7 deletions

View File

@@ -22,6 +22,8 @@
#include "files.hpp"
#include "misc.hpp"
#include "solist.hpp"
#include "art_method.hpp"
using namespace std;
@@ -579,18 +581,98 @@ void ZygiskContext::run_modules_post() {
}
m.tryUnload();
}
// Remove from SoList to avoid detection
bool solist_res = SoList::Initialize();
if (!solist_res) {
LOGE("Failed to initialize SoList\n");
} else {
SoList::NullifySoName("jit-cache");
}
// Remap as well to avoid checking of /memfd:jit-cache
for (auto &info : lsplt::MapInfo::Scan()) {
if (strstr(info.path.c_str(), "jit-cache-zygisk"))
{
void *addr = (void *)info.start;
size_t size = info.end - info.start;
// MAP_SHARED should fix the suspicious mapping.
void *copy = mmap(nullptr, size, PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if (copy == MAP_FAILED) {
LOGE("Failed to mmap jit-cache-zygisk\n");
continue;
}
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);
}
}
// Don't know if there's a header for things like this
// so I just put it into a lambda
auto generateRandomString = [](char *str, int length) {
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
srand(time(NULL));
for (int i = 0; i < length; i++) {
int key = rand() % (sizeof(charset) - 1);
str[i] = charset[key];
}
str[length] = '\0';
};
// Randomize name of anonymous mappings
// We don't run this in the previous loop because LSPosed might also add
// mappings that are not related to /memfd:jit-zygisk-cache
//
// Since we changed to MAP_SHARED, I don't think this is still needed but let's
// leave it here just in case.
for (auto info : lsplt::MapInfo::Scan()) {
// I had some problems with info.perms & PROT_EXEC so I had to change lsplt source a bit.
// If that problem occurs here, do strchr(info.perms_str.c_str(), 'x') instead and add perms_str
// to the lsplt MapInfo struct and set it to the raw perms string in Scan();
if (info.perms & PROT_EXEC && info.path.empty()) {
// Generate Random Name
char randomString[11];
generateRandomString(randomString, 10);
LOGI("Randomized Memory map name: %s", randomString);
// Memory address of random string
uintptr_t strAddr = (uintptr_t)&randomString;
// https://lore.kernel.org/lkml/1383170047-21074-2-git-send-email-ccross@android.com/
prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, info.start, info.end - info.start, strAddr);
}
// Remap as MAP_SHARED
if (info.perms & PROT_EXEC && info.dev == 0 && info.path.find("anon") != std::string::npos) {
void *addr = reinterpret_cast<void *>(info.start);
size_t size = info.end - info.start;
void *copy = mmap(nullptr, size, PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -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);
}
}
}
/* Zygisksu changed: Load module fds */
void ZygiskContext::app_specialize_pre() {
flags[APP_SPECIALIZE] = true;
info_flags = zygiskd::GetProcessFlags(g_ctx->args.app->uid);
if ((info_flags & (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) == (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) {
LOGI("current uid %d is manager!", g_ctx->args.app->uid);
setenv("ZYGISK_ENABLED", "1", 1);
} else {
run_modules_pre();
if ((info_flags & PROCESS_ON_DENYLIST) == PROCESS_ON_DENYLIST) {
flags[DO_REVERT_UNMOUNT] = true;
}
run_modules_pre();
}