| View previous topic :: View next topic | |
| Author | Message |
|---|---|
| JustHim24 How do I cheat? Reputation: 0 Joined: 15 Jan 2024 Posts: 7 |
Post Posted: Thu Mar 27, 2025 10:06 am Post subject: Question: Patching Methods Mono .NET
Reply with quote
Hey ive been playing a bunch of Schedule I recently and using the mono tab i clicked on .NET Info, went to Assembly-CSharp.dll and found a method i want to patch. Does anyone have any good resources/tutorials on how to do this properly preferably for beginners? I do have a programming background so writing the actual code shouldnt be too big of a task. Thanks!
|
| Back to top | |
| jgoemat Master Cheater Reputation: 23 Joined: 25 Sep 2011 Posts: 264 |
Post Posted: Mon Aug 04, 2025 5:29 pm Post subject: MonoHelper
This post has 1 review(s) Reply with quote
Sorry I don't have time to create a tutorial or video or update a lot of things, but I have a 'MonoHelper' project that you might be interested in. Here's the link that has some info: https://fearlessrevolution.com/viewtopic.php?t=11415
But if you want to use it, I recommend downloading one of my recent tables and checking it out as I've updated the script recently. I condensed it into a single table entry that runs the LUA. What it does is pre-process a single mono dll, defaulting to 'Assembly-CSharp' which is most often used. Then it adds a 'Search' button in the Mono menu when connected to a game. It filters classes, properties, and methods as you type. Here's a recent one for 'Rock Crusher' demo which is free if you want to see how the scripts it creates work and try it out: https://fearlessrevolution.com/search.php?author_id=7314&sr=posts - if you right-click on the script and go to "group config' and uncheck 'hide all children when deactivated' then delete all the children you can copy it to your own table. Usually I start just by using Mono->Search and looking for classes like 'Player', 'Ship', 'Manager', 'Entity', etc. It's a good thing when you find something with an 'Update()' method. That means it is usually called every frame. I usually start by finding something like that and in the class window I right-click on the method and select 'Create Debug Entry'. That'll create a table entry you can enable to hook that method. That table entry has children that show the last value of RCX when it was called (pointer to that class instance), how many times it was called, and all the parameter values passed the last time it was called. I'll usually copy that value and load it into the structure dissectory (CTRL+M for memory viewer, then CTRL+D for structure dissector) and let it generate the structure to see what I'm working with. Then I can just add instructions to try out something to cheat and I have a working script. For example in the Rock Crusher I have a cheat to not consume fuel. I just searched for 'fuel' and found the FuelManager class and ConsumeFuel method by searching for which seemed like what I wanted. I just double-clicked to open the class and right-clicked on that method to create a debug entery and added some code. I added `GETMONOSTRUCT(FuelManager)` which sets up the field names with offsets for the script, and three instructions to set the current fuel to max and zero out xmm1 which is the parameter for how much fuel to consume, the rest was generated. Code: define(hook,"SR.Run.Combat.FuelManager:Consume")
define(bytes,55 48 8B EC 48) [enable] assert(hook, bytes) alloc(newmem,1000,ドル hook) label(pFuelManager_Consume) { RCX: FuelManager (this) XMM1: single amount R8: SR.Run.Combat.FuelConsumptionSource source Returns (RAX) System.Void } GETMONOSTRUCT(FuelManager) newmem: // increment counter, store instance and parameters (could be off for static method?) push rbp mov rbp,rsp push rax mov [pFuelManager_Consume], rcx inc dword ptr [pFuelManager_Consume+8] movss [pFuelManager_Consume+10], XMM1 // amount mov [pFuelManager_Consume+18], R8 // source mov eax,[rcx+maxFuel] mov [rcx+currentFuel],eax // set current fuel to max xorps xmm1,xmm1 // zero out amount pop rax pop rbp // original code // push rbp // mov rbp,rsp // sub rsp,00000080 readmem(hook,11) jmp hook+B align 10 pFuelManager_Consume: dq 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 hook: jmp newmem registersymbol(pFuelManager_Consume) [disable] hook: db bytes unregistersymbol(pFuelManager_Consume) dealloc(newmem) You should also check out this post: https://forum.cheatengine.org/viewtopic.php?t=623200 - You can actually write C# now and have it compiled as part of your scripts. It's a bit complicated, but I found a pretty simple method `CraftingWindowUI.CheckCraftable()`. I created a class of my own in my own namespace 'MyGuild' here to replace that method, using a static class and static method with 'this CraftingWindowUI' as the first parameter. Then I just hooked the method and jumped to my replacement which added 'ui.CraftButton.interactable = true' to make it always interactable. Code: {$lua}
if syntaxcheck then return end local references, core = dotnetpatch_getAllReferences() local code = [[namespace MyGuild { public static class CraftingWindowExtensions { public static void CheckCraftable(this CraftingWindowUI ui) { ui.CraftButton.interactable = true; ui.CraftPrompt.UpdateUI(); } } } ]] local assemblyPath = compileCS(code, references, core) mono_loadAssemblyFromFile(assemblyPath) {$asm} |