mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-29 13:00:17 +02:00
feat(composer_hooks): armv7 support
This commit is contained in:
parent
2bb055f464
commit
33dc0c7510
@ -772,7 +772,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"composer_hooks": {
|
"composer_hooks": {
|
||||||
"name": "Composer Hooks",
|
"name": "Composer Hooks",
|
||||||
"description": "Injects code into the Composer cross-platform UI framework (arm64 only)",
|
"description": "Injects code into the Composer cross-platform UI framework",
|
||||||
"properties": {
|
"properties": {
|
||||||
"bypass_camera_roll_limit": {
|
"bypass_camera_roll_limit": {
|
||||||
"name": "Bypass Camera Roll Limit",
|
"name": "Bypass Camera Roll Limit",
|
||||||
@ -780,7 +780,7 @@
|
|||||||
},
|
},
|
||||||
"composer_console": {
|
"composer_console": {
|
||||||
"name": "Composer Console",
|
"name": "Composer Console",
|
||||||
"description": "Allows you to execute JavaScript code in Composer"
|
"description": "Allows you to execute JavaScript code in Composer (arm64 only)"
|
||||||
},
|
},
|
||||||
"composer_logs": {
|
"composer_logs": {
|
||||||
"name": "Composer Logs",
|
"name": "Composer Logs",
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
const callExport = require('composer_core/src/DeviceBridge')[EXPORTED_FUNCTION_NAME];
|
|
||||||
|
|
||||||
if (!callExport) {
|
|
||||||
return "No export function found";
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = callExport("getConfig");
|
const config = callExport("getConfig");
|
||||||
|
|
||||||
if (config.composerLogs) {
|
if (config.composerLogs) {
|
||||||
|
@ -186,21 +186,16 @@ class ComposerHooks: Feature("ComposerHooks", loadParams = FeatureLoadParams.ACT
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val hookResult = context.native.composerEval("""
|
context.native.setComposerLoader("""
|
||||||
(() => { try { const EXPORTED_FUNCTION_NAME = "$exportedFunctionName"; $loaderScript
|
(() => { const callExport = require('composer_core/src/DeviceBridge')["$exportedFunctionName"]; try { $loaderScript
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return e.toString() + "\n" + e.stack;
|
try {
|
||||||
|
callExport("log", "error", e.toString() + "\n" + e.stack);
|
||||||
|
} catch (t) {}
|
||||||
}
|
}
|
||||||
return "success";
|
})();
|
||||||
})()
|
|
||||||
""".trimIndent().trim())
|
""".trimIndent().trim())
|
||||||
|
|
||||||
if (hookResult != "success") {
|
|
||||||
context.shortToast(("Composer loader failed : $hookResult").also {
|
|
||||||
context.log.error(it)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.composerConsole.get()) {
|
if (config.composerConsole.get()) {
|
||||||
injectConsole()
|
injectConsole()
|
||||||
}
|
}
|
||||||
@ -221,16 +216,6 @@ class ComposerHooks: Feature("ComposerHooks", loadParams = FeatureLoadParams.ACT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var composerThreadTask: (() -> Unit)? = null
|
loadHooks()
|
||||||
|
|
||||||
findClass("com.snap.composer.callable.ComposerFunctionNative").hook("nativePerform", HookStage.BEFORE) {
|
|
||||||
composerThreadTask?.invoke()
|
|
||||||
composerThreadTask = null
|
|
||||||
}
|
|
||||||
|
|
||||||
context.coroutineScope.launch {
|
|
||||||
context.native.waitForComposer()
|
|
||||||
composerThreadTask = ::loadHooks
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -93,20 +93,32 @@ namespace ComposerHook {
|
|||||||
|
|
||||||
static uintptr_t global_instance;
|
static uintptr_t global_instance;
|
||||||
static JSContext *global_ctx;
|
static JSContext *global_ctx;
|
||||||
|
static std::string* composer_loader;
|
||||||
|
|
||||||
HOOK_DEF(JSValue, js_eval, uintptr_t instance, JSContext *ctx, uintptr_t this_obj, uint8_t *input, uintptr_t input_len, const char *filename, unsigned int flags, unsigned int scope_idx) {
|
HOOK_DEF(JSValue, js_eval, uintptr_t instance, JSContext *ctx, uintptr_t this_obj, char *input, uintptr_t input_len, const char *filename, unsigned int flags, unsigned int scope_idx) {
|
||||||
if (global_instance == 0 || global_ctx == nullptr) {
|
if (global_instance == 0 || global_ctx == nullptr) {
|
||||||
global_instance = instance;
|
global_instance = instance;
|
||||||
global_ctx = ctx;
|
global_ctx = ctx;
|
||||||
}
|
LOGD("Injecting composer loader");
|
||||||
|
|
||||||
|
composer_loader->resize(composer_loader->size() + input_len);
|
||||||
|
memcpy((void*) (composer_loader->c_str() + composer_loader->size() - input_len), input, input_len);
|
||||||
|
|
||||||
|
input = (char*) composer_loader->c_str();
|
||||||
|
input_len = composer_loader->size();
|
||||||
|
} else {
|
||||||
|
if (composer_loader != nullptr) {
|
||||||
|
delete composer_loader;
|
||||||
|
composer_loader = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
return js_eval_original(instance, ctx, this_obj, input, input_len, filename, flags, scope_idx);
|
return js_eval_original(instance, ctx, this_obj, input, input_len, filename, flags, scope_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void waitForComposer(JNIEnv *, jobject) {
|
void setComposerLoader(JNIEnv *env, jobject, jstring code) {
|
||||||
while (global_instance == 0 || global_ctx == nullptr) {
|
auto code_str = env->GetStringUTFChars(code, nullptr);
|
||||||
usleep(10000);
|
composer_loader = new std::string(code_str, env->GetStringUTFLength(code));
|
||||||
}
|
env->ReleaseStringUTFChars(code, code_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring composerEval(JNIEnv *env, jobject, jstring script) {
|
jstring composerEval(JNIEnv *env, jobject, jstring script) {
|
||||||
@ -117,7 +129,7 @@ namespace ComposerHook {
|
|||||||
|
|
||||||
auto script_str = env->GetStringUTFChars(script, nullptr);
|
auto script_str = env->GetStringUTFChars(script, nullptr);
|
||||||
auto length = env->GetStringUTFLength(script);
|
auto length = env->GetStringUTFLength(script);
|
||||||
auto jsvalue = js_eval_original(global_instance, global_ctx, (uintptr_t) &global_ctx->global_obj, (uint8_t *) script_str, length, "<input>", 0, 0);
|
auto jsvalue = js_eval_original(global_instance, global_ctx, (uintptr_t) &global_ctx->global_obj, (char *) script_str, length, "<eval>", 0, 0);
|
||||||
env->ReleaseStringUTFChars(script, script_str);
|
env->ReleaseStringUTFChars(script, script_str);
|
||||||
|
|
||||||
if (jsvalue.tag == JS_TAG_STRING) {
|
if (jsvalue.tag == JS_TAG_STRING) {
|
||||||
@ -157,12 +169,11 @@ namespace ComposerHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
if (!ARM64) return;
|
|
||||||
auto js_eval_ptr = util::find_signature(
|
auto js_eval_ptr = util::find_signature(
|
||||||
common::client_module.base,
|
common::client_module.base,
|
||||||
common::client_module.size,
|
common::client_module.size,
|
||||||
"00 E4 00 6F 29 00 80 52 76 00 04 8B",
|
ARM64 ? "00 E4 00 6F 29 00 80 52 76 00 04 8B" : "A1 B0 07 92 81 46",
|
||||||
-0x28
|
ARM64 ? -0x28 : -0x7
|
||||||
);
|
);
|
||||||
if (js_eval_ptr == 0) {
|
if (js_eval_ptr == 0) {
|
||||||
LOGE("js_eval_ptr signature not found");
|
LOGE("js_eval_ptr signature not found");
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <dobby.h>
|
#include <dobby.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -33,21 +32,13 @@ bool JNICALL init(JNIEnv *env, jobject clazz) {
|
|||||||
|
|
||||||
util::remap_sections(BUILD_PACKAGE);
|
util::remap_sections(BUILD_PACKAGE);
|
||||||
|
|
||||||
auto threads = std::vector<std::thread>();
|
UnaryCallHook::init(env);
|
||||||
|
AssetHook::init(env);
|
||||||
#define RUN(body) \
|
FstatHook::init();
|
||||||
threads.push_back(std::thread([&] { body; }))
|
SqliteMutexHook::init();
|
||||||
|
DuplexHook::init(env);
|
||||||
RUN(UnaryCallHook::init(env));
|
|
||||||
RUN(AssetHook::init(env));
|
|
||||||
RUN(FstatHook::init());
|
|
||||||
RUN(SqliteMutexHook::init());
|
|
||||||
RUN(DuplexHook::init(env));
|
|
||||||
if (common::native_config->composer_hooks) {
|
if (common::native_config->composer_hooks) {
|
||||||
RUN(ComposerHook::init());
|
ComposerHook::init();
|
||||||
}
|
|
||||||
for (auto &thread : threads) {
|
|
||||||
thread.join();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGD("Native initialized");
|
LOGD("Native initialized");
|
||||||
@ -94,7 +85,7 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *_) {
|
|||||||
methods.push_back({"init", "()Z", (void *)init});
|
methods.push_back({"init", "()Z", (void *)init});
|
||||||
methods.push_back({"loadConfig", "(L" BUILD_NAMESPACE "/NativeConfig;)V", (void *)load_config});
|
methods.push_back({"loadConfig", "(L" BUILD_NAMESPACE "/NativeConfig;)V", (void *)load_config});
|
||||||
methods.push_back({"lockDatabase", "(Ljava/lang/String;Ljava/lang/Runnable;)V", (void *)lock_database});
|
methods.push_back({"lockDatabase", "(Ljava/lang/String;Ljava/lang/Runnable;)V", (void *)lock_database});
|
||||||
methods.push_back({"waitForComposer", "()V", (void *) ComposerHook::waitForComposer});
|
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({"composerEval", "(Ljava/lang/String;)Ljava/lang/String;",(void *) ComposerHook::composerEval});
|
||||||
|
|
||||||
env->RegisterNatives(env->FindClass(std::string(BUILD_NAMESPACE "/NativeLib").c_str()), methods.data(), methods.size());
|
env->RegisterNatives(env->FindClass(std::string(BUILD_NAMESPACE "/NativeLib").c_str()), methods.data(), methods.size());
|
||||||
|
@ -2,6 +2,7 @@ package me.rhunk.snapenhance.nativelib
|
|||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
|
||||||
|
@Suppress("KotlinJniMissingFunction")
|
||||||
class NativeLib {
|
class NativeLib {
|
||||||
var nativeUnaryCallCallback: (NativeRequestData) -> Unit = {}
|
var nativeUnaryCallCallback: (NativeRequestData) -> Unit = {}
|
||||||
var nativeShouldLoadAsset: (String) -> Boolean = { true }
|
var nativeShouldLoadAsset: (String) -> Boolean = { true }
|
||||||
@ -62,6 +63,6 @@ class NativeLib {
|
|||||||
private external fun init(): Boolean
|
private external fun init(): Boolean
|
||||||
private external fun loadConfig(config: NativeConfig)
|
private external fun loadConfig(config: NativeConfig)
|
||||||
private external fun lockDatabase(name: String, callback: Runnable)
|
private external fun lockDatabase(name: String, callback: Runnable)
|
||||||
external fun waitForComposer()
|
external fun setComposerLoader(code: String)
|
||||||
external fun composerEval(code: String): String?
|
external fun composerEval(code: String): String?
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user