mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-06-13 13:47:47 +02:00
fix(native): load config before init
- add native remap apk
This commit is contained in:
@ -627,6 +627,10 @@
|
||||
"disable_bitmoji": {
|
||||
"name": "Disable Bitmoji",
|
||||
"description": "Disables Friends Profile Bitmoji"
|
||||
},
|
||||
"remap_apk": {
|
||||
"name": "Remap APK",
|
||||
"description": "Hides SnapEnhance apk path in /proc/self/maps"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -11,6 +11,7 @@ class Experimental : ConfigContainer() {
|
||||
|
||||
class NativeHooks : ConfigContainer(hasGlobalState = true) {
|
||||
val disableBitmoji = boolean("disable_bitmoji")
|
||||
val remapApk = boolean("remap_apk") { addNotices(FeatureNotice.UNSTABLE) }
|
||||
}
|
||||
|
||||
class E2EEConfig : ConfigContainer(hasGlobalState = true) {
|
||||
|
@ -147,11 +147,16 @@ class ModContext(
|
||||
_config.loadFromCallback { file ->
|
||||
file.loadFromBridge(bridgeClient)
|
||||
}
|
||||
reloadNativeConfig()
|
||||
}
|
||||
|
||||
fun reloadNativeConfig() {
|
||||
native.loadNativeConfig(
|
||||
NativeConfig(
|
||||
disableBitmoji = config.experimental.nativeHooks.disableBitmoji.get(),
|
||||
disableMetrics = config.global.disableMetrics.get(),
|
||||
hookAssetOpen = config.experimental.disableComposerModules.get().isNotEmpty()
|
||||
hookAssetOpen = config.experimental.disableComposerModules.get().isNotEmpty(),
|
||||
remapApk = config.experimental.nativeHooks.remapApk.get(),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -190,12 +190,14 @@ class SnapEnhance {
|
||||
val libName = param.arg<String>(1)
|
||||
if (libName != "client") return@hook
|
||||
unhook()
|
||||
appContext.native.initOnce()
|
||||
appContext.native.nativeUnaryCallCallback = { request ->
|
||||
appContext.event.post(NativeUnaryCallEvent(request.uri, request.buffer)) {
|
||||
request.buffer = buffer
|
||||
request.canceled = canceled
|
||||
appContext.native.initOnce {
|
||||
nativeUnaryCallCallback = { request ->
|
||||
appContext.event.post(NativeUnaryCallEvent(request.uri, request.buffer)) {
|
||||
request.buffer = buffer
|
||||
request.canceled = canceled
|
||||
}
|
||||
}
|
||||
appContext.reloadNativeConfig()
|
||||
}
|
||||
}.also { unhook = { it.unhook() } }
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ android {
|
||||
cmake {
|
||||
arguments += listOf(
|
||||
"-DOBFUSCATED_NAME=$nativeName",
|
||||
"-DBUILD_PACKAGE=${rootProject.ext["applicationId"]}",
|
||||
"-DBUILD_NAMESPACE=${namespace!!.replace(".", "/")}"
|
||||
)
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
|
||||
)
|
||||
|
||||
add_compile_definitions(BUILD_NAMESPACE="${BUILD_NAMESPACE}")
|
||||
add_compile_definitions(BUILD_PACKAGE="${BUILD_PACKAGE}")
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
android
|
||||
log
|
||||
|
@ -13,6 +13,7 @@ typedef struct {
|
||||
bool disable_bitmoji;
|
||||
bool disable_metrics;
|
||||
bool hook_asset_open;
|
||||
bool remap_apk;
|
||||
} native_config_t;
|
||||
|
||||
namespace common {
|
||||
|
@ -15,7 +15,6 @@ void JNICALL init(JNIEnv *env, jobject clazz) {
|
||||
LOGD("Initializing native");
|
||||
using namespace common;
|
||||
|
||||
native_config = new native_config_t;
|
||||
native_lib_object = env->NewGlobalRef(clazz);
|
||||
client_module = util::get_module("libclient.so");
|
||||
|
||||
@ -32,6 +31,10 @@ void JNICALL init(JNIEnv *env, jobject clazz) {
|
||||
SqliteMutexHook::init();
|
||||
DuplexHook::init(env);
|
||||
|
||||
if (native_config->remap_apk) {
|
||||
util::remap_sections(BUILD_PACKAGE);
|
||||
}
|
||||
|
||||
LOGD("Native initialized");
|
||||
}
|
||||
|
||||
@ -43,6 +46,7 @@ void JNICALL load_config(JNIEnv *env, jobject _, jobject config_object) {
|
||||
native_config->disable_bitmoji = GET_CONFIG_BOOL("disableBitmoji");
|
||||
native_config->disable_metrics = GET_CONFIG_BOOL("disableMetrics");
|
||||
native_config->hook_asset_open = GET_CONFIG_BOOL("hookAssetOpen");
|
||||
native_config->remap_apk = GET_CONFIG_BOOL("remapApk");
|
||||
}
|
||||
|
||||
void JNICALL lock_database(JNIEnv *env, jobject _, jstring database_name, jobject runnable) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define HOOK_DEF(ret, func, ...) ret (*func##_original)(__VA_ARGS__); ret func(__VA_ARGS__)
|
||||
|
||||
@ -51,7 +52,43 @@ namespace util {
|
||||
return { start_offset, end_offset - start_offset };
|
||||
}
|
||||
|
||||
uintptr_t find_signature(uintptr_t module_base, uintptr_t size, const std::string &pattern, int offset = 0) {
|
||||
static void remap_sections(const char* path) {
|
||||
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];
|
||||
|
||||
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);
|
||||
|
||||
auto section_size = end - start;
|
||||
auto section_ptr = mmap(0, section_size, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
if (section_ptr == MAP_FAILED) {
|
||||
LOGE("mmap failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(section_ptr, (void *)start, section_size);
|
||||
|
||||
if (mremap(section_ptr, section_size, section_size, MREMAP_MAYMOVE | MREMAP_FIXED, start) == MAP_FAILED) {
|
||||
LOGE("mremap failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
mprotect((void *)start, section_size, (flags[0] == 'r' ? PROT_READ : 0) | (flags[1] == 'w' ? PROT_WRITE : 0) | (flags[2] == 'x' ? PROT_EXEC : 0));
|
||||
}
|
||||
}
|
||||
|
||||
static uintptr_t find_signature(uintptr_t module_base, uintptr_t size, const std::string &pattern, int offset = 0) {
|
||||
std::vector<char> bytes;
|
||||
std::vector<char> mask;
|
||||
for (size_t i = 0; i < pattern.size(); i += 3) {
|
||||
|
@ -4,4 +4,5 @@ data class NativeConfig(
|
||||
val disableBitmoji: Boolean = false,
|
||||
val disableMetrics: Boolean = false,
|
||||
val hookAssetOpen: Boolean = false,
|
||||
val remapApk: Boolean = false,
|
||||
)
|
@ -11,13 +11,15 @@ class NativeLib {
|
||||
private set
|
||||
}
|
||||
|
||||
fun initOnce() {
|
||||
fun initOnce(callback: NativeLib.() -> Unit) {
|
||||
if (initialized) throw IllegalStateException("NativeLib already initialized")
|
||||
runCatching {
|
||||
System.loadLibrary(BuildConfig.NATIVE_NAME)
|
||||
init()
|
||||
initialized = true
|
||||
callback(this)
|
||||
init()
|
||||
}.onFailure {
|
||||
initialized = false
|
||||
Log.e("SnapEnhance", "NativeLib init failed")
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user