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": {
|
"disable_bitmoji": {
|
||||||
"name": "Disable Bitmoji",
|
"name": "Disable Bitmoji",
|
||||||
"description": "Disables Friends Profile 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) {
|
class NativeHooks : ConfigContainer(hasGlobalState = true) {
|
||||||
val disableBitmoji = boolean("disable_bitmoji")
|
val disableBitmoji = boolean("disable_bitmoji")
|
||||||
|
val remapApk = boolean("remap_apk") { addNotices(FeatureNotice.UNSTABLE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
class E2EEConfig : ConfigContainer(hasGlobalState = true) {
|
class E2EEConfig : ConfigContainer(hasGlobalState = true) {
|
||||||
|
@ -147,11 +147,16 @@ class ModContext(
|
|||||||
_config.loadFromCallback { file ->
|
_config.loadFromCallback { file ->
|
||||||
file.loadFromBridge(bridgeClient)
|
file.loadFromBridge(bridgeClient)
|
||||||
}
|
}
|
||||||
|
reloadNativeConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reloadNativeConfig() {
|
||||||
native.loadNativeConfig(
|
native.loadNativeConfig(
|
||||||
NativeConfig(
|
NativeConfig(
|
||||||
disableBitmoji = config.experimental.nativeHooks.disableBitmoji.get(),
|
disableBitmoji = config.experimental.nativeHooks.disableBitmoji.get(),
|
||||||
disableMetrics = config.global.disableMetrics.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)
|
val libName = param.arg<String>(1)
|
||||||
if (libName != "client") return@hook
|
if (libName != "client") return@hook
|
||||||
unhook()
|
unhook()
|
||||||
appContext.native.initOnce()
|
appContext.native.initOnce {
|
||||||
appContext.native.nativeUnaryCallCallback = { request ->
|
nativeUnaryCallCallback = { request ->
|
||||||
appContext.event.post(NativeUnaryCallEvent(request.uri, request.buffer)) {
|
appContext.event.post(NativeUnaryCallEvent(request.uri, request.buffer)) {
|
||||||
request.buffer = buffer
|
request.buffer = buffer
|
||||||
request.canceled = canceled
|
request.canceled = canceled
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
appContext.reloadNativeConfig()
|
||||||
}
|
}
|
||||||
}.also { unhook = { it.unhook() } }
|
}.also { unhook = { it.unhook() } }
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ android {
|
|||||||
cmake {
|
cmake {
|
||||||
arguments += listOf(
|
arguments += listOf(
|
||||||
"-DOBFUSCATED_NAME=$nativeName",
|
"-DOBFUSCATED_NAME=$nativeName",
|
||||||
|
"-DBUILD_PACKAGE=${rootProject.ext["applicationId"]}",
|
||||||
"-DBUILD_NAMESPACE=${namespace!!.replace(".", "/")}"
|
"-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_NAMESPACE="${BUILD_NAMESPACE}")
|
||||||
|
add_compile_definitions(BUILD_PACKAGE="${BUILD_PACKAGE}")
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||||
android
|
android
|
||||||
log
|
log
|
||||||
|
@ -13,6 +13,7 @@ typedef struct {
|
|||||||
bool disable_bitmoji;
|
bool disable_bitmoji;
|
||||||
bool disable_metrics;
|
bool disable_metrics;
|
||||||
bool hook_asset_open;
|
bool hook_asset_open;
|
||||||
|
bool remap_apk;
|
||||||
} native_config_t;
|
} native_config_t;
|
||||||
|
|
||||||
namespace common {
|
namespace common {
|
||||||
|
@ -15,7 +15,6 @@ void JNICALL init(JNIEnv *env, jobject clazz) {
|
|||||||
LOGD("Initializing native");
|
LOGD("Initializing native");
|
||||||
using namespace common;
|
using namespace common;
|
||||||
|
|
||||||
native_config = new native_config_t;
|
|
||||||
native_lib_object = env->NewGlobalRef(clazz);
|
native_lib_object = env->NewGlobalRef(clazz);
|
||||||
client_module = util::get_module("libclient.so");
|
client_module = util::get_module("libclient.so");
|
||||||
|
|
||||||
@ -32,6 +31,10 @@ void JNICALL init(JNIEnv *env, jobject clazz) {
|
|||||||
SqliteMutexHook::init();
|
SqliteMutexHook::init();
|
||||||
DuplexHook::init(env);
|
DuplexHook::init(env);
|
||||||
|
|
||||||
|
if (native_config->remap_apk) {
|
||||||
|
util::remap_sections(BUILD_PACKAGE);
|
||||||
|
}
|
||||||
|
|
||||||
LOGD("Native initialized");
|
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_bitmoji = GET_CONFIG_BOOL("disableBitmoji");
|
||||||
native_config->disable_metrics = GET_CONFIG_BOOL("disableMetrics");
|
native_config->disable_metrics = GET_CONFIG_BOOL("disableMetrics");
|
||||||
native_config->hook_asset_open = GET_CONFIG_BOOL("hookAssetOpen");
|
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) {
|
void JNICALL lock_database(JNIEnv *env, jobject _, jstring database_name, jobject runnable) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#define HOOK_DEF(ret, func, ...) ret (*func##_original)(__VA_ARGS__); ret func(__VA_ARGS__)
|
#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 };
|
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> bytes;
|
||||||
std::vector<char> mask;
|
std::vector<char> mask;
|
||||||
for (size_t i = 0; i < pattern.size(); i += 3) {
|
for (size_t i = 0; i < pattern.size(); i += 3) {
|
||||||
|
@ -4,4 +4,5 @@ data class NativeConfig(
|
|||||||
val disableBitmoji: Boolean = false,
|
val disableBitmoji: Boolean = false,
|
||||||
val disableMetrics: Boolean = false,
|
val disableMetrics: Boolean = false,
|
||||||
val hookAssetOpen: Boolean = false,
|
val hookAssetOpen: Boolean = false,
|
||||||
|
val remapApk: Boolean = false,
|
||||||
)
|
)
|
@ -11,13 +11,15 @@ class NativeLib {
|
|||||||
private set
|
private set
|
||||||
}
|
}
|
||||||
|
|
||||||
fun initOnce() {
|
fun initOnce(callback: NativeLib.() -> Unit) {
|
||||||
if (initialized) throw IllegalStateException("NativeLib already initialized")
|
if (initialized) throw IllegalStateException("NativeLib already initialized")
|
||||||
runCatching {
|
runCatching {
|
||||||
System.loadLibrary(BuildConfig.NATIVE_NAME)
|
System.loadLibrary(BuildConfig.NATIVE_NAME)
|
||||||
init()
|
|
||||||
initialized = true
|
initialized = true
|
||||||
|
callback(this)
|
||||||
|
init()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
|
initialized = false
|
||||||
Log.e("SnapEnhance", "NativeLib init failed")
|
Log.e("SnapEnhance", "NativeLib init failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user