Developing a Mod Menu for il2cpp Applications
Welcome! I am pleased to share the mod menu I developed for il2cpp applications. Below are detailed instructions to guide you through the process.
Required Tools and Resources
- Personal Computer (PC)
- Native Development Kit (NDK)
- Android Studio (version 3.x)
- Apktool
- Proficiency in C++, Java, and Smali languages
Step 1: Initial Setup
Begin by cloning the Floating ModMenu repository. Open the project in Android Studio and locate the following method:
private void modMenu()
Within this method, you will add the mod menu options. Use the provided examples as a guide. In the .../FloatingModMenu/app/src/main/jni/src/main.cpp
file, create functions that will implement the hooks using the KittyMemory library. These functions should be called from the native library and linked to the switches.
Example Implementation
Java Code:
private native void godmode_on();
private void modMenu() {
addSwitch("God Mode", new SW() {
public void OnWrite(boolean isChecked) {
if (isChecked) {
godmode_on();
Toast.makeText(getBaseContext(), "God Mode is activated", Toast.LENGTH_SHORT).show();
} else {
godmode_off();
Toast.makeText(getBaseContext(), "God Mode is disabled", Toast.LENGTH_SHORT).show();
}
}
});
}
Once all necessary options are added, compile the application.
Step 2: Application Parsing and Code Injection
After adding the required options, inject the mod into the application. Decompile the application using Apktool and other tools.
Extract the application files using Apktool. Copy the files from the assets
folder (including images) and from the lib/armeabi-v7a/libKittyMemory.so
folder into the decompiled game directory.
Next, update the AndroidManifest.xml to add permission for displaying overlays and include the mod-menu service. Copy the following permission from the application's AndroidManifest.xml:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Paste this permission into the permissions section of the game's AndroidManifest.xml. Then, copy the service declaration:
<service android:enabled="true" android:exported="false" android:name="com.mrikso.modmenu.FloatingModMenuService"/>
Paste it in the game's AndroidManifest.xml before the closing </application>
tag.
Inject the mod menu by copying the smali files from the parsed application directory (e.g., smali\com\mrikso\modmenu\FloatingModMenuService...) into the game's smali folder.
Register the mod menu call and load the libKittyMemory library. Locate the main activity in the game's AndroidManifest.xml and update it as follows:
.method public Start()V
.locals 3
.line 23
const-string v0, "KittyMemory"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
.line 24
sget v0, Landroid/os/Build$VERSION;->SDK_INT:I
const/16 v1, 0x17
if-lt v0, v1, :cond_0
invoke-static {p0}, Landroid/provider/Settings;->canDrawOverlays(Landroid/content/Context;)Z
move-result v0
if-nez v0, :cond_0
.line 25
new-instance v0, Landroid/content/Intent;
new-instance v1, Ljava/lang/StringBuilder;
invoke-direct {v1}, Ljava/lang/StringBuilder;->()V
const-string v2, "package:"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual {p0}, Landroid/app/Activity;->getPackageName()Ljava/lang/String;
move-result-object v2
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-static {v1}, Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;
move-result-object v1
const-string v2, "android.settings.action.MANAGE_OVERLAY_PERMISSION"
invoke-direct {v0, v2, v1}, Landroid/content/Intent;->(Ljava/lang/String;Landroid/net/Uri;)V
.line 26
.local v0, "intent":Landroid/content/Intent;
const/16 v1, 0x7d2
invoke-virtual {p0, v0, v1}, Landroid/app/Activity;->startActivityForResult(Landroid/content/Intent;I)V
.line 27
.end local v0 # "intent":Landroid/content/Intent;
goto :goto_0
.line 28
:cond_0
new-instance v0, Landroid/content/Intent;
const-class v1, Lcom/mrikso/modmenu/FloatingModMenuService;
invoke-direct {v0, p0, v1}, Landroid/content/Intent;->(Landroid/content/Context;Ljava/lang/Class;)V
invoke-virtual {p0, v0}, Landroid/app/Activity;->startService(Landroid/content/Intent;)Landroid/content/ComponentName;
.line 30
:goto_0
return-void
.end method
.method public onActivityResult(IILandroid/content/Intent;)V
.locals 2
.param p1, "requestCode" # I
.param p2, "resultCode" # I
.param p3, "data" # Landroid/content/Intent;
.line 34
const/16 v0, 0x7d2
if-ne p1, v0, :cond_1
.line 35
const/4 v0, -0x1
if-ne p2, v0, :cond_0
.line 36
new-instance v0, Landroid/content/Intent;
const-class v1, Lcom/mrikso/modmenu/FloatingModMenuService;
invoke-direct {v0, p0, v1}, Landroid/content/Intent;->(Landroid/content/Context;Ljava/lang/Class;)V
invoke-virtual {p0, v0}, Landroid/app/Activity;->startService(Landroid/content/Intent;)Landroid/content/ComponentName;
goto :goto_0
.line 38
:cond_0
const/4 v0, 0x0
const-string v1, "Draw over other app permission not available. Closing the application"
invoke-static {p0, v1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
.line 39
invoke-virtual {p0}, Landroid/app/Activity;->finish()V
goto :goto_0
.line 42
:cond_1
invoke-super {p0, p1, p2, p3}, Landroid/app/Activity;->onActivityResult(IILandroid/content/Intent;)V
.line 44
:goto_0
return-void
.end method
In the OnCreate
method of the main activity, add:
invoke-virtual {p0}, Lcom/mrikso/modmenu/MainActivity;->Start()V
Replace com/mrikso/modmenu/MainActivity
with the correct path for your game's main activity.
Step 3: Finalizing the Mod
These steps will guide you to successfully modify your game. Good luck!
0 Comments