Requirments:
- Jailbroken Device
- TrollDecrypt
- dnSpy/IlSpy/Text Editor
- Decent C++ Knowledge
- Patience
- SilentPwn Mod Menu Template (@Batch)
Thanks to @Puddin for the interesting game.
Since I downloaded this cheat
but it didn’t work for me, I decided to do the following:
1. Decrypt the IPA
I used TrollDecrypt.
2. Dump il2cpp
I used Il2CppDumper (GUI) — needs to be built manually.
Alternatively, use Perfare’s version.
2.1 Open Assembly-CSharp.dll using dnSpy
2.2 Or just open the dump.cs file using any text editor
3. Find possible classes and methods (e.g. God Mode)
3.1 Found Hero class
3.2 Found takeDmg method (returns a float)
3.3 Used IGG - Live Offset Patcher, added Offset 0x1D7D858
3.4 Unsure how to return 0 in hex form, so I went to Godbolt and used:
int square() {
return 0;
}
The result:
square():
mov w0, 0
ret
Why return int instead of float?
Because int 0 and float 0 are practically the same in this context, but float 0.0 uses more binary space than int 0, which is just 4 bytes — simpler and efficient.
3.5 Converted that into Arm64 hex at armconverter:
00008052
C0035FD6
Used this in Live Offset Patcher. When tested, my Hero took no damage anymore. Sweet.
4. ATK Multiply
4.1 Found atk property (also returns float) in the same Hero class.
4.2 Live Offset Patcher can't do multiplications, so I used KittyMemory to hook.
Tweak Code for Multiplying ATK:
Used this template: SilentPwn
Modified it to auto-open main category (not sharing my modified version though).
float _atkValue = 100;
float (*OriginalAtk)(void *instance);
float CheatAtk(void *instance) {
if (instance != NULL && _atkValue > 0) {
return _atkValue * OriginalAtk(instance);
}
return OriginalAtk(instance);
}
void hooks(){
[Hook hook:0x1D7BC5C // Hero ATK
callback:(void *)CheatAtk
original:(void **)&OriginalAtk];
}
void setupOptions(ModMenu *menu) {
__weak ModMenu *weakMenu = menu;
[menu addSlider:@"ATK"
initialValue:100.0
minValue:1.0
maxValue:100.0
forCategory:0];
[menu addCallback:^(id value) {
_atkValue = [(NSNumber *)value floatValue];
} forKey:@"ATK" inCategory:0];
}
Also added a shortcut method in Menu.mm:
- (void)addCallback:(void (^)(id))callback forKey:(NSString *)key inCategory:(NSInteger)category {
NSString *realKey = [self keyForSetting:key inCategory:category];
NSString *callbackKey = [NSString stringWithFormat:@"%@_callback", realKey];
self.settingValues[callbackKey] = callback;
}
Why? It's easier to use than the long version.
__weak ModMenu *weakMenu = menu; //Assign weakMenu
[menu addCallback:^(id value) {
_ATKValue = [(NSNumber *)value floatValue];
} forKey:[weakMenu keyForSetting:@"ATK" inCategory:0]];
5. Monster ATK Boost
5.1 Found class mon and its atk property (same structure as Hero).
5.2 Reused the same CheatAtk and hook logic. Just added another hook:
[Hook hook:0x1D96F28 // Monster ATK
callback:(void *)CheatAtk
original:(void **)&OriginalAtk];
So now the result looks like this:
float _atkValue = 100;
float (*OriginalAtk)(void *instance);
float CheatAtk(void *instance) {
if (instance != NULL && _atkValue > 0) {
return _atkValue * OriginalAtk(instance);
}
return OriginalAtk(instance);
}
void hooks(){
[Hook hook:0x1D7BC5C callback:(void *)CheatAtk original:(void **)&OriginalAtk]; // Hero
[Hook hook:0x1D96F28 callback:(void *)CheatAtk original:(void **)&OriginalAtk]; // Monster
}
void setupOptions(ModMenu *menu) {
[menu addSlider:@"ATK"
initialValue:100.0
minValue:1.0
maxValue:100.0
forCategory:0];
[menu addCallback:^(id value) {
_atkValue = [(NSNumber *)value floatValue];
} forKey:@"ATK" inCategory:0];
}
6. Ads Bypass
6.1 Found class panel_shop_freeDia and method Awake()
In Unity, Awake() runs as soon as the class is loaded.
(Reference: https://docs.unity3d.com/6000.1/Documentation/ScriptReference/MonoBehaviour.Awake.html)
6.2 Loaded into IDA
Searched for address 0x1DC8BE4, found method panel_shop_freeDia__Awake
Press F5
Also found panel_shop_freeDia__Awake_b__18_0,
Search with Funtions Panel
and within it, found this line:
ransuzAppLovin__showRewardAd(inst, v13, 0, 0);
Seems like this is where reward ads show up.
6.3 Traced it further and AI Chat suggested modifying verse__saveIsExist to always return true.
6.4 Return True Patch
Searched for verse__saveIsExist and found address 0x1D2F77C
Used Live Offset Patcher or added to patches section of the tweak.
How to return true via godbolt using:
bool square() {
return true;
}
Output:
mov w0, 1
ret
Converted to Hex via armconverter:
20008052
C0035FD6
Added this to the tweak:
void patches() {
[Patch offset:0x1D2F77C patch:@"20 00 80 52 C0 03 5F D6"];
}
Now all ads are bypassed and rewards are instantly granted!
Pro tip: In IDA, press X on verse__saveIsExist to see all its usage points — those are all bypassed too.
7. Dev Cheats
7.1 I don’t really want to share this part but… I’ll just leave the address here for you to figure out on your own. Good luck! 😏
Ps. I used AI chat to help translate and reorder the words. Honestly, my linguistic identity has completely disappeared. I am very sad, but it's okay for everyone's understanding the tutorial.