commit 006f9f84e39bc8c9d39b011505c41de62402e0c2
parent a355ea966727fe86e35cd962dd2c9c59b649e8a8
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Tue, 11 Jun 2024 00:09:13 +0200
refactor(native): remap sections
Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>
Diffstat:
5 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/SnapEnhance.kt
@@ -5,6 +5,7 @@ import android.app.Application
import android.content.Context
import android.content.res.Resources
import android.os.Build
+import dalvik.system.BaseDexClassLoader
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -27,6 +28,7 @@ import me.rhunk.snapenhance.core.util.LSPatchUpdater
import me.rhunk.snapenhance.core.util.hook.HookAdapter
import me.rhunk.snapenhance.core.util.hook.HookStage
import me.rhunk.snapenhance.core.util.hook.hook
+import me.rhunk.snapenhance.core.util.hook.hookConstructor
import kotlin.system.exitProcess
import kotlin.system.measureTimeMillis
@@ -205,6 +207,9 @@ class SnapEnhance {
request.canceled = canceled
}
}
+ BaseDexClassLoader::class.java.hookConstructor(HookStage.AFTER) {
+ appContext.native.hideAnonymousDexFiles()
+ }
appContext.reloadNativeConfig()
}
}.also { unhook = { it.unhook() } }
diff --git a/native/jni/src/dobby_helper.h b/native/jni/src/dobby_helper.h
@@ -9,5 +9,6 @@ static pthread_mutex_t hook_mutex = PTHREAD_MUTEX_INITIALIZER;
static void inline SafeHook(void *addr, void *hook, void **original) {
pthread_mutex_lock(&hook_mutex);
DobbyHook(addr, hook, original);
+ mprotect((void *)((uintptr_t) *original & PAGE_MASK), PAGE_SIZE, PROT_EXEC);
pthread_mutex_unlock(&hook_mutex);
}
\ No newline at end of file
diff --git a/native/jni/src/library.cpp b/native/jni/src/library.cpp
@@ -4,9 +4,9 @@
#include <vector>
#include <thread>
-#include "dobby_helper.h"
#include "logger.h"
#include "common.h"
+#include "dobby_helper.h"
#include "hooks/unary_call.h"
#include "hooks/fstat_hook.h"
#include "hooks/sqlite_mutex.h"
@@ -93,6 +93,16 @@ void JNICALL lock_database(JNIEnv *env, jobject, jstring database_name, jobject
}
}
+void JNICALL hide_anonymous_dex_files(JNIEnv *, jobject) {
+ util::remap_sections([](const std::string &line, size_t size) {
+ return (
+ (size == PAGE_SIZE && line.find("r-xp 00000000") != std::string::npos && line.find("[v") == std::string::npos) ||
+ line.find("dalvik-DEX") != std::string::npos ||
+ line.find("dalvik-classes") != std::string::npos
+ );
+ });
+}
+
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *_) {
common::java_vm = vm;
JNIEnv *env = nullptr;
@@ -104,8 +114,12 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *_) {
methods.push_back({"lockDatabase", "(Ljava/lang/String;Ljava/lang/Runnable;)V", (void *)lock_database});
methods.push_back({"setComposerLoader", "(Ljava/lang/String;)V", (void *) ComposerHook::setComposerLoader});
methods.push_back({"composerEval", "(Ljava/lang/String;)Ljava/lang/String;",(void *) ComposerHook::composerEval});
+ methods.push_back({"hideAnonymousDexFiles", "()V", (void *)hide_anonymous_dex_files});
env->RegisterNatives(env->FindClass(std::string(BUILD_NAMESPACE "/NativeLib").c_str()), methods.data(), methods.size());
- util::remap_sections(BUILD_PACKAGE);
+ util::remap_sections([](const std::string &line, size_t size) {
+ return line.find(BUILD_PACKAGE) != std::string::npos;
+ });
+ hide_anonymous_dex_files(env, nullptr);
return JNI_VERSION_1_6;
}
diff --git a/native/jni/src/util.h b/native/jni/src/util.h
@@ -52,14 +52,13 @@ namespace util {
return { start_offset, end_offset - start_offset };
}
- static void remap_sections(const char* path) {
+ static void remap_sections(std::function<bool(const std::string &, size_t)> filter) {
char buff[256];
auto maps = fopen("/proc/self/maps", "rt");
while (fgets(buff, sizeof buff, maps) != NULL) {
int len = strlen(buff);
if (len > 0 && buff[len - 1] == '\n') buff[--len] = '\0';
- if (strstr(buff, path) == nullptr) continue;
size_t start, end, offset;
char flags[4];
@@ -67,7 +66,7 @@ namespace util {
if (sscanf(buff, "%zx-%zx %c%c%c%c %zx", &start, &end,
&flags[0], &flags[1], &flags[2], &flags[3], &offset) != 7) continue;
- LOGD("Remapping 0x%zx-0x%zx", start, end);
+ if (!filter(buff, end - start)) continue;
auto section_size = end - start;
auto section_ptr = mmap(0, section_size, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
@@ -84,7 +83,11 @@ namespace util {
break;
}
- mprotect((void *)start, section_size, (flags[0] == 'r' ? PROT_READ : 0) | (flags[1] == 'w' ? PROT_WRITE : 0) | (flags[2] == 'x' ? PROT_EXEC : 0));
+ auto new_prot = (flags[0] == 'r' ? PROT_READ : 0) | (flags[1] == 'w' ? PROT_WRITE : 0) | (flags[2] == 'x' ? PROT_EXEC : 0);
+ if (new_prot & PROT_EXEC) {
+ new_prot &= ~PROT_READ;
+ }
+ mprotect((void *)start, section_size, new_prot);
}
fclose(maps);
}
diff --git a/native/src/main/kotlin/me/rhunk/snapenhance/nativelib/NativeLib.kt b/native/src/main/kotlin/me/rhunk/snapenhance/nativelib/NativeLib.kt
@@ -59,4 +59,5 @@ class NativeLib {
private external fun lockDatabase(name: String, callback: Runnable)
external fun setComposerLoader(code: String)
external fun composerEval(code: String): String?
+ external fun hideAnonymousDexFiles()
}
\ No newline at end of file