Jump to content

H5GG Enhanced Menu Tutorial - JSPlug-in Advanced


Happy Secret

37 posts in this topic

Recommended Posts

With last JSPlug-in 101 tutorial, I am sure there are more people start enjoying the power of H5GG Enhanced Menu. 

In last tutorial, I have covered 
1. How to use 3-Lines of code to create a Cheat
2. How to use Unity Wrapper (directly access Fields of any Unity User Object) to create very readable and easy to understand Cheat
3. How to use JSPlug-in Pre-build Mod Menu Template to create powerful Cheat 

Spoiler

This time, I would like to cover more advanced use JSPlug-in of this powerful H5GG Enhanced Menu. 

Feature 1) Direct Unity Method Access

Spoiler

Scenario a) You Probably had came across game that has Obscured or protected value, this make hacking them very difficult to cheat. 
JSPlug-in's solution to this is, update game value using game's own function/method

Spoiler
var script = initializeUnitySupport();
var aryObj = script.call("findUnityObjectOfType", ["$Gameplay", true]);
let Gameplay = new UnityObject(aryObj[0]);
Gameplay.loadMethods(["void AddGold(int32)","void set_AddExp(int32)"]);
Gameplay.AddGold(1000);
Gameplay.set_AddExp(1000);


Scenario b) You  probably had came across game cheat that create object (money, item, enemy, skill) from nowhere. How does it work? 
JSPlug-in's solution to this is, also using game's own function/method

Spoiler
var script = initializeUnitySupport();
var aryObj = script.call("findUnityObjectOfType", ["$Gameplay", true]);
let Gameplay = new UnityObject(aryObj[0]);
Gameplay.loadMethods(["void CreateJam(int32,vector,int32,int32,vector4,int32)"]);
let vector = {x:0, y:0, z:0};
let vector4 = {w:0, x:0, y:0, z:0};
Gameplay.CreateJam(1,vector,5,5000,vector4,202104);//Create Experience Drop from nowhere

Scenario c) You  probably had came across game cheat that use in-game build-in Cheat feature like a GameMaster(GM). How does it work? 
JSPlug-in's solution to this is, again using game's own function/method

Spoiler
var script = initializeUnitySupport();
var aryObj = script.call("findUnityObjectOfType", ["$UIManager",true]);
var unityUIManager = new UnityObject(aryObj[0]);
unityUIManager.loadMethods(["void Cheat_OpenItemTestPanel()"]);
unityUIManager.Cheat_OpenItemTestPanel();

Now, you can see how powerful of this Feature is. You can do all kind of crazy things as long as you understand how the game work. (Static Analysis)

Tell me more about your innovative use of this Features in comments below. 

Feature 2) Direct Access to Unity Array, List, Dictionary

Spoiler

Scenario a) You Probably aware, a lot of the game store Character/Player/Item Stat in Unity Array, List, Dictionary. Are there way for us to easily access these data? 
JSPlug-in's solution to this is, wrapping them with UnityArray, UnityList, UnityDictionary

UnityArray: 

Spoiler
let RewardListAry = new UnityArray(GameData.m_RewardList)
for (let j=0;j<RewardListAry.size();j++){
	let Reward = new UnityObject(RewardListAry.get_Item(j))
	Reward.loadFields(["reward_list_id","item_type","prob","item_value","desc"])
	console.log(Reward.reward_list_id + "," + Reward.item_type + "," + Reward.prob + "," + Reward.item_value + "," + Reward.desc)
}

UnityList:

Spoiler
let JamList = new UnityList(Gameplay.m_JamList)
for (let j=0;j<JamList.size();j++){
	let Jam = new UnityObject(JamList.get_Item(j))
	Jam.loadFields(["m_ItemType"])
	if (Jam.m_ItemType ==1) Jam.m_ItemType = 20; //Change all basic exp drop into Magnet item
}

UnityDictionary:

Spoiler
//Demostrate access possibility outside UnityObject 
let tableHeroEnhanceDictionary = new UnityDictionary(readPtr(Number(tableHeroEnhanceObj) + Number(gUnityClasses.ExcelSheetData$TableHeroEnhance._dicData.offset)))
for (i = 0; i < tableHeroEnhanceDictionary.size(); i++) {
	let tmpAddr = tableHeroEnhanceDictionary.get_Item(i);
	if (tmpAddr == 0x0) continue; //Sometime dictionary/list could be fixed length, you need to manually exclude invalid entries 
	let statValueAddr = Number(tmpAddr) + Number(hidden_ExcelSheetData$TableHeroEnhance__StatValue_offset) //using offset label
	writeFloat(statValueAddr, 333); //Change every Stat value to 333
}

Scenario b) Some competitive game like sport game, they might have teaming concept. There usually has a list somewhere either in Array / List / Dictionary format. In case, you want to de-link your cheat from Ally/Enemy team. It would be easier to get only Ally/Enemy team object to cheat. How does it work? 

JSPlug-in's solution to this is, also using UnityArray, UnityList, UnityDictionary 

Spoiler
let MonsterList = new UnityList(Gameplay.m_MonsterList)
for (let j=0;j<MonsterList.size();j++){
	let Monster = new UnityObject(MonsterList.get_Item(j))
	//Do whatever you want to do with it
}

*Same Apply for Ally

Scenario c) We like to cheat skill cool time. However, there not always some global timer easy for us to find.  At least in general it is more easy to find the Skill list, and we can cheat max cool time directly.

 JSPlug-in's solution to this is, again using UnityArray, UnityList, UnityDictionary

Spoiler
let SkillAry = new UnityArray(Character.m_Skill)
for (let j=0;j<SkillAry.size();j++){
	let Skill = new UnityObject(SkillAry.get_Item(j))
	Skill.loadFields(["m_CoolTime"])
	Skill.m_CoolTime=0.5
}

Now, you can see how powerful of this Feature is. You can do all kind of crazy things as long as you understand how the game work. (Static Analysis)

Tell me more about your innovative use of this Features in comments below. 

Feature 3) Dynamic/Runtime/Late Binding of JSPlug-in for flexibility (Javascript Runtime) 

Spoiler

Scenario a) Some games like to mix all stat under one Array or List or Dictionary. However, while we want to apply cheat we obviously want to handle them differently. Are there way for us to apply different cheat on them differently while we can trigger them in the similar way?
JSPlug-in's solution to this is, leveraging the power of Dynamic/Runtime/Late Binding characteristic of Javascript.

Spoiler
let ItemStatAry = new UnityArray(Number(Gameplay.m_ItemStat),'int32')
ItemStatAry.addPower = function(value){
  this.set_Item(0,this.get_Item(0)+value)//power
}
ItemStatAry.addHP = function(value){
  this.set_Item(1,this.get_Item(1)+value)//HP
}
ItemStatAry.addDefense = function(value){
  this.set_Item(2,this.get_Item(2)+value)//Defense
}
ItemStatAry.setSpeed = function(value){
  this.set_Item(3,value)//speed
}

What we have done above is creating new function/method for the UnityArray object at runtime and use them to access individual Stat separately. With this we can trigger them in similar way.

Spoiler
ItemStatAry.addPower(10); 
ItemStatAry.addHP(100); 
ItemStatAry.addDefense(10); 
ItemStatAry.setSpeed(100);

You may ask why we want want make trigger them in similar way. Why is it important?

If you remember in last Tutorial, we have introduced a Mod Menu Template that make creating Mod Menu as simple as 5 simple steps
One of the key requirement is, the object must have field can update directly / method that can call directly with cheat value. 
So, after the above processing, they can now be part of the Mod Menu Template now.

Here is another example

Spoiler
//For primitive type UnityArray, you need to explicitly tell the data type, or it will default as pointer type
let ImaeRecoveryValueAry = new UnityArray(Const.ImaeRecoveryValue,'int32') 
ImaeRecoveryValueAry.setAll = function(value){
	for (let j=0;j<this._size;j++){
		this.set_Item(j,value)
	}
}

We also try to wrap the primitive UnityArray update with a setAll function. The objective is also make it usable in Mod Menu Template

Now, you can see how powerful of this Feature is. You can do all kind of crazy things as long as you understand how the game work. (Static Analysis)

Tell me more about your innovative use of this Features in comments below. 

Feature 4) Mixing all together with revised advanced menu (SELFLIST, ENEMYLIST, reference to field, reference to return value of method call)

Spoiler

In last JSPlug-in 101 tutorial, we have introduced a Mod Menu Template design specifically to leverage the power of H5GG Enhanced Menu. 


With 5 Simple Steps, you should able to create simple Cheat Menu for Simple Unity Games
This is obviously not for all Unity Games.
Some Unity Games can't be cheated without Patching / Hooking.

The typical way of game cheating are using patch / hook to change the behaviour of the game. We find method/instruction that driving the behaviour we want to cheat and change it the way we want. Say,
changing the way how game process Currency in order to produce Currency cheat.  
- changing the way how game calculate damage in order to produce a Damage Multiplier, as well as creating God mode. 
- changing the way how game handle count down, in order to produce various Time / Cool Down related cheat
These are
great way to produce cheat. But they are not Non-Jailbroken friendly. Thanks to the latest JIT update of Sideloadly. It makes this a lot easier for Non-Jailbroken. 
With H5GG Enhanced Menu on Unity game, we are going a very different direction. It is pretty much 
like the legacy cheat engine way of changing in-memory data to create the cheat. The key different is, we have much smarter way to locate the object/field in memory to cheat. With this new approach, we can produce cheat that we do not need to create update per game version. The cheat (script) itself always work across version. It will only fail when game developer target them explicitly, changing the logic, detecting their existence. It saves a lot time, and this is pretty much the same happening to Cheat Engine / Game Guardian scripting. 

As H5GG Enhanced Menu advancing over time, the Mod Menu Template also got it progressive improvement. It is now more flexible and able to cover more different scenarios. That 5 Simple Steps remains that 5 Simple Steps, but we are providing more options/tools in handling different scenarios

Mod Menu Template updated, using IMAE Guardian Girl cheat as example (suggest you read the last JSPlug-in 101 tutorial on this Mod Menu Template before continue)

Spoiler
/*
	H5GG Plugin Mod Menu logic should enable easier Mod Menu development for non-jailbroken. It preserve existing H5GG UI and features, while adding new cheat menu.
	Cheat implemented using a patch free approach, the game binary does not required to patch. 
	
	Contribute by Happy Secret on iOSGods (2023)
*/
//gIl2cppInit = false;
var script = initializeUnitySupport();

//[STEP 1][MODIFY] Define what you want to cheat with the script
var cheats = {
	gold: ["Gameplay", "m_Gold", "10", "SELF", "ON", "AddGold"],
	Exp: ["Gameplay", "m_AddExp", "1000", "SELF", "ON", "set_AddExp"],
	AddPower: ["ItemStats", "notUsed", "10", "SELF", "ON", "addPower"],
	AddMaxHP: ["ItemStats", "notUsed", "10", "SELF", "ON", "addHP"],
	AddDefense: ["ItemStats", "notUsed", "10", "SELF", "ON", "addDefense"],
	SetSpeed: ["ItemStats", "notUsed", "100", "SELF", "ON", "setSpeed"],
	DropItemTypes: ["Jams", "m_ItemType", 20, "SELFLIST", "ON", "DIRECT"],//12=30power,20=magnet
	levelUpInvincibleTime: ["Const", "LevelUpInvincibleTime", "HUNDRED", "SELF", "ON", "DIRECT"],
	ImaeRecovery: ["ImaeRecoveryValues", "notUsed", "HUNDRED", "SELF", "ON", "setAll"],
	adsCoolTime: ["Const", "AdsCoolTime", "TEN", "SELF", "ON", "DIRECT"],
	specialSkillCoolTime: ["SpecialSkill", "m_CoolTime", "ONE", "SELF", "ON", "DIRECT"],
};

var intervalID;
var aryObj
var cheatState = false;
var cheatMode = "recurrent";
var recurrentInterval = 1200; //try not to be small than 1000, prevent system freeze

function toogleCheat() {
	cheatState = !cheatState;
	document.getElementById("applybutton").textContent = ' Toggle OFF ';
	document.getElementById("applybutton").style.backgroundColor = '#E8E8E850';

	if (cheatState) {
		intervalID = setInterval(function () {
			if (cheatState) {
				try {
					script = initializeUnitySupport();
					//[STEP 2][MODIFY]Change the root object of interest, which should able to link to your other cheat object
					aryObj = script.call("findUnityObjectOfType", ["$Gameplay", true]);
				} catch (e) {
					//reset Unity Support
					gIl2cppInit = false;
					var script = initializeUnitySupport();
					appendLog("Unity support crashed and reset complete");
				}

				if (!aryObj) {
					appendLog("Cannot find object to cheat. Engine stopped.");
					cheatState = false;
					document.getElementById("applybutton").textContent = ' Toggle Cheat ';
					return;
				} else if (aryObj.length == 0) {
					appendLog("Cheat waiting for core object.");
					return;
				}

				for (let i = 0; i < aryObj.length; i++) {
					//[STEP 3][MODIFY]Create the Unity User Object wrapper object from a Root Object instance address, and enable the linking field access (prepare core object for delink / filtering) 
					let Gameplay = new UnityObject(aryObj[i]);

					Gameplay.loadFields(['m_GameData', "m_JamList", 'm_Player', "m_ItemSpec", "m_ItemStat"])
					Gameplay.loadMethods(["void AddGold(int32)", "void set_AddExp(int32)", "single get_MonitorPower()", "single get_MonitorMaxPower()"]);
					//debugInfo("Gameplay (" + aryObj[i].toString(16) + ") with player:" + Gameplay.m_Player, [aryObj[i]])

					//[STEP 4][MODIFY]Define the scope of the cheat, certain cheat we do not want to globally apply. (Filtering condition or Grouping)
					let isSelf = true//BattleCharacter.CurrentUnitType==100? true:false;
					let cheatObj = {};
					//End prepare core object for delink / filtering here

					//[STEP 5][MODIFY]Preparing all cheat objects required here
					cheatObj["Gameplay"] = Gameplay

					let GameData = new UnityObject(Gameplay.m_GameData)
					GameData.loadFields(["m_Const"])
					let Const = new UnityObject(GameData.m_Const)
					Const.loadFields(["LevelUpInvincibleTime", "AdsCoolTime", "ImaeRecoveryValue"])

					cheatObj["Const"] = Const

					let ImaeRecoveryValueAry = new UnityArray(Const.ImaeRecoveryValue, 'int32')
					ImaeRecoveryValueAry.setAll = function (value) {
						for (let j = 0; j < this._size; j++) {
							this.set_Item(j, value)
						}
					}
					cheatObj["ImaeRecoveryValues"] = ImaeRecoveryValueAry

					let JamList = new UnityList(Gameplay.m_JamList)
					//JamList.export()
					let JamAry = [];
					for (let j = 0; j < JamList.size(); j++) {
						let Jam = new UnityObject(JamList.get_Item(j))
						Jam.loadFields(["m_ItemType"])
						if (Jam.m_ItemType == 1) JamAry.push(Jam)
						else debugInfo("New ItemType:" + Jam.m_ItemType, [JamList.get_Item(j)])
					}
					cheatObj["Jams"] = JamAry

					let Character = new UnityObject(Gameplay.m_Player)
					Character.loadFields(["m_SelectSpecialSkill", "m_Skill"])
					let SpecialSkill = new UnityObject(Character.m_SelectSpecialSkill)
					SpecialSkill.loadFields(["m_CoolTime"])

					cheatObj["SpecialSkill"] = SpecialSkill

					let ItemStatAddr = Gameplay.m_ItemStat
					let ItemStatAry = new UnityArray(Number(ItemStatAddr), 'int32')

					ItemStatAry.addPower = function (value) {
						this.set_Item(0, this.get_Item(0) + value)//power
					}
					ItemStatAry.addHP = function (value) {
						this.set_Item(1, this.get_Item(1) + value)//HP
					}
					ItemStatAry.addDefense = function (value) {
						this.set_Item(2, this.get_Item(2) + value)//Defense
					}
					ItemStatAry.setSpeed = function (value) {
						this.set_Item(3, value)//speed
					}
					cheatObj["ItemStats"] = ItemStatAry

					//End prepare cheat object
					for (var prop in cheats) {
						if (Object.prototype.hasOwnProperty.call(cheats, prop)) {
							let obj;
							let addr;
							let oldValue = 0;
							if (isNaN(cheats[prop][2])) {
								switch (cheats[prop][2]) {
									case "ONE":
										cheats[prop][2] = 1
										break;
									case "ZERO":
										cheats[prop][2] = 0
										break;
									case "TEN":
										cheats[prop][2] = 10
										break;
									case "HUNDRED":
										cheats[prop][2] = 100
										break;
									case "NIL":
										cheats[prop][2] = -987654321
										break;
								}
							}

							//check current cheat item relevant to this record and turned ON
							let shouldApplyCheatItem = false
							//this cover both SELF and SELFLIST
							if (isSelf && cheats[prop][3].indexOf("SELF") != -1 && cheats[prop][4] == "ON") {
								//this cover both SELF and SELFLIST
								shouldApplyCheatItem = true
							} else if (isSelf == false && cheats[prop][3].indexOf("ENEMY") != -1 && cheats[prop][4] == "ON") {
								//this cover both ENEMY and ENEMYLIST
								shouldApplyCheatItem = true
							}

							if (!shouldApplyCheatItem) continue //skip current cheat on this object

							let value;
							if (isNaN(cheats[prop][2]) && cheats[prop][2].indexOf(".") != -1) {
								if (cheats[prop][2].indexOf("()") != -1) //check if it is a method call
									value = cheatObj[cheats[prop][2].split(".")[0]][cheats[prop][2].split(".")[1].split("()")[0]]()
								else
									value = cheatObj[cheats[prop][2].split(".")[0]][cheats[prop][2].split(".")[1]]
							} else {
								if (isNaN(cheats[prop][2]) && cheats[prop][2].indexOf("()") != -1) //check if it is a method call
									value = cheatObj[cheats[prop][0]][cheats[prop][2].split("()")[0]]()
								else if (isNaN(cheats[prop][2]))
									value = cheatObj[cheats[prop][0]][cheats[prop][2]]
								else
									value = cheats[prop][2]
							}

							value = Number(value)

							//case for Non-list, covering both SELF or ENEMY, make it store like an array
							//so that one set of logic apply for both	
							if (!Array.isArray(cheatObj[cheats[prop][0]]))
								cheatObj[cheats[prop][0]] = [cheatObj[cheats[prop][0]]]

							let cheatObjAry = cheatObj[cheats[prop][0]]

							for (let i = 0; i < cheatObjAry.length; i++) {
								if (cheats[prop][5] == "DIRECT")
									cheatObjAry[i][cheats[prop][1]] = value
								else {
									if (value == -987654321)
										cheatObjAry[i][cheats[prop][5]]()
									else 
										cheatObjAry[i][cheats[prop][5]](value)
								}
							}

						}
					}//end For cheat item
				}//end For core object list
				appendLog("Cheat applied successfully");
			} else {
				clearInterval(intervalID);
			}
		}, recurrentInterval);
	} else {
		//code will stop on next coming iteration
		document.getElementById("applybutton").textContent = ' Toggle Cheat ';
		appendLog("Cheat stopped");
	}

	if (cheatMode != "recurrent") clearInterval(intervalID);
}

//[OPTIONAL STEP][ADD] Define your own complex or one time cheat by extending with custom logic
function triggerSkillCoolTimeCheat() {
	try {
		var GameplayObjs = script.call("findUnityObjectOfType", ["$Gameplay", true]);
		var GameplayAddr;
		var Gameplay
		for (let i = 0; i < GameplayObjs.length; i++) {
			GameplayAddr = GameplayObjs[i]
			Gameplay = new UnityObject(GameplayAddr)

			Gameplay.loadFields(['m_Player'])
			let Character = new UnityObject(Gameplay.m_Player)
			Character.loadFields(["m_Skill"])
			let SkillAry = new UnityArray(Character.m_Skill)
			//let Skills =[];
			for (let j = 0; j < SkillAry.size(); j++) {
				let Skill = new UnityObject(SkillAry.get_Item(j))
				Skill.loadFields(["m_CoolTime"])
				Skill.m_CoolTime = 0.5
			}
			appendLog("Apply Skill CoolTime successful")
		}

	} catch (e) {
		debugInfo("Error in running JSPlugin on GamePlay:" + GameplayAddr
			+ JSON.stringify(e, Object.getOwnPropertyNames(e)) + ":" + e.toString(), [GameplayAddr]);
	}
}

//[OPTIONAL STEP][ADD] Define your own complex or one time cheat by extending with custom logic
function triggerDropItemCheat() {
	try {
		var GameplayObjs = script.call("findUnityObjectOfType", ["$Gameplay", true]);
		var GameplayAddr;
		var Gameplay
		for (let i = 0; i < GameplayObjs.length; i++) {
			GameplayAddr = GameplayObjs[i]
			Gameplay = new UnityObject(GameplayAddr)

			Gameplay.loadFields(['m_Player', 'm_GameData'])
			Gameplay.loadMethods(["void CreateJam(int32,vector,int32,int32,vector4,int32)"]);
			let Character = new UnityObject(Gameplay.m_Player)
			Character.loadFields(["m_Skill", "m_Head"])

			let position = script.call("transform_get_position", [Number(Character.m_Head)]);
			let position2 = { w: 0, x: position.x, y: position.y, z: position.z }
			Gameplay.CreateJam(1, position, 5, 5000, position2, 202104)
			Gameplay.CreateJam(1, position, 20, 0, position2, 400002)
			Gameplay.CreateJam(1, position, 40, 0, position2, 600002)
			Gameplay.CreateJam(1, position, 34, 0, position2, 500503)
			appendLog("Current Pos:" + JSON.stringify(position));
			//Gameplay.export();

			/*****Download RewardList******
			let GameData = new UnityObject(Gameplay.m_GameData)
			GameData.loadFields(["m_RewardList"])
			let RewardListAry = new UnityArray(GameData.m_RewardList)
			//RewardListAry.export()
			
			let RewardDetails ="reward_list_id,item_type,prob,item_value,desc\n"
			for (let j=0;j<RewardListAry.size();j++){
				let Reward = new UnityObject(RewardListAry.get_Item(j))
				Reward.loadFields(["reward_list_id","item_type","prob","item_value","desc"])
				RewardDetails = RewardDetails + Reward.reward_list_id+","+Reward.item_type+","+Reward.prob+","+Reward.item_value+","+Reward.desc+ "\n"
			}
			appendLog(script.call("writeDataToFile",["mydownload.txt", RewardDetails]))
			*********/

			appendLog("Drop Item done")
		}

	} catch (e) {
		debugInfo("Error in running JSPlugin on GamePlay:" + GameplayAddr
			+ JSON.stringify(e, Object.getOwnPropertyNames(e)) + ":" + e.toString(), [GameplayAddr]);
	}
}

/* Add button on H5GG UI to open the Cheat UI, if it does not exist */
if ($("#cheatpluginmodmenu").length == 0) {
	var btn = $('<button id="cheatpluginmodmenu">Cheat</button>');
	btn.attr("credit", "Happy Secret");
	btn.click(function () {
		$("#cheatpluginpage").show();
	});
	//backward compatible with standard H5GG menu
	if ($("#frontview").length == 0) {
		$('#results_count').after(btn);
	} else {
		$("#frontview").append(btn);
	}
}

/* Create the Cheat UI Layer, if it does not exist */
if ($("#cheatpluginpage").length == 0) {
	var popup_pixelfancheat_html = $('<div id="cheatpluginpage"  style="background-color: #FDFDFD; width:100%; height:100%; position:absolute; left:0; top:0; border:1px solid #B8B8B880; border-radius: 5px; padding: 0px; z-index: 99999;-webkit-user-select: all;-webkit-touch-callout: default;"></div>');
	$(document.body).append(popup_pixelfancheat_html);
}

/* Generate Clean Cheat Menu UI */
var html = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cheat by Happy Secret';
html += '<br><div style="float:right; font-size:16px; font-family: Arial, sans-serif;" onclick="closecheatpluginpage()">&nbsp;X&nbsp;</div><br>';

/* Prepare Cheat Item */
for (var prop in cheats) {
	if (Object.prototype.hasOwnProperty.call(cheats, prop)) {
		if (isNaN(cheats[prop][2]))
			html += '<label><input name="' + prop + '"type="checkbox" ' + '" onchange="checkchange(this)" checked/>' + prop + '<output>(' + cheats[prop][4] + ')</output></label>';
		else
			html += '<label><input name="' + prop + '"type="range" min="0" max="' + cheats[prop][2] * 2 + '" value="' + cheats[prop][2] + '" style="width:50%" onchange="rangechange(this)" />' + prop + '<output>(' + cheats[prop][2] + ')</output></label><br>';
	}
}

html += '<p align="center"><button onclick="toogleCheat()" id="applybutton">&nbsp;Toggle Cheat&nbsp;</button>';
html += '<button onclick="triggerSkillCoolTimeCheat()" id="triggerbutton">&nbsp;Skill CoolTime Cheat&nbsp;</button>';
html += '<button onclick="triggerDropItemCheat()" id="triggerbutton">&nbsp;Drop Item Cheat&nbsp;</button>';
html += '</hr><div id="cheatpluginpagelog" class="scrollbar" ></div>';


$("#cheatpluginpage").html(html);
$("#cheatpluginpage").hide();

function closecheatpluginpage() {
	$("#cheatpluginpage").hide();
}

function rangechange(input) {
	cheats[input.name][2] = Number(input.value);

	input.nextElementSibling.value = '(' + input.value + ')';
	//input.previousElementSibling.value = '(' + input.value + ')';

	//Change Apply Button Color to remind user to press Apply
	document.getElementById("applybutton").style.backgroundColor = 'yellow';
}

function checkchange(input) {
	cheats[input.name][4] = input.checked ? "ON" : "OFF"

	input.nextElementSibling.value = '(' + cheats[input.name][4] + ')';

	//Change Apply Button Color to remind user to press Apply
	document.getElementById("applybutton").style.backgroundColor = 'yellow';
}

/* Create Cheat Log */
function appendLog(msg) {
	var oldmsg = $("#cheatpluginpagelog").html();
	if (oldmsg.length > 300) oldmsg = "";
	oldmsg = getCurTime() + ' - ' + msg + '<br>' + oldmsg;
	$("#cheatpluginpagelog").html(oldmsg);
}

 

Let me explain the key 5 Steps again here

STEP 1) Define what you want to cheat with the script

Spoiler
var cheats = {
	gold: ["Gameplay", "m_Gold", "10", "SELF", "ON", "AddGold"],
	Exp: ["Gameplay", "m_AddExp", "1000", "SELF", "ON", "set_AddExp"],
	AddPower: ["ItemStats", "notUsed", "10", "SELF", "ON", "addPower"],
	AddMaxHP: ["ItemStats", "notUsed", "10", "SELF", "ON", "addHP"],
	AddDefense: ["ItemStats", "notUsed", "10", "SELF", "ON", "addDefense"],
	SetSpeed: ["ItemStats", "notUsed", "100", "SELF", "ON", "setSpeed"],
	DropItemTypes: ["Jams", "m_ItemType", 20, "SELFLIST", "ON", "DIRECT"],//12=30power,20=magnet
	levelUpInvincibleTime: ["Const", "LevelUpInvincibleTime", "HUNDRED", "SELF", "ON", "DIRECT"],
	ImaeRecovery: ["ImaeRecoveryValues", "notUsed", "HUNDRED", "SELF", "ON", "setAll"],
	adsCoolTime: ["Const", "AdsCoolTime", "TEN", "SELF", "ON", "DIRECT"],
	specialSkillCoolTime: ["SpecialSkill", "m_CoolTime", "ONE", "SELF", "ON", "DIRECT"],
};

- gold/Exp/AddPower/etc are the label of the UI component (e.g. Slider or Checkbox) on the Cheat Menu
- Inside the [ ] bracket, there are 6 cheat params
  Param1 (e.g. "GamePlay") is the name of the class object/array of object that hold the field you want to change or hold the method you want to call
  Param2 (e.g. "m_Gold") is the field name to change
  Param3 (e.g. 10 or "HUNDRED" or "Any Field Name" or "ClassObjectName.MethodName()") is the value to change. Use "ONE"/"TEN"/"HUNDRED" for cheat that only need to enable/disable without a numeral value.
        Field Name or Method name, essentially mean the value to be retrived somewhere.
  Param4 (e.g. "SELF" or "ENEMY" or "SELFLIST" or "ENEMYLIST") is for de-link, it used to tell which group of object should apply this cheat on (Filtering condition)
  Param5 (e.g. "ON" or "OFF") is a switch to turn on and off the cheat
  Param6 (e.g. "DIRECT" Or "AddGold") is used to indicate it is an direct update or a method need to call to trigger the update. (obfuscated field)

STEP 2) Change the root object of interest, which should able to link to your other cheat object

Spoiler
aryObj = script.call("findUnityObjectOfType", ["$Gameplay", true]);

Change the “$Gameplay” to an object class that you can find object link with Unity Static Analyzer. You need to full long name with those $.

STEP 3) Create the Unity User Object wrapper object from a Root Object instance address, and enable the linking field access

Spoiler
let Gameplay = new UnityObject(aryObj[i]);
Gameplay.loadFields(['m_GameData', "m_JamList", 'm_Player', "m_ItemSpec", "m_ItemStat"])
Gameplay.loadMethods(["void AddGold(int32)", "void set_AddExp(int32)", "single get_MonitorPower()", "single get_MonitorMaxPower()"]);

Here create the base Unity Object, you just need to name it and identify those Fields/Methods in this object you are going to use.

STEP 4) Define the scope of the cheat, certain cheat we do not want to globally apply. (Filtering condition or Grouping)

Spoiler
let isSelf = true//BattleCharacter.CurrentUnitType==100? true:false;

This is used to delink. Delink mean, cheat apply to certain object not all. Say, only on myself but not enemy. We want to amplify our team's attack but not enemy's team. You would only use this to delink if your root object contains both Ally and Enemy.

STEP 5) Preparing all cheat objects required here

Spoiler
cheatObj["Gameplay"] = Gameplay

let GameData = new UnityObject(Gameplay.m_GameData)
GameData.loadFields(["m_Const"])
let Const = new UnityObject(GameData.m_Const)
Const.loadFields(["LevelUpInvincibleTime", "AdsCoolTime", "ImaeRecoveryValue"])

cheatObj["Const"] = Const

let ImaeRecoveryValueAry = new UnityArray(Const.ImaeRecoveryValue, 'int32')
ImaeRecoveryValueAry.setAll = function (value) {
  for (let j = 0; j < this._size; j++) {
    this.set_Item(j, value)
  }
}
cheatObj["ImaeRecoveryValues"] = ImaeRecoveryValueAry

let JamList = new UnityList(Gameplay.m_JamList)
//JamList.export()
let JamAry = [];
for (let j = 0; j < JamList.size(); j++) {
  let Jam = new UnityObject(JamList.get_Item(j))
  Jam.loadFields(["m_ItemType"])
  if (Jam.m_ItemType == 1) JamAry.push(Jam)
  else debugInfo("New ItemType:" + Jam.m_ItemType, [JamList.get_Item(j)])
}
cheatObj["Jams"] = JamAry

let Character = new UnityObject(Gameplay.m_Player)
Character.loadFields(["m_SelectSpecialSkill", "m_Skill"])
let SpecialSkill = new UnityObject(Character.m_SelectSpecialSkill)
SpecialSkill.loadFields(["m_CoolTime"])

cheatObj["SpecialSkill"] = SpecialSkill

let ItemStatAddr = Gameplay.m_ItemStat
let ItemStatAry = new UnityArray(Number(ItemStatAddr), 'int32')

ItemStatAry.addPower = function (value) {
  this.set_Item(0, this.get_Item(0) + value)//power
}
ItemStatAry.addHP = function (value) {
  this.set_Item(1, this.get_Item(1) + value)//HP
}
ItemStatAry.addDefense = function (value) {
  this.set_Item(2, this.get_Item(2) + value)//Defense
}
ItemStatAry.setSpeed = function (value) {
  this.set_Item(3, value)//speed
}
cheatObj["ItemStats"] = ItemStatAry

 

Highlight 1) cheatObj["<<Param 1 Name>>"] = <<Object reference>>
 This is very important step to allow core mod menu engine knows where to apply the cheat. You can see different ways to prepare it
  1) Directly link it with base Unity Object (e.g. Gameplay)
 2) Link to other object through field reference (e.g. Const)
 3) Link to object that represent an Array, and has Dynamic/Runtime/Late Binding method to apply update (e.g. ImaeRecoveryValues)
  4) Link to list of objects (SELFLIST, team) with select/filtering condition, each object would eventually apply the relevant cheat once (e.g. Jams)
  5) Link to Primitive Type Array, and has Dynamic/Runtime/Late Binding method to apply cheat to individual array item (e.g. ItemStats) 

Highlight 2) Every object would have its Fields / Methods prepared and ready for consumption
  It could be as simple as loadFields, loadMethods. OR as advanced as Dynamic/Runtime/Late Binding method to custom create cheat logic to apply 

OPTIONAL STEP) Define your own complex or one time cheat by extending with custom logic
Example 1) High volume of object to update, requires to handle separately

Spoiler
function triggerSkillCoolTimeCheat() {
	try {
		var GameplayObjs = script.call("findUnityObjectOfType", ["$Gameplay", true]);
		var GameplayAddr;
		var Gameplay
		for (let i = 0; i < GameplayObjs.length; i++) {
			GameplayAddr = GameplayObjs[i]
			Gameplay = new UnityObject(GameplayAddr)

			Gameplay.loadFields(['m_Player'])
			let Character = new UnityObject(Gameplay.m_Player)
			Character.loadFields(["m_Skill"])
			let SkillAry = new UnityArray(Character.m_Skill)
			//let Skills =[];
			for (let j = 0; j < SkillAry.size(); j++) {
				let Skill = new UnityObject(SkillAry.get_Item(j))
				Skill.loadFields(["m_CoolTime"])
				Skill.m_CoolTime = 0.5
			}
			appendLog("Apply Skill CoolTime successful")
		}

	} catch (e) {
		debugInfo("Error in running JSPlugin on GamePlay:" + GameplayAddr
			+ JSON.stringify(e, Object.getOwnPropertyNames(e)) + ":" + e.toString(), [GameplayAddr]);
	}
}

This above logic loop through all Skills and apply changes to their cool time. There are few hundred objects, we cannot put inside the original cheat block which trigger every 1.2 seconds. It will overload the game and might cause game stability issue. This cheat needs to handle separately.

Example 2) Cheat that are very specific, and would trigger conditionally when needed

Spoiler
function triggerDropItemCheat() {
	try {
		var GameplayObjs = script.call("findUnityObjectOfType", ["$Gameplay", true]);
		var GameplayAddr;
		var Gameplay
		for (let i = 0; i < GameplayObjs.length; i++) {
			GameplayAddr = GameplayObjs[i]
			Gameplay = new UnityObject(GameplayAddr)

			Gameplay.loadFields(['m_Player', 'm_GameData'])
			Gameplay.loadMethods(["void CreateJam(int32,vector,int32,int32,vector4,int32)"]);
			let Character = new UnityObject(Gameplay.m_Player)
			Character.loadFields(["m_Skill", "m_Head"])

			let position = script.call("transform_get_position", [Number(Character.m_Head)]);
			let position2 = { w: 0, x: position.x, y: position.y, z: position.z }
			Gameplay.CreateJam(1, position, 5, 5000, position2, 202104)
			Gameplay.CreateJam(1, position, 20, 0, position2, 400002)
			Gameplay.CreateJam(1, position, 40, 0, position2, 600002)
			Gameplay.CreateJam(1, position, 34, 0, position2, 500503)
			appendLog("Drop Item done")
		}
	} catch (e) {
		debugInfo("Error in running JSPlugin on GamePlay:" + GameplayAddr
			+ JSON.stringify(e, Object.getOwnPropertyNames(e)) + ":" + e.toString(), [GameplayAddr]);
	}
}

This above logic create Item Drop of our own interest. We might not need to keep dropping item indefinitely
This cheat would obviously handle separately.

 

Now, you can see how powerful of this Feature is. You can do all kind of crazy things as long as you understand how the game work. (Static Analysis)

Tell me more about your innovative use of this Features in comments below. 

 

Feature 5) Export Unity Runtime Data

Spoiler

Scenario a) You want to make an item drop cheat. You have found the method to drop item, however you are not sure the code and other detail required to drop item. Of course, you can manually navigate the item list to check item one by one. However, it will take ages. Are there smarter way?
JSPlug-in's solution to this is, leveraging the power of export() method to download relevant data

Spoiler
let GameData = new UnityObject(Gameplay.m_GameData)
GameData.loadFields(["m_RewardList"])
let RewardListAry = new UnityArray(GameData.m_RewardList)
RewardListAry.export()

 

In this scenario, RewardList is actually the item list that could drop from battle. The list after export() would be available inside Documents folder of the game. You will need to enable File Sharing during sideload in order to access them

This feature is available on UnityArray, UnityList, UnityDictionary, and UnityObject

Now, you can see how powerful of this Feature is. You can do all kind of crazy things as long as you understand how the game work. (Static Analysis)

Tell me more about your innovative use of this Features in comments below. 


 

 

 

TO BE CONTINUED...

Updated by Happy Secret
Updated Tutorial to cover Feature 5
  • Like 16
  • Winner 2
  • Thanks 2
  • Haha 1
  • Agree 1
  • Informative 2
Link to comment
Share on other sites

4 hours ago, cronaldo4278 said:

I had question can it be used as integrate from igamegod and iiosgods mod menu and sideloadly ? 

As long as your game didn’t detect it, you can mix them all together. 
In fact, H5GG and iGameGod are good partner in cheat. 

Link to comment
Share on other sites

12 minutes ago, Happy Secret said:

As long as your game didn’t detect it, you can mix them all together. 
In fact, H5GG and iGameGod are good partner in cheat. 

Ihad question are values changeable permanent or temporary ? Like game currency  

Link to comment
Share on other sites

1 hour ago, cronaldo4278 said:

Ihad question are values changeable permanent or temporary ? Like game currency  

Of course depends on game.

If currency is server-sided, we can cheat them locally. Or you can use those money to buy thing, if money is server-sided. 
In other word, locally you have 999999, but server side would only have 100. You can’t buy 110 thing. 
Currency is relatively more protected in game. 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below. For more information, please read our Posting Guidelines.
Reply to this topic... Posting Guidelines

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Our picks

    • CarX Street v1.2.2 Cheats +4
      Modded/Hacked App: CarX Street By KAR IKS TEKHNOLODZHIS, OOO
      Bundle ID: com.carxtech.sr
      iTunes Store Link: https://apps.apple.com/us/app/carx-street/id1458863319?uo=4

       


      Mod Requirements:
      - Non-Jailbroken/Jailed or Jailbroken iPhone/iPad/iPod Touch.
      - Sideloadly / Cydia Impactor or alternatives.
      - A Computer Running Windows/macOS/Linux with iTunes installed.


      Hack Features:
      - 2M currency
      - Max level
      - Unlimited fuel
      - Unlimited nitro
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 57 replies
    • Gangstar Vegas Cheats v680 +4
      Modded/Hacked App: Gangstar Vegas By Gameloft
      Bundle ID: com.gameloft.gangstar4
      iTunes Store Link: https://apps.apple.com/us/app/gangstar-vegas/id571393580?uo=4


      Hack Features:
      - Infinite Currencies
      - Infinite Run ( To stop running turn off in menu then click run again )
      - Infinite Ammo / No Reload ( Required re-launching the game after purchasing new gun and enabled in menu before load into the game )
      - No Cops


      NOTE: Turn off wifi before playing

      iOS Hack Download Link: https://iosgods.com/topic/147734-gangstar-vegas-cheats-v530-4/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 885 replies
    • Modern Warships Cheats v0.76.1 +7
      Modded/Hacked App: Modern Warships By Sergiy Petrov
      Bundle ID: com.Shooter.ModernWarships
      iTunes Store Link: https://apps.apple.com/us/app/modern-warships/id1541751298?uo=4


      Hack Features:
      - Multiply Attack
      - Multiply Defense
      - Infinite Ammo
      - No Reload
      - Freeze Boosters
      - Free Subscription?
       + 10% EXP
       + 50% Cash + Gold


      iOS Hack Download Link: https://iosgods.com/topic/146309-modern-warships-cheats-v0450-6/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 1,082 replies
    • Guild of Heroes: Fantasy RPG v1.161.7 - [ x Player Damage & More ]
      Modded/Hacked App: Guild of Heroes: Fantasy RPG By BIT.GAMES PBL
      Bundle ID: com.goplaytoday.guildofheroes
      iTunes Store Link: https://itunes.apple.com/us/app/guild-of-heroes-fantasy-rpg/id979474617?mt=8&uo=4&at=1010lce4


      Mod Requirements:
      - Jailbroken iPhone/iPad/iPod Touch.
      - iFile / Filza / iFunBox / iTools or any other file managers for iOS.
      - Cydia Substrate (from Cydia).
      - PreferenceLoader (from Cydia).


      Hack Features:
      - x Player Damage - x1 - 10
      - x Player Defense - x1 - 10
      - Enemies Auto Die
      - Premium Activate
      - Freeze Resources
      - Freeze Potions

      All features are unlinked and only for player, you!
      Note:
      Not Responsible For Any Bans


      This hack is an In-Game Mod Menu (iGMM). In order to activate the Mod Menu, tap on the iOSGods button found inside the app. This hack works on the latest x64 or ARM64 iDevices: iPhone 5s, 6, 6 Plus, 6s, 6s Plus, 7, 7 Plus, 8, 8 Plus, X, Xr, Xs, Xs Max, SE, iPod Touch 6G, iPad Air, Air 2, Pro & iPad Mini 2, 3, 4 and later.
      Non-Jailbroken & No Jailbreak required hack(s): https://iosgods.com/topic/79822-guild-of-heroes-fantasy-rpg-v1679-5k-gold-sell-value-more/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 1,502 replies
    • GardenScapes v7.7.0 Jailed Cheats +3
      Modded/Hacked App: Gardenscapes By Playrix Games
      Bundle ID: com.playrix.gardenscapes-m3-ios
      iTunes Store Link: https://itunes.apple.com/us/app/gardenscapes/id1105855019?mt=8&uo=4&at=1010lce4



      Hack Features:
      - Infinite Moves (Won't Subtract)
      - Infinite Boosters (Won't Substract)

       

      Hack Download Link: https://iosgods.com/topic/71553-arm64-gardenscapes-v290-jailed-cheats-2/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 1,479 replies
    • [ Seven Deadly Sins JP ] - 七つの大罪 光と闇の交戦 : グラクロ Cheats v8.6.31 +5
      Modded/Hacked App: 七つの大罪 光と闇の交戦 : グラクロ By Netmarble Corporation
      Bundle ID: com.netmarble.nanatsunotaizai
      iTunes Store Link: https://apps.apple.com/jp/app/七つの大罪-光と闇の交戦-グラクロ/id1268959718?uo=4&at=1010lce4


      Hack Features:
      - God Mode
      - OHK


      iOS Hack Download Link: https://iosgods.com/topic/112888-seven-deadly-sins-%E4%B8%83%E3%81%A4%E3%81%AE%E5%A4%A7%E7%BD%AA-%E5%85%89%E3%81%A8%E9%97%87%E3%81%AE%E4%BA%A4%E6%88%A6-%E3%82%B0%E3%83%A9%E3%82%AF%E3%83%AD-v340-god-mode-unlimited-mp/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 988 replies
    • Unknown Knights: Pixel RPG Cheats v1.0.95 +2
      Modded/Hacked App: Unknown Knights: Pixel RPG By cookapps
      Bundle ID: com.cookapps.bm.unknownknight
      iTunes Store Link: https://apps.apple.com/us/app/unknown-knights-pixel-rpg/id6443811741?uo=4


      Hack Features:
      - Multiply Attack
      - Multiply Defense


      iOS Hack Download Link: https://iosgods.com/topic/178281-unknown-knights-pixel-rpg-cheats-v1085-2/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 124 replies
    • [ Seven Deadly Sins KR ] 일곱 개의 대죄: GRAND CROSS Cheats v8.6.31 +5
      Modded/Hacked App: 일곱 개의 대죄: GRAND CROSS By Netmarble Corporation
      Bundle ID: com.netmarble.nanakr
      iTunes Store Link: https://apps.apple.com/kr/app/%EC%9D%BC%EA%B3%B1-%EA%B0%9C%EC%9D%98-%EB%8C%80%EC%A3%84-grand-cross/id1449552940?uo=4


      Hack Features:
      - God Mode
      - One Hit Kill
      - Multiply Attack
      - Multiply Defense
      - Make Enemies God Mode for some quests


      iOS Hack Download Link: https://iosgods.com/topic/154899-seven-deadly-sins-kr-%EC%9D%BC%EA%B3%B1-%EA%B0%9C%EC%9D%98-%EB%8C%80%EC%A3%84-grand-cross-cheats-v750-5/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 113 replies
    • Tanks A Lot - 3v3 Brawls Cheats v6.300 +6
      Modded/Hacked App: Tanks A Lot - 3v3 Brawls by BoomBit, Inc.
      Bundle ID: com.boombitgames.TanksALot
      iTunes Store Link: https://apps.apple.com/us/app/tanks-a-lot-3v3-brawls/id1344713773?uo=4&at=1010lce4


      Hack Features:
      - God Mode
      - Infinite Ammo
      - No Reload
      - Speed Hacks
      - Disable Enemy Shield
      - No Skill Cooldown


      Hack Download Link: https://iosgods.com/topic/76001-arm64-tanks-a-lot-3v3-brawls-cheats-v190-6/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 1,976 replies
    • Zooba: Zoo Battle Royale Game v4.32.0 Jailed Cheats +2
      Modded/Hacked App: Zooba: Zoo Battle Royale Games By Wildlife Studios Limited
      Bundle ID: com.fungames.battleroyale
      iTunes Store Link: https://apps.apple.com/us/app/zooba-zoo-battle-royale-games/id1459402952?uo=4


      Hack Features:
      - Map Hacks
      - Allow Shoot in Water


      Jailbreak required hack(s): https://iosgods.com/topic/131104-arm64-zooba-zoo-battle-royale-game-cheats-all-versions-2/


      iOS Hack Download Link: https://iosgods.com/topic/131134-arm64-zooba-zoo-battle-royale-game-v320-jailed-cheats-2/
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 1,034 replies
    • ONE PIECE トレジャークルーズ [OP TREASURE CRUISE Japan] v13.4.1 +5
      Modded/Hacked App: ONE PIECE トレジャークルーズ By Bandai Namco Entertainment Inc.
      Bundle ID: jp.co.bandainamcogames.NBGI0199
      iTunes Store Link: https://apps.apple.com/jp/app/one-piece-%E3%83%88%E3%83%AC%E3%82%B8%E3%83%A3%E3%83%BC%E3%82%AF%E3%83%AB%E3%83%BC%E3%82%BA/id824116884?uo=4


      Hack Features:
      - Go over Character Box Capacity
      - Auto Win
      - God Mode
      - Skill Available after 1 Turn
      - High Damage Hits
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 62 replies
    • Global ONE PIECE TREASURE CRUISE v13.4.1 +5
      App Name: ONE PIECE TREASURE CRUISE By Bandai Namco Entertainment Inc. v12.1.2
      Bundle ID: jp.co.bandainamcogames.BNGI0218
      Requires: iOS 10.0 or later.
      Price: Free
      iTunes URL: https://apps.apple.com/us/app/one-piece-treasure-cruise/id943690848

      Hack Features:

      - Auto Win

      - God Mode

      - Skill Available after 1 Turn

      - High Damage Hits

      - Go over Character Box Capacity
        • Informative
        • Agree
        • Haha
        • Thanks
        • Winner
        • Like
      • 202 replies
×
  • Create New...

Important Information

We would like to place cookies on your device to help make this website better. The website cannot give you the best user experience without cookies. You can accept or decline our cookies. You may also adjust your cookie settings. Privacy Policy - Guidelines