diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f674c89..6fae9b4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: chmod +x .scripts/setup_docker.sh - name: 为 ${{ matrix.cross }} 注册米哈游通行证 run: ./gradlew build - - name: Build native (${{ matrix.cross }}) + - name: 是 (${{ matrix.cross }}) 成为米孝子的第一天捏 run: .scripts/setup_docker.sh env: CROSS: ${{ matrix.cross }} @@ -41,7 +41,7 @@ jobs: with: name: ${{ matrix.cross }} path: | - native/cmake-build-release/bin + native-old/build/bin build-jars: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 3038f52..1cce9cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ .gradle .idea *.log -/native/cmake* +/native-old/cmake* build/ *.class @@ -9,4 +9,4 @@ native-build/ temp/ .vscode -/native/build +/native-old/build diff --git a/.scripts/build.sh b/.scripts/build.sh index 545a344..b03d888 100644 --- a/.scripts/build.sh +++ b/.scripts/build.sh @@ -1,13 +1,13 @@ -cd native +cd native-old -rm -rf cmake-build-release -mkdir cmake-build-release -cd cmake-build-release +rm -rf build +mkdir build +cd build echo "开始配置构建" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CACHEFILE_DIR=$PWD -Dcross_triple=$CROSS .. echo "开始构建本机库" -cmake --build . --target native -- -j 3 +cmake --build . --target sakiko -- -j 3 ecode=$? diff --git a/.scripts/build_on_win.sh b/.scripts/build_on_win.sh index 2249c28..b1cdc15 100644 --- a/.scripts/build_on_win.sh +++ b/.scripts/build_on_win.sh @@ -1,13 +1,13 @@ -cd native +cd native-old -rm -rf cmake-build-release -mkdir cmake-build-release -cd cmake-build-release +rm -rf build +mkdir build +cd build echo "开始配置构建" cmake -DCMAKE_BUILD_TYPE=Release .. -G "MinGW Makefiles" echo "开始构建本机库" -cmake --build . --target native -- -j 3 +cmake --build . --target sakiko -- -j 3 ecode=$? diff --git a/README.md b/README.md index 5db7c1a..cab5eba 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,12 @@ Sakiko是一款跨平台的JavaHook方案,旨在提供更灵活的JVM内部Hoo - `sakiko-old-0.11.4.514-core.jar` - **旧版**运行时Java库 - `sakiko-old-0.11.4.514-launcher.jar` - **旧版**启动器包(Java Agent) - **平台-架构.zip**: - - `libnative.dll` / `libnative.so` - 本机库 + - `libsakiko.dll` / `libsakiko.so` - 本机库 使用Sakiko,您需要修改Java命令行,格式如下: ```shell -java -agentpath:/path/to/libnative.so -javaagent:/path/to/sakiko-old-0.11.4.514-launcher.jar ... +java -agentpath:/path/to/libsakiko.so -javaagent:/path/to/sakiko-old-0.11.4.514-launcher.jar ... ``` ## 克隆与构建 diff --git a/api/src/main/kotlin/Api.kt b/api/src/main/kotlin/Api.kt index 06add62..28e9755 100644 --- a/api/src/main/kotlin/Api.kt +++ b/api/src/main/kotlin/Api.kt @@ -39,14 +39,18 @@ class UnhookConfig(private val method: Method) { } class HookConfig { - var before: (() -> Unit)? = null - var after: (() -> Unit)? = null + var beforeLambda: (HookContext.() -> Unit)? = null + var afterLambda: (HookContext.() -> Unit)? = null - fun before(action: () -> Unit) { - before = action + fun before(action: HookContext.() -> Unit) { + beforeLambda = action } - fun after(action: () -> Unit) { - after = action + fun after(action: HookContext.() -> Unit) { + afterLambda = action } +} + +class HookContext(val args: Array) { + } \ No newline at end of file diff --git a/core/src/main/kotlin/Core.kt b/core/src/main/kotlin/Core.kt index a69c8ac..f80b8dc 100644 --- a/core/src/main/kotlin/Core.kt +++ b/core/src/main/kotlin/Core.kt @@ -1,6 +1,7 @@ package me.earzuchan.sakiko.core import me.earzuchan.sakiko.api.HookConfig +import me.earzuchan.sakiko.api.HookContext import me.earzuchan.sakiko.api.SakikoBaseModule import me.earzuchan.sakiko.api.SakikoBridge import me.earzuchan.sakiko.core.util.Log @@ -8,6 +9,11 @@ import java.lang.reflect.Method const val TAG = "SakikoCore" +// Karlatemp圣千古 +object KarlatempNativeCompat { + external fun initNative(): Boolean +} + object Runner { fun runModule(module: SakikoBaseModule) { module.onHook() @@ -20,10 +26,8 @@ object Runner { ensureBridge() } - private external fun helloMamba(): Boolean - private fun ensureNative() { - if (!helloMamba()) { + if (!KarlatempNativeCompat.initNative()) { throw UnsatisfiedLinkError("Native library status is not OK") } @@ -31,12 +35,12 @@ object Runner { } private fun ensureBridge() { - SakikoBridge.INSTANCE = SakikoBridgeImpl() + SakikoBridge.INSTANCE = SakikoKarlatempBridge() Log.debug(TAG, "Bridge initialized") } } -public class SakikoBridgeImpl : SakikoBridge() { +public class SakikoKarlatempBridge : SakikoBridge() { override fun hook(method: Method, config: HookConfig) { Log.debug(TAG, "Hook ${method.name}") } diff --git a/loader/build.gradle.kts b/loader/build.gradle.kts index 1de477f..5e5d218 100644 --- a/loader/build.gradle.kts +++ b/loader/build.gradle.kts @@ -29,7 +29,7 @@ tasks.register("testLoader") { mainClass.set("me.earzuchan.sakiko.loader.LoaderEntry") doFirst { - val nativeLibDir = file("${project.rootDir}/native/cmake-build-release") + val nativeLibDir = file("${project.rootDir}/native-old/build") val nativeLib = nativeLibDir.listFiles()?.firstOrNull { it.extension == "dll" || it.extension == "so" } val agentJar = tasks.named("agentJar").get().archiveFile.get().asFile diff --git a/native/CMakeLists.txt b/native-old/CMakeLists.txt similarity index 92% rename from native/CMakeLists.txt rename to native-old/CMakeLists.txt index a854a59..40df2b1 100644 --- a/native/CMakeLists.txt +++ b/native-old/CMakeLists.txt @@ -23,4 +23,4 @@ set(CMAKE_ANDROID_ARM_NEON ON) set(CMAKE_ANDROID_STL_TYPE system) add_compile_definitions(DEBUG) -add_library(native SHARED ${SRC_DIR} src/lib.cpp) +add_library(sakiko SHARED ${SRC_DIR} src/lib.cpp) diff --git a/native/includes/jni/classfile_constants.h b/native-old/includes/jni/classfile_constants.h similarity index 100% rename from native/includes/jni/classfile_constants.h rename to native-old/includes/jni/classfile_constants.h diff --git a/native/includes/jni/jawt.h b/native-old/includes/jni/jawt.h similarity index 100% rename from native/includes/jni/jawt.h rename to native-old/includes/jni/jawt.h diff --git a/native/includes/jni/jdwpTransport.h b/native-old/includes/jni/jdwpTransport.h similarity index 100% rename from native/includes/jni/jdwpTransport.h rename to native-old/includes/jni/jdwpTransport.h diff --git a/native/includes/jni/jni.h b/native-old/includes/jni/jni.h similarity index 100% rename from native/includes/jni/jni.h rename to native-old/includes/jni/jni.h diff --git a/native/includes/jni/jvmti.h b/native-old/includes/jni/jvmti.h similarity index 100% rename from native/includes/jni/jvmti.h rename to native-old/includes/jni/jvmti.h diff --git a/native/includes/jni/jvmticmlr.h b/native-old/includes/jni/jvmticmlr.h similarity index 100% rename from native/includes/jni/jvmticmlr.h rename to native-old/includes/jni/jvmticmlr.h diff --git a/native/includes/jni/unix/jni_md.h b/native-old/includes/jni/unix/jni_md.h similarity index 100% rename from native/includes/jni/unix/jni_md.h rename to native-old/includes/jni/unix/jni_md.h diff --git a/native/includes/jni/win32/bridge/AccessBridgeCallbacks.h b/native-old/includes/jni/win32/bridge/AccessBridgeCallbacks.h similarity index 100% rename from native/includes/jni/win32/bridge/AccessBridgeCallbacks.h rename to native-old/includes/jni/win32/bridge/AccessBridgeCallbacks.h diff --git a/native/includes/jni/win32/bridge/AccessBridgeCalls.c b/native-old/includes/jni/win32/bridge/AccessBridgeCalls.c similarity index 100% rename from native/includes/jni/win32/bridge/AccessBridgeCalls.c rename to native-old/includes/jni/win32/bridge/AccessBridgeCalls.c diff --git a/native/includes/jni/win32/bridge/AccessBridgeCalls.h b/native-old/includes/jni/win32/bridge/AccessBridgeCalls.h similarity index 100% rename from native/includes/jni/win32/bridge/AccessBridgeCalls.h rename to native-old/includes/jni/win32/bridge/AccessBridgeCalls.h diff --git a/native/includes/jni/win32/bridge/AccessBridgePackages.h b/native-old/includes/jni/win32/bridge/AccessBridgePackages.h similarity index 100% rename from native/includes/jni/win32/bridge/AccessBridgePackages.h rename to native-old/includes/jni/win32/bridge/AccessBridgePackages.h diff --git a/native/includes/jni/win32/jawt_md.h b/native-old/includes/jni/win32/jawt_md.h similarity index 100% rename from native/includes/jni/win32/jawt_md.h rename to native-old/includes/jni/win32/jawt_md.h diff --git a/native/includes/jni/win32/jni_md.h b/native-old/includes/jni/win32/jni_md.h similarity index 100% rename from native/includes/jni/win32/jni_md.h rename to native-old/includes/jni/win32/jni_md.h diff --git a/native/src/ArgumentNative.cpp b/native-old/src/ArgumentNative.cpp similarity index 100% rename from native/src/ArgumentNative.cpp rename to native-old/src/ArgumentNative.cpp diff --git a/native/src/CallParameter.cpp b/native-old/src/CallParameter.cpp similarity index 100% rename from native/src/CallParameter.cpp rename to native-old/src/CallParameter.cpp diff --git a/native/src/CallParameter.h b/native-old/src/CallParameter.h similarity index 100% rename from native/src/CallParameter.h rename to native-old/src/CallParameter.h diff --git a/native/src/ChangeLookupOwner.cpp b/native-old/src/ChangeLookupOwner.cpp similarity index 100% rename from native/src/ChangeLookupOwner.cpp rename to native-old/src/ChangeLookupOwner.cpp diff --git a/native/src/ClassHooks.cpp b/native-old/src/ClassHooks.cpp similarity index 100% rename from native/src/ClassHooks.cpp rename to native-old/src/ClassHooks.cpp diff --git a/native/src/ClassHooks.h b/native-old/src/ClassHooks.h similarity index 100% rename from native/src/ClassHooks.h rename to native-old/src/ClassHooks.h diff --git a/native/src/ExtNativeBridge.cpp b/native-old/src/ExtNativeBridge.cpp similarity index 100% rename from native/src/ExtNativeBridge.cpp rename to native-old/src/ExtNativeBridge.cpp diff --git a/native/src/ForceEarlyReturnNative.cpp b/native-old/src/ForceEarlyReturnNative.cpp similarity index 100% rename from native/src/ForceEarlyReturnNative.cpp rename to native-old/src/ForceEarlyReturnNative.cpp diff --git a/native/src/JvmHookFrameworkBridge.cpp b/native-old/src/JvmHookFrameworkBridge.cpp similarity index 100% rename from native/src/JvmHookFrameworkBridge.cpp rename to native-old/src/JvmHookFrameworkBridge.cpp diff --git a/native/src/JvmReturnValueImpl.cpp b/native-old/src/JvmReturnValueImpl.cpp similarity index 100% rename from native/src/JvmReturnValueImpl.cpp rename to native-old/src/JvmReturnValueImpl.cpp diff --git a/native/src/LowLevelAccess.cpp b/native-old/src/LowLevelAccess.cpp similarity index 100% rename from native/src/LowLevelAccess.cpp rename to native-old/src/LowLevelAccess.cpp diff --git a/native/src/MethodInfoImpl.cpp b/native-old/src/MethodInfoImpl.cpp similarity index 100% rename from native/src/MethodInfoImpl.cpp rename to native-old/src/MethodInfoImpl.cpp diff --git a/native/src/lib.cpp b/native-old/src/lib.cpp similarity index 59% rename from native/src/lib.cpp rename to native-old/src/lib.cpp index b3c5c31..0e798eb 100644 --- a/native/src/lib.cpp +++ b/native-old/src/lib.cpp @@ -11,11 +11,10 @@ #include #include "ClassHooks.h" - static JavaVM *javaVm = null; jvmtiEnv *jtiEnv = null; -// region fields +// 区域字段 extern jfieldID ArgumentsNativeClass$size; extern jfieldID ArgumentsNativeClass$address; @@ -25,14 +24,16 @@ extern jmethodID ArgumentsNativeClass$init; static jobject classLoaderX; static jmethodID broadcastMethodEnter; +static jmethodID ezOnMethodEnter; static jmethodID broadcastMethodExit; +static jmethodID ezOnMethodExit; static jmethodID broadcastClassPrepare; - static jmethodID methodCallImplInit; +static jmethodID hookCtxCtor; static jfieldID methodCallImpl$caller; -// endregion +// 结束区域字段 extern jobject extClassLoader; @@ -41,7 +42,8 @@ bool shouldNotHookJvmClasses = true; extern MethodHookInfo *headHookInfo; extern int methodHookCount; -struct HookInvokingInfo { +struct HookInvokingInfo +{ bool runningHook; bool exitingMethod; // onMethodExit processing bool broadcastingMethodPrepareLoad; @@ -67,43 +69,46 @@ jobject newForceEarlyReturnNative(JNIEnv *env, CallParameter *pointer); void clearForceEarlyReturnNativeAddress(JNIEnv *env, jobject); jobject new_JvmReturnValueImpl( - JNIEnv *jniEnv, jvmtiEnv *jvmti_env, - jboolean was_popped_by_exception, jobject jthr, - jvalue *pointer -); + JNIEnv *jniEnv, jvmtiEnv *jvmti_env, + jboolean was_popped_by_exception, jobject jthr, + jvalue *pointer); void release_JvmReturnValueImpl(JNIEnv *jniEnv, jobject obj); void init_MethodInfoImpl(JNIEnv *jni); jobject new_MethodInfoImpl( - JNIEnv *, jvmtiEnv *, jclass, jmethodID *, - jstring, jstring, jint -); + JNIEnv *, jvmtiEnv *, jclass, jmethodID *, + jstring, jstring, jint); void release_MethodInfoImpl(JNIEnv *jni, jobject o); // endregion -jclass getDeclaredClass(jmethodID met) { +jclass getDeclaredClass(jmethodID met) +{ jclass c; jtiEnv->GetMethodDeclaringClass(met, &c); return c; } bool shouldRunHook( - JNIEnv *jni, jmethodID metid, - int *hookCounts, jobject **allHooks -) { + JNIEnv *jni, jmethodID metid, + int *hookCounts, jobject **allHooks) +{ int hccount = 0; jobject *allHooks0 = null; auto mh = headHookInfo; - do { - if (mh->method != null) { - if (*((void **) (mh->method)) == *((void **) (metid))) { - if (allHooks0 == null) { + do + { + if (mh->method != null) + { + if (*((void **)(mh->method)) == *((void **)(metid))) + { + if (allHooks0 == null) + { allHooks0 = static_cast(malloc(methodHookCount * (sizeof(jobject)))); *allHooks = allHooks0; } @@ -115,16 +120,19 @@ bool shouldRunHook( } while (mh != null); *hookCounts = hccount; - if (hccount != 0) return true; + if (hccount != 0) + return true; *allHooks = null; free(allHooks0); return false; } -HookInvokingInfo *getHookInvokingInfo(jvmtiEnv *jvmti_env, jthread thread) { +HookInvokingInfo *getHookInvokingInfo(jvmtiEnv *jvmti_env, jthread thread) +{ HookInvokingInfo *info; jvmti_env->GetThreadLocalStorage(thread, reinterpret_cast(&info)); - if (info == null) { + if (info == null) + { info = new HookInvokingInfo; memset(info, 0, sizeof(HookInvokingInfo)); // std::cout << "NTT HII " << std::endl; @@ -133,20 +141,24 @@ HookInvokingInfo *getHookInvokingInfo(jvmtiEnv *jvmti_env, jthread thread) { return info; } -jobject findCaller(jvmtiEnv *jvmti_env, JNIEnv *jniEnv, jthread thread) { +jobject findCaller(jvmtiEnv *jvmti_env, JNIEnv *jniEnv, jthread thread) +{ jvmtiFrameInfo frameInfo[1]; jint frameCount; - //std::cout << "Caller invoke" << std::endl; + // std::cout << "Caller invoke" << std::endl; auto err0 = jvmti_env->GetStackTrace(thread, 1, 1, frameInfo, &frameCount); - //std::cout << "Caller invoke complete, " << frameCount << std::endl; - if (err0 == JVMTI_ERROR_NONE && frameCount > 0) { + // std::cout << "Caller invoke complete, " << frameCount << std::endl; + if (err0 == JVMTI_ERROR_NONE && frameCount > 0) + { jclass resp = null; - //std::cout << "Fc" << std::endl; + // std::cout << "Fc" << std::endl; jvmti_env->GetMethodDeclaringClass(frameInfo[0].method, &resp); - //std::cout << "EOF" << std::endl; + // std::cout << "EOF" << std::endl; return resp; - } else { - //std::cout << "JTI: " << err0 << std::endl; + } + else + { + // std::cout << "JTI: " << err0 << std::endl; } return null; } @@ -155,18 +167,20 @@ jobject findCaller(jvmtiEnv *jvmti_env, JNIEnv *jniEnv, jthread thread) { #pragma ide diagnostic ignored "bugprone-misplaced-widening-cast" JNICALL void onMethodEntry( - jvmtiEnv *jvmti_env, - JNIEnv *jni_env, - jthread thread, - jmethodID method -) { + jvmtiEnv *jvmti_env, + JNIEnv *jni_env, + jthread thread, + jmethodID method) +{ int hookCount; jobject *hookInstances; bool hook = shouldRunHook(jni_env, method, &hookCount, &hookInstances); - if (!hook) return; + if (!hook) + return; auto invokingInfo = getHookInvokingInfo(jvmti_env, thread); - if (invokingInfo->runningHook || invokingInfo->exitingMethod) { + if (invokingInfo->runningHook || invokingInfo->exitingMethod) + { return; } @@ -174,8 +188,10 @@ JNICALL void onMethodEntry( jclass methodOwner; jvmti_env->GetMethodDeclaringClass(method, &methodOwner); jvmti_env->GetClassLoader(methodOwner, &classLoaderZ); - if (jni_env->IsSameObject(classLoaderZ, classLoaderX)) return; - if (extClassLoader != null && jni_env->IsSameObject(classLoaderZ, extClassLoader)) return; + if (jni_env->IsSameObject(classLoaderZ, classLoaderX)) + return; + if (extClassLoader != null && jni_env->IsSameObject(classLoaderZ, extClassLoader)) + return; invokingInfo->runningHook = true; { @@ -186,7 +202,6 @@ JNICALL void onMethodEntry( jint modifiers; jvmti_env->GetMethodModifiers(method, &modifiers); - #ifdef DEBUG std::cout << "[JvmHookFramework - onMethodEntry ] " << cln << "." << methodName << methodDesc @@ -203,11 +218,14 @@ JNICALL void onMethodEntry( jclass bridgeClass; jvmti_env->GetMethodDeclaringClass(broadcastMethodEnter, &bridgeClass); - int slots = 0, size = 0; - if ((modifiers & JVM_ACC_STATIC) == 0) { slots++; } + if ((modifiers & JVM_ACC_STATIC) == 0) + { + slots++; + } size_t end = indexOf(methodDesc, ')', 1); - for (int i = 1; i < end;) { + for (int i = 1; i < end;) + { readType(methodDesc, &i, end); size++; } @@ -215,106 +233,115 @@ JNICALL void onMethodEntry( memset(parameters, 0, size * sizeof(CallParameter)); - for (int i = 1, x = 0; i < end; x++) { + for (int i = 1, x = 0; i < end; x++) + { auto t = readType(methodDesc, &i, end); - switch (t) { // NOLINT(hicpp-multiway-paths-covered) - case JVM_SIGNATURE_ARRAY: - case JVM_SIGNATURE_CLASS: { - - auto p = CallParameter(); - p.type = JVM_SIGNATURE_CLASS; - jobject obj; - jvmti_env->GetLocalObject(thread, 0, slots, &obj); - p.value = obj; - p.slot = slots; - p.edited = false; - parameters[x] = p; - - slots++; - break; - } - case JVM_SIGNATURE_BYTE: - case JVM_SIGNATURE_CHAR: - case JVM_SIGNATURE_INT: - case JVM_SIGNATURE_SHORT: - case JVM_SIGNATURE_BOOLEAN: { - - auto p = CallParameter(); - p.type = JVM_SIGNATURE_INT; - jint val; - jvmti_env->GetLocalInt(thread, 0, slots, &val); - p.iv = val; - p.slot = slots; - p.edited = false; - parameters[x] = p; - - slots++; - break; - } - case JVM_SIGNATURE_FLOAT: { - - auto p = CallParameter(); - p.type = JVM_SIGNATURE_FLOAT; - jfloat val; - jvmti_env->GetLocalFloat(thread, 0, slots, &val); - p.jf = val; - p.slot = slots; - p.edited = false; - parameters[x] = p; - - slots++; - break; - } - case JVM_SIGNATURE_LONG: { - - auto p = CallParameter(); - p.type = JVM_SIGNATURE_LONG; - jlong val; - jvmti_env->GetLocalLong(thread, 0, slots, &val); - p.lv = val; - p.slot = slots; - p.edited = false; - parameters[x] = p; - - slots += 2; - break; - } - case JVM_SIGNATURE_DOUBLE: { - auto p = CallParameter(); - p.type = JVM_SIGNATURE_DOUBLE; - jdouble val; - jvmti_env->GetLocalDouble(thread, 0, slots, &val); - p.jd = val; - p.slot = slots; - p.edited = false; - parameters[x] = p; - - slots += 2; - break; - } + switch (t) + { // NOLINT(hicpp-multiway-paths-covered) + case JVM_SIGNATURE_ARRAY: + case JVM_SIGNATURE_CLASS: + { + + auto p = CallParameter(); + p.type = JVM_SIGNATURE_CLASS; + jobject obj; + jvmti_env->GetLocalObject(thread, 0, slots, &obj); + p.value = obj; + p.slot = slots; + p.edited = false; + parameters[x] = p; + + slots++; + break; + } + case JVM_SIGNATURE_BYTE: + case JVM_SIGNATURE_CHAR: + case JVM_SIGNATURE_INT: + case JVM_SIGNATURE_SHORT: + case JVM_SIGNATURE_BOOLEAN: + { + + auto p = CallParameter(); + p.type = JVM_SIGNATURE_INT; + jint val; + jvmti_env->GetLocalInt(thread, 0, slots, &val); + p.iv = val; + p.slot = slots; + p.edited = false; + parameters[x] = p; + + slots++; + break; + } + case JVM_SIGNATURE_FLOAT: + { + + auto p = CallParameter(); + p.type = JVM_SIGNATURE_FLOAT; + jfloat val; + jvmti_env->GetLocalFloat(thread, 0, slots, &val); + p.jf = val; + p.slot = slots; + p.edited = false; + parameters[x] = p; + + slots++; + break; + } + case JVM_SIGNATURE_LONG: + { + + auto p = CallParameter(); + p.type = JVM_SIGNATURE_LONG; + jlong val; + jvmti_env->GetLocalLong(thread, 0, slots, &val); + p.lv = val; + p.slot = slots; + p.edited = false; + parameters[x] = p; + + slots += 2; + break; + } + case JVM_SIGNATURE_DOUBLE: + { + auto p = CallParameter(); + p.type = JVM_SIGNATURE_DOUBLE; + jdouble val; + jvmti_env->GetLocalDouble(thread, 0, slots, &val); + p.jd = val; + p.slot = slots; + p.edited = false; + parameters[x] = p; + + slots += 2; + break; + } } - } jclass c = getDeclaredClass(methodCallImplInit); jclass ancc = getDeclaredClass(ArgumentsNativeClass$init); auto anc = jni_env->NewObject( - ancc, - ArgumentsNativeClass$init - ); + ancc, + ArgumentsNativeClass$init); jobject thisObj; - if ((modifiers & JVM_ACC_STATIC) == 0) { + if ((modifiers & JVM_ACC_STATIC) == 0) + { jvmti_env->GetLocalInstance(thread, 0, &thisObj); - } else { + } + else + { thisObj = null; } jni_env->SetIntField(anc, ArgumentsNativeClass$size, size); - jni_env->SetLongField(anc, ArgumentsNativeClass$address, (jlong) (¶meters)); - if (thisObj != null) { + jni_env->SetLongField(anc, ArgumentsNativeClass$address, (jlong)(¶meters)); + if (thisObj != null) + { jni_env->SetObjectField(anc, ArgumentsNativeClass$thisObj, thisObj); } @@ -325,101 +352,112 @@ JNICALL void onMethodEntry( auto inf = new_MethodInfoImpl(jni_env, jvmti_env, methodOwner, &method, metName0, metDesc0, modifiers); auto call = jni_env->NewObject( - c, - methodCallImplInit, - methodOwner, metName0, metDesc0, - modifiers, anc, - forceERN, - inf - ); + c, + methodCallImplInit, + methodOwner, metName0, metDesc0, + modifiers, anc, + forceERN, + inf); auto caller = findCaller(jvmti_env, jni_env, thread); jni_env->SetObjectField(call, methodCallImpl$caller, caller); jni_env->CallStaticVoidMethod( - bridgeClass, broadcastMethodEnter, call, - (jlong) (hookInstances), - (jint) hookCount - ); + bridgeClass, broadcastMethodEnter, call, + (jlong)(hookInstances), + (jint)hookCount); clearForceEarlyReturnNativeAddress(jni_env, forceERN); release_MethodInfoImpl(jni_env, inf); - jni_env->SetLongField(anc, ArgumentsNativeClass$address, (jlong) 0); + jni_env->SetLongField(anc, ArgumentsNativeClass$address, (jlong)0); // allow onMethodExit process invokingInfo->hooks = hookInstances; - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) + { auto p = parameters[i]; - if (p.edited) { - switch (p.type) { - case JVM_SIGNATURE_INT: { - jvmti_env->SetLocalInt(thread, 0, p.slot, p.iv); - break; - } - case JVM_SIGNATURE_FLOAT: { - jvmti_env->SetLocalFloat(thread, 0, p.slot, p.jf); - break; - } - case JVM_SIGNATURE_DOUBLE: { - jvmti_env->SetLocalDouble(thread, 0, p.slot, p.jd); - break; - } - case JVM_SIGNATURE_CLASS: { - auto jo = (jobject) p.value; - jvmti_env->SetLocalObject(thread, 0, p.slot, jo); - jni_env->DeleteGlobalRef(jo); - break; - } - case JVM_SIGNATURE_LONG: { - jvmti_env->SetLocalLong(thread, 0, p.slot, p.lv); - break; - } - } - } - } - if (returnForce.edited) { - // std::cout << "RF EDX " << methodDesc[end + 1] << std::endl; - switch (methodDesc[end + 1]) { - case JVM_SIGNATURE_CLASS: - case JVM_SIGNATURE_ARRAY: { - auto o = (jobject) returnForce.value; - jvmti_env->ForceEarlyReturnObject(thread, o); - jni_env->DeleteGlobalRef(o); - break; - } + if (p.edited) + { + switch (p.type) + { case JVM_SIGNATURE_INT: - case JVM_SIGNATURE_SHORT: - case JVM_SIGNATURE_CHAR: - case JVM_SIGNATURE_BOOLEAN: - case JVM_SIGNATURE_BYTE: { - jvmti_env->ForceEarlyReturnInt(thread, returnForce.iv); + { + jvmti_env->SetLocalInt(thread, 0, p.slot, p.iv); break; } - case JVM_SIGNATURE_VOID: { - jvmti_env->ForceEarlyReturnVoid(thread); + case JVM_SIGNATURE_FLOAT: + { + jvmti_env->SetLocalFloat(thread, 0, p.slot, p.jf); break; } - case JVM_SIGNATURE_FLOAT: { - jvmti_env->ForceEarlyReturnFloat(thread, returnForce.jf); + case JVM_SIGNATURE_DOUBLE: + { + jvmti_env->SetLocalDouble(thread, 0, p.slot, p.jd); break; } - case JVM_SIGNATURE_DOUBLE: { - jvmti_env->ForceEarlyReturnDouble(thread, returnForce.jd); + case JVM_SIGNATURE_CLASS: + { + auto jo = (jobject)p.value; + jvmti_env->SetLocalObject(thread, 0, p.slot, jo); + jni_env->DeleteGlobalRef(jo); break; } - case JVM_SIGNATURE_LONG: { - jvmti_env->ForceEarlyReturnLong(thread, returnForce.lv); + case JVM_SIGNATURE_LONG: + { + jvmti_env->SetLocalLong(thread, 0, p.slot, p.lv); break; } + } + } + } + if (returnForce.edited) + { + // std::cout << "RF EDX " << methodDesc[end + 1] << std::endl; + switch (methodDesc[end + 1]) + { + case JVM_SIGNATURE_CLASS: + case JVM_SIGNATURE_ARRAY: + { + auto o = (jobject)returnForce.value; + jvmti_env->ForceEarlyReturnObject(thread, o); + jni_env->DeleteGlobalRef(o); + break; + } + case JVM_SIGNATURE_INT: + case JVM_SIGNATURE_SHORT: + case JVM_SIGNATURE_CHAR: + case JVM_SIGNATURE_BOOLEAN: + case JVM_SIGNATURE_BYTE: + { + jvmti_env->ForceEarlyReturnInt(thread, returnForce.iv); + break; + } + case JVM_SIGNATURE_VOID: + { + jvmti_env->ForceEarlyReturnVoid(thread); + break; + } + case JVM_SIGNATURE_FLOAT: + { + jvmti_env->ForceEarlyReturnFloat(thread, returnForce.jf); + break; + } + case JVM_SIGNATURE_DOUBLE: + { + jvmti_env->ForceEarlyReturnDouble(thread, returnForce.jd); + break; + } + case JVM_SIGNATURE_LONG: + { + jvmti_env->ForceEarlyReturnLong(thread, returnForce.lv); + break; + } } } free(parameters); - } invokingInfo->runningHook = false; - - } #pragma clang diagnostic pop @@ -429,12 +467,16 @@ JNICALL void onMethodExit(jvmtiEnv *jvmti_env, jthread thread, jmethodID method, jboolean was_popped_by_exception, - jvalue return_value) { + jvalue return_value) +{ auto invokingInfo = getHookInvokingInfo(jvmti_env, thread); // if (invokingInfo->runningHook) return; - if (invokingInfo->hooks == null) return; - if (*((void **) (invokingInfo->targetMethod)) != *((void **) method)) return; - if (invokingInfo->exitingMethod) { + if (invokingInfo->hooks == null) + return; + if (*((void **)(invokingInfo->targetMethod)) != *((void **)method)) + return; + if (invokingInfo->exitingMethod) + { #ifdef DEBUG jclass methodDeclaredClass; @@ -459,7 +501,6 @@ JNICALL void onMethodExit(jvmtiEnv *jvmti_env, jvmti_env->GetMethodDeclaringClass(method, &methodDeclaredClass); jvmti_env->GetClassLoader(methodDeclaredClass, &metClassloader); - #ifdef DEBUG { char *methodDesc, *methodName, *methodClassName; @@ -486,58 +527,63 @@ JNICALL void onMethodExit(jvmtiEnv *jvmti_env, auto retV = new_JvmReturnValueImpl(jni_env, jvmti_env, was_popped_by_exception, null, &return_value); auto metInfo = new_MethodInfoImpl( - jni_env, jvmti_env, methodDeclaredClass, &method, methodNameJ, methodDescJ, - modifiers - ); + jni_env, jvmti_env, methodDeclaredClass, &method, methodNameJ, methodDescJ, + modifiers); auto caller = findCaller(jvmti_env, jni_env, thread); jni_env->CallStaticVoidMethod( - bridgeClass, broadcastMethodExit, - methodDeclaredClass, methodNameJ, methodDescJ, modifiers, cc, retV, - metInfo, caller, - (jlong) invokingInfo->hooks, (jint) invokingInfo->hookCounts - ); + bridgeClass, broadcastMethodExit, + methodDeclaredClass, methodNameJ, methodDescJ, modifiers, cc, retV, + metInfo, caller, + (jlong)invokingInfo->hooks, (jint)invokingInfo->hookCounts); release_JvmReturnValueImpl(jni_env, retV); release_MethodInfoImpl(jni_env, metInfo); - - if (returnForce.edited) { + if (returnForce.edited) + { jni_env->ExceptionClear(); char *methodDesc; jvmti_env->GetMethodName(method, null, &methodDesc, null); - switch (methodDesc[indexOf(methodDesc, ')', 0) + 1]) { - case JVM_SIGNATURE_CLASS: - case JVM_SIGNATURE_ARRAY: { - auto o = (jobject) returnForce.value; - jvmti_env->ForceEarlyReturnObject(thread, o); - jni_env->DeleteGlobalRef(o); - break; - } - case JVM_SIGNATURE_INT: - case JVM_SIGNATURE_SHORT: - case JVM_SIGNATURE_CHAR: - case JVM_SIGNATURE_BOOLEAN: - case JVM_SIGNATURE_BYTE: { - jvmti_env->ForceEarlyReturnInt(thread, returnForce.iv); - break; - } - case JVM_SIGNATURE_VOID: { - jvmti_env->ForceEarlyReturnVoid(thread); - break; - } - case JVM_SIGNATURE_FLOAT: { - jvmti_env->ForceEarlyReturnFloat(thread, returnForce.jf); - break; - } - case JVM_SIGNATURE_DOUBLE: { - jvmti_env->ForceEarlyReturnDouble(thread, returnForce.jd); - break; - } - case JVM_SIGNATURE_LONG: { - jvmti_env->ForceEarlyReturnLong(thread, returnForce.lv); - break; - } + switch (methodDesc[indexOf(methodDesc, ')', 0) + 1]) + { + case JVM_SIGNATURE_CLASS: + case JVM_SIGNATURE_ARRAY: + { + auto o = (jobject)returnForce.value; + jvmti_env->ForceEarlyReturnObject(thread, o); + jni_env->DeleteGlobalRef(o); + break; + } + case JVM_SIGNATURE_INT: + case JVM_SIGNATURE_SHORT: + case JVM_SIGNATURE_CHAR: + case JVM_SIGNATURE_BOOLEAN: + case JVM_SIGNATURE_BYTE: + { + jvmti_env->ForceEarlyReturnInt(thread, returnForce.iv); + break; + } + case JVM_SIGNATURE_VOID: + { + jvmti_env->ForceEarlyReturnVoid(thread); + break; + } + case JVM_SIGNATURE_FLOAT: + { + jvmti_env->ForceEarlyReturnFloat(thread, returnForce.jf); + break; + } + case JVM_SIGNATURE_DOUBLE: + { + jvmti_env->ForceEarlyReturnDouble(thread, returnForce.jd); + break; + } + case JVM_SIGNATURE_LONG: + { + jvmti_env->ForceEarlyReturnLong(thread, returnForce.lv); + break; + } } } @@ -550,23 +596,25 @@ JNICALL void onMethodExit(jvmtiEnv *jvmti_env, } JNICALL void onThreadDeath( - jvmtiEnv *jvmti_env, - JNIEnv *jni_env, - jthread thread) { + jvmtiEnv *jvmti_env, + JNIEnv *jni_env, + jthread thread) +{ HookInvokingInfo *info; jvmti_env->GetThreadLocalStorage(thread, reinterpret_cast(&info)); - if (info != null) { + if (info != null) + { free(info); } } JNICALL void onClassPrepare( - jvmtiEnv *jvmti_env, - JNIEnv *jni_env, - jthread thread, - jclass klass -) { + jvmtiEnv *jvmti_env, + JNIEnv *jni_env, + jthread thread, + jclass klass) +{ auto hookinfo = getHookInvokingInfo(jvmti_env, thread); if (hookinfo->broadcastingMethodPrepareLoad || hookinfo->runningHook) @@ -574,9 +622,12 @@ JNICALL void onClassPrepare( jobject klassLoader; jvmti_env->GetClassLoader(klass, &klassLoader); - if (klassLoader == null)return; - if (jni_env->IsSameObject(klassLoader, classLoaderX)) return; - if (jni_env->IsSameObject(klassLoader, extClassLoader)) return; + if (klassLoader == null) + return; + if (jni_env->IsSameObject(klassLoader, classLoaderX)) + return; + if (jni_env->IsSameObject(klassLoader, extClassLoader)) + return; hookinfo->broadcastingMethodPrepareLoad = true; jclass bridgeClass; @@ -594,13 +645,15 @@ JNICALL void onClassPrepare( hookinfo->broadcastingMethodPrepareLoad = false; } -JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) { - //std::cout << "OnLoad called" << std::endl; +JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) +{ + std::cout << "OnLoad called" << std::endl; javaVm = vm; - jint jnierror = vm->GetEnv((void **) &jtiEnv, + jint jnierror = vm->GetEnv((void **)&jtiEnv, JVMTI_VERSION_1_2); - if (jnierror != JNI_OK) { + if (jnierror != JNI_OK) + { std::cerr << "Get JvmTI failed" << std::endl; return jnierror; } @@ -614,12 +667,12 @@ JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) { capabilities.can_access_local_variables = true; jint cresp = jtiEnv->AddCapabilities(&capabilities); - if (cresp != JNI_OK) { + if (cresp != JNI_OK) + { std::cerr << "AddCapabilities failed: " << cresp << std::endl; return cresp; } - jvmtiEventCallbacks callbacks; memset(&callbacks, 0, sizeof callbacks); callbacks.MethodEntry = onMethodEntry; @@ -627,22 +680,25 @@ JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) { callbacks.ThreadEnd = onThreadDeath; callbacks.ClassPrepare = onClassPrepare; - if (jtiEnv->SetEventCallbacks(&callbacks, sizeof callbacks) != JNI_OK) { + if (jtiEnv->SetEventCallbacks(&callbacks, sizeof callbacks) != JNI_OK) + { std::cerr << "Set callbacks failed" << std::endl; return JVMTI_ERROR_INTERNAL; } jtiEnv->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, null); return JVMTI_ERROR_NONE; - } // region Java Native bridges +void initNative(JNIEnv *env, jclass owner, bool isCompat = false) +{ + std::cout << "initNative called" << std::endl; -JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_initializeNative(JNIEnv *env, jclass owner) { - //std::cout << "initializeNative called" << std::endl; + std::cout << "is Compat: " << isCompat << std::endl; - if (jtiEnv == null) { + if (jtiEnv == null) + { env->GetJavaVM(&javaVm); Agent_OnLoad(javaVm, null, null); // 加载Jvmti } @@ -650,31 +706,31 @@ JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_initializ classLoaderX = env->NewGlobalRef(classLoaderX); + std::cout << "before do sth for fun" << std::endl; - // + if (isCompat) + { + std::cout << "fuck you karlatemp" << std::endl; + exit(0); + } + else { broadcastMethodEnter = env->GetStaticMethodID( - owner, "broadcastMethodEnter", - "(Lio/github/karlatemp/jvmhook/call/MethodCall;JI)V" - ); + owner, "broadcastMethodEnter", + "(Lio/github/karlatemp/jvmhook/call/MethodCall;JI)V"); broadcastMethodExit = env->GetStaticMethodID( - owner, "broadcastMethodExit", - "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ILio/github/karlatemp/jvmhook/call/MethodCall$ForceEarlyReturn;Lio/github/karlatemp/jvmhook/call/MethodReturnValue;Lio/github/karlatemp/jvmhook/call/MethodInfo;Ljava/lang/Class;JI)V" - ); + owner, "broadcastMethodExit", + "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ILio/github/karlatemp/jvmhook/call/MethodCall$ForceEarlyReturn;Lio/github/karlatemp/jvmhook/call/MethodReturnValue;Lio/github/karlatemp/jvmhook/call/MethodInfo;Ljava/lang/Class;JI)V"); broadcastClassPrepare = env->GetStaticMethodID( - owner, "broadcastClassPrepare", - "(Ljava/lang/Class;Ljava/lang/ClassLoader;)V" - ); + owner, "broadcastClassPrepare", + "(Ljava/lang/Class;Ljava/lang/ClassLoader;)V"); jclass MethodCallImpl = env->FindClass("io/github/karlatemp/jvmhook/core/MethodCallImpl"); methodCallImplInit = env->GetMethodID( - MethodCallImpl, "", - "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ILio/github/karlatemp/jvmhook/call/Arguments;Lio/github/karlatemp/jvmhook/call/MethodCall$ForceEarlyReturn;Lio/github/karlatemp/jvmhook/call/MethodInfo;)V" - ); + MethodCallImpl, "", + "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ILio/github/karlatemp/jvmhook/call/Arguments;Lio/github/karlatemp/jvmhook/call/MethodCall$ForceEarlyReturn;Lio/github/karlatemp/jvmhook/call/MethodInfo;)V"); methodCallImpl$caller = env->GetFieldID( - MethodCallImpl, "caller", "Ljava/lang/Class;" - ); - + MethodCallImpl, "caller", "Ljava/lang/Class;"); } init_ArgumentNative(env, jtiEnv); init_ForceEarlyReturnNative(env, jtiEnv); @@ -682,38 +738,47 @@ JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_initializ init_MethodInfoImpl(env); } +JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_initializeNative(JNIEnv *env, jclass owner) +{ + initNative(env, owner); +} + JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_initializeExts( - JNIEnv *env, jclass -) { + JNIEnv *env, jclass) +{ jtiEnv->SetEventNotificationMode( - JVMTI_ENABLE, - JVMTI_EVENT_CLASS_PREPARE, - null /* all threads */); + JVMTI_ENABLE, + JVMTI_EVENT_CLASS_PREPARE, + null /* all threads */); { auto e = env->ExceptionOccurred(); auto extCl = env->FindClass("io/github/karlatemp/jvmhook/core/extsys/ExtLoader"); - if (extCl == null) { + if (extCl == null) + { env->ExceptionClear(); - if (e != null) env->Throw(e); - } else { + if (e != null) + env->Throw(e); + } + else + { auto loadMet = env->GetStaticMethodID(extCl, "load", "()V"); env->CallStaticVoidMethod(extCl, loadMet); } } jtiEnv->SetEventNotificationMode( - JVMTI_ENABLE, - JVMTI_EVENT_METHOD_ENTRY, - null /* all threads */); + JVMTI_ENABLE, + JVMTI_EVENT_METHOD_ENTRY, + null /* all threads */); jtiEnv->SetEventNotificationMode( - JVMTI_ENABLE, - JVMTI_EVENT_METHOD_EXIT, - null /* all threads */); + JVMTI_ENABLE, + JVMTI_EVENT_METHOD_EXIT, + null /* all threads */); } -JNIEXPORT jobject JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_valueOfPointer - (JNIEnv *, jclass, jlong pointer, jint index) { - return (((jobject *) (void *) pointer))[(int) index]; +JNIEXPORT jobject JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_valueOfPointer(JNIEnv *, jclass, jlong pointer, jint index) +{ + return (((jobject *)(void *)pointer))[(int)index]; } // endregion @@ -721,52 +786,62 @@ JNIEXPORT jobject JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_valueO // region registerHooks JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_registerHook0( - JNIEnv *env, jclass, - jobject method, jobject hook -) { + JNIEnv *env, jclass, + jobject method, jobject hook) +{ jclass k; jmethodID met = env->FromReflectedMethod(method); jtiEnv->GetMethodDeclaringClass(met, &k); registerHook(env, k, met, hook); } -JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_unregisterHook0( JNIEnv *env, jclass, jobject method, jobject hook) { +JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_unregisterHook0(JNIEnv *env, jclass, jobject method, jobject hook) +{ jclass k; jmethodID met = env->FromReflectedMethod(method); jtiEnv->GetMethodDeclaringClass(met, &k); unregisterHook(env, k, met, hook); } -jmethodID findMetOfHook(JNIEnv *env, jclass target, jstring metName, jstring metDesc) { +jmethodID findMetOfHook(JNIEnv *env, jclass target, jstring metName, jstring metDesc) +{ auto metN = env->GetStringUTFChars(metName, null); auto metD = env->GetStringUTFChars(metDesc, null); auto mi = env->GetMethodID(target, metN, metD); - if (mi != null) return mi; + if (mi != null) + return mi; auto mx = env->GetStaticMethodID(target, metN, metD); - if (mx != null) env->ExceptionClear(); + if (mx != null) + env->ExceptionClear(); return mx; } -JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_registerHook (JNIEnv *env, jclass, jclass target, jstring metName, jstring metDesc, jobject hook) { +JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_registerHook(JNIEnv *env, jclass, jclass target, jstring metName, jstring metDesc, jobject hook) +{ auto m = findMetOfHook(env, target, metName, metDesc); - if (m == null)return; + if (m == null) + return; registerHook(env, target, m, hook); std::cout << "Register hook " << env->GetStringUTFChars(metName, null) << " - " << env->GetStringUTFChars(metDesc, null) - << " . " << (*((void **) m)) << std::endl; + << " . " << (*((void **)m)) << std::endl; } -JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_unregisterHook - (JNIEnv *env, jclass, jclass target, jstring metName, jstring metDesc, jobject hook) { +JNIEXPORT void JNICALL Java_io_github_karlatemp_jvmhook_core_Bootstrap_unregisterHook(JNIEnv *env, jclass, jclass target, jstring metName, jstring metDesc, jobject hook) +{ auto m = findMetOfHook(env, target, metName, metDesc); - if (m == null)return; + if (m == null) + return; unregisterHook(env, target, m, hook); } -extern "C" JNIEXPORT jboolean JNICALL Java_me_earzuchan_sakiko_core_Runner_helloMamba(JNIEnv *, jclass) { +extern "C" JNIEXPORT jboolean JNICALL Java_me_earzuchan_sakiko_core_KarlatempNativeCompat_initNative(JNIEnv *env, jclass owner) +{ + initNative(env, owner, true); + return JNI_TRUE; } diff --git a/native/src/lib.h b/native-old/src/lib.h similarity index 100% rename from native/src/lib.h rename to native-old/src/lib.h diff --git a/native/src/utils.cpp b/native-old/src/utils.cpp similarity index 100% rename from native/src/utils.cpp rename to native-old/src/utils.cpp diff --git a/native/src/utils.h b/native-old/src/utils.h similarity index 100% rename from native/src/utils.h rename to native-old/src/utils.h