C++:
#include <pthread.h>
#include <jni.h>
#include <src/Includes/Utils.h>
#include <src/Substrate/SubstrateHook.h>
#include "KittyMemory/MemoryPatch.h"
#include "Includes/Logger.h"
extern "C" {
JNIEXPORT jstring JNICALL
Java_uk_lgl_modmenu_FloatingModMenuService_Title(
JNIEnv *env,
jobject activityObject) {
jstring str = env->NewStringUTF("Modded by あざらし");
return str;
}
JNIEXPORT jstring JNICALL
Java_uk_lgl_modmenu_FloatingModMenuService_Heading(
JNIEnv *env,
jobject activityObject) {
std::string toast_text = "@azarasiYO";
return env->NewStringUTF(toast_text.c_str());
}
JNIEXPORT jstring JNICALL
Java_uk_lgl_modmenu_FloatingModMenuService_Icon(
JNIEnv *env,
jobject activityObject) {
//Use https://www.base64encode.org/ to encode your image to base64
std::string str = "~~~";
return env->NewStringUTF(str.c_str());
}
JNIEXPORT jint JNICALL
Java_uk_lgl_modmenu_FloatingModMenuService_IconSize(
JNIEnv *env,
jobject activityObject) {
return 70;
}
JNIEXPORT jstring JNICALL
Java_uk_lgl_modmenu_FloatingModMenuService_Toast(
JNIEnv *env,
jclass clazz) {
return env->NewStringUTF("Title title");
}
JNIEXPORT jobjectArray JNICALL
Java_uk_lgl_modmenu_FloatingModMenuService_getFeatureList(
JNIEnv *env,
jobject activityObject) {
jobjectArray ret;
// Note: Do not translate the first text
// Usage:
// Category_(text)
// Toggle_[feature name]
// SeekBar_[feature name]_[min value]_[max value]
// Spinner_[feature name]_[Items e.g. item1_item2_item3]
// Button_[feature name]
const char *features[] = {
"Toggle_ammo"};
int Total_Feature = (sizeof features /
sizeof features[0]); //Now you dont have to manually update the number everytime;
ret = (jobjectArray) env->NewObjectArray(Total_Feature, env->FindClass("java/lang/String"),
env->NewStringUTF(""));
int i;
for (i = 0; i < Total_Feature; i++)
env->SetObjectArrayElement(ret, i, env->NewStringUTF(features[i]));
return (ret);
}
bool ammo = false;
bool ammo2 = false;
struct My_Patches {
MemoryPatch a;
// etc...
} my_cool_Patches;
const char *libName = "libil2cpp.so";
JNIEXPORT void JNICALL
Java_uk_lgl_modmenu_FloatingModMenuService_Changes(
JNIEnv *env,
jobject activityObject,
jint feature,
jint value) {
__android_log_print(ANDROID_LOG_VERBOSE, "Mod Menu", "Feature: = %d", feature);
__android_log_print(ANDROID_LOG_VERBOSE, "Mod Menu", "Value: = %d", value);
switch (feature) {
case 0:
ammo = !ammo;
ammo2 = !ammo2;
break;
}
}
}
bool NewWeaponHookInitialized = false;
void(*old_NewWeapon)(void *instance);
void NewWeapon(void *instance) {
if (instance != NULL) {
if (!NewWeaponHookInitialized) {
//Check if this hook initialized. If so log
NewWeaponHookInitialized = true;
LOGI("GameManager_LateUpdate hooked");
if (ammo) {
*(int *) ((uint64_t) instance + 0x64) = 999;
}
if (ammo2) {
*(int *) ((uint64_t) instance + 0x60) = 999;
//Your code here
}
old_NewWeapon(instance);
}
}
}
void *hack_thread(void *) {
LOGI("I have been loaded. Mwuahahahaha");
do {
sleep(1);
} while (!isLibraryLoaded(libName));
LOGI("I found the il2cpp lib. Address is: %p", (void *) findLibrary(libName));
LOGI("Hooking GameManager_LateUpdate");
MSHookFunction((void *) getAbsoluteAddress(libName, 0x771BB8), (void *) NewWeapon,
(void **) &old_NewWeapon);
return NULL;
}
I want to do MSHookFunction, but I can't, why? I do not know the cause