One issue on making assembler cheat on jit bytecode (unity/flash) game is that piece of assembler code to be injected may not existed until the related bytecode got executed and jit compiled. So that invincible cheat has to be activated after being hit, for example.
I remembered a master has even written a complex hooking code into the mono.dll so that the cheats is automatic activated when the related byecode being compiled.
Not sure from which version of 6.4+, it seems the issue is solved, probably by the work starting from these post? (ie. search result of getmonostruct)
http://forum.cheatengine.org/viewtopic.php?p=5589255&sid=542b8b456e35c33dd8616532115b2f71
http://forum.cheatengine.org/viewtopic.php?p=5565915&sid=8d234bca3e755b4b7f8fb3dd3cecaff0
http://forum.cheatengine.org/viewtopic.php?t=575692
Forgive my ignorance if those are well known fact, but it seems not many making cheats with the mono feature. Here allow me present a way of efficiency use of mono feature in a certain type of cheat.
Some of the cheats may called ‘function parameter hijacking’.
The example script is here: http://forum.cheatengine.org/viewtopic.php?p=5606528#5606528
The three Jit cheats all made by modifying the input parameters ie. [ebp+0c].
But 1st, the mono feature is used to instantiate the target functions.
Code: |
globalalloc(__,$4000)
__:
dq __
usemono()
getmonostruct(InteractionInstance_Base)
getmonostruct(BehaviourStat)
getmonostruct(CraftingManager)__+40:
dd “CraftingManager:CanCraftRecipe”
dd “CraftingManager:RemoveItemsFromInventory”
dd “CraftingManager:HasTheseIngredients”
dd “BehaviourStat:Modify”
dd “InteractionInstance_Base:ModifyInteractionDuration”
dd “InteractionInstance_Base:ResetInteractionTimer” |
The command ‘usemono’ is the aa equivalent of lua function LaunchMonoDataCollector(). It establish a monopipe between the target process and ce. Note, if some debugging function is made, the pipe will be broken and need re-connecting.
Then getmonostruct bring the class information and the symbols “class:function” made the respective target functions being jit compiled. Note , sometime an extra namespace may be need, refer it like “namespace:class:function”.
Now the starting address of the respective functions is ready and can be refer by the symbol form as “class:function”.
This is the code that make the functions always return true in ‘crafting consume none’ cheat:
Code: |
define(can,”CraftingManager:CanCraftRecipe”)
define(del,”CraftingManager:RemoveItemsFromInventory”)
define(has,”CraftingManager:HasTheseIngredients”)[ENABLE]
assert(can,55 8b ec 57 56)
assert(del,55 8b ec 57 56)
assert(has,55 8b ec 57 56)
can:
xor eax,eax
inc eax
ret
del:
xor eax,eax
inc eax
ret
has:
xor eax,eax
inc eax
ret
[DISABLE]
can:
db 55 8b ec 57 56
del:
db 55 8b ec 57 56
has:
db 55 8b ec 57 56 |
Since the initial few byte of the function of a fixed calling convention and signature is pretty constant, it make the cheat almost fail-save.
Here another example by making a code cave to examine the input parameter and change it if need:
Code: |
define(mod,”BehaviourStat:Modify”)
[ENABLE]
__+0f4:
dd (float)8
assert(mod+04,83 ec 04 8b 7d 08)
__+1300:
readmem(mod+04,6)
cmp dword ptr [ebp+0c],0
jle @f
fld dword ptr [ebp+0c]
fdiv dword ptr [__+0f4]
fstp dword ptr [ebp+0c]
jmp mod+0a
@@:
fld dword ptr [ebp+0c]
fmul dword ptr [__+0f4]
fstp dword ptr [ebp+0c]
jmp mod+0a
mod+04:
jmp __+1300
nop
[DISABLE]
assert(mod+04,e9)
mod+04:
db 83 ec 04 8b 7d 08 |
—
Although I’ve not actually used in cheat. The offset of property can also be refer. But it has to include the getmonostruct command in the script to bring in the struct info. ie. (not actual code)
Code: |
GETMONOSTRUCT(BehaviourStat)
…
mov [edi+BehaviourStat.fatigue],0
… |
Further with an extended version aobscan with range specification, more update resisting and efficient cheat can be made on mono game.
sorry if it cause more confusion…probably not for beginner.
bye~
ADDED:
some property is using getter or setter. For example for HEALTH, refer the getter function as get_HEALTH. Note that the jit de-compiled code may or may not use a getter function but just an offset, it can be randomly either case in different running of the same version of game. function hijacking likely won’t work for these cases.
_________________
– Retarded.
|