|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Sat Oct 26, 2013 9:35 am Post subject: Using msdbg with CE to hack .NET games. |
|
|
Hi folks,
CE is still by far my favorite debugger, but using msdbg with SOS is incredibly useful when it comes to hacking .NET games. I'm going to attempt to give a few tips for using these tools by example.
To begin, you'll need to download the free msdbg debugger. In most cases, you'll need the 32-bit debugger. Unfortunately, if you're on a 64-bit OS, the stupid automatic setup program will only provide the 64-bit version. After much effort, I was able to turn up this link for the 32-bit setup program: msdbg 32-bit. It has been a while since I've installed, but I believe it chooses sensible defaults for everything. You may have to poke around a bit to setup symbol servers, but that's outside the scope of this tutorial.
For this tutorial, I'm going to use Terraria as an example. There are plenty of .NET games to choose from, but this one is pretty simple, pretty popular, and I'm already fairly familiar with it. The same principles apply for any target, however. So, begin by firing up Terraria and attaching CE to it. Let's start by finding our player's health address as usual. Search for the number, take some damage, search again, etc. Right-click the found address and ask CE to identify what accesses this address. We see a bunch of hits, all of the form [base+1f0] - so, from this we can pretty safely infer the base address for the player class (figure 1). So, fire up msdbg and attach to Terraria. The first thing I always do upon launching msdbg is setup the debugging markup language extensions, which allows addresses and such to be clicked on like hyperlinks. It's very useful. Type ".prefer_dml 1" to enable this funcionality. Then, load the SOS CLR extension: ".loadby sos clr" Now, let's dump the player class we found the address to: "!do XX", where XX is the address we located in CE. MSDBG will respond by telling us that the address points to a "Terraria.Player" class, and dumps the entire class structure for us (figure 2)! We can use this information to determine the offsets of every class member.
Part 2.
We can use msdbg to get a list of all objects on the heap (since .NET offers scant few primitives, this includes nearly everything). Try a command like: "dumpheap -stat -type Terraria" This will dump a summary of all heap items containing the name Terraria. The -stat argument is relatively important in a game this size with a query this broad, since the number of results might otherwise be so large as to tie up the system for a long time. In this case, we get a nice list of a bunch of Terraria classes, each including a method table id (see fig 3). Let's take a look at NPC by clicking the MT entry next to it. OK, msdbg printed the address and mt for each of the 400-odd NPCs the game has allocated. If we click the address for one, we get a class dump, similar to the one we saw for the player class earlier. If we click the mt for the class, we get an abbreviated summary of the class's vtable. We can see more detail with the -md argument, eg: "!dumpmt -md xx" (fig 4). Ah! This is useful. We can see a list of each method belonging to the class, along with a flag indicating whether or not the method has already been JIT compiled. If we click one of the methods that's been compiled, we can get the address of the method and drill down right to the disassembly. Let's do so for the NPCLoot function, as it looks useful. Scrolling down from the top of the code listing, we see that the game calls some internal functions (Terraria.Player.FindClosest) and Terraria.Item.NewItem(Int32, Int32, Int32, Int32, Int32, Int32, Boolean, Int32, Boolean). The calling convention is fastcall, so we can look at how the code is loading registers and the stack before calling the funcion to suss out the parameters. In this case, the push 209h draws our attention... why, the game is spawning an item with id 0x209 here! Reading further, we see a similar process for pretty much every item an NPC can drop. This is incredibly useful, because it tells us exactly what we need to tinker in order to modify drop rates for specific items. We can even use the code dumps to easily create our aob scans. Essentially, msdbg has given us the ability to navigate .net code as easily as we would native code using the relocated addresses CEs symbol handler finds for us with the added bonus of automatically dissecting structures.
part 3:
Useful msdbg/sos commands:
!help
!help xxx, eg !help do
!dumpheap [-stat] [-type (ABC)], eg !dumpheap -type Terraria.Main
!name2ee, eg !name2ee Terraria NPC.NPCLoot
!dumpmt [-md]
Description: |
|
Filesize: |
19.79 KB |
Viewed: |
49726 Time(s) |
|
Description: |
|
Filesize: |
13.05 KB |
Viewed: |
49726 Time(s) |
|
Description: |
|
Filesize: |
37.48 KB |
Viewed: |
49736 Time(s) |
|
Description: |
|
Filesize: |
205.91 KB |
Viewed: |
49736 Time(s) |
|
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Sat Oct 26, 2013 12:05 pm Post subject: |
|
|
nice.
Perhaps using or hooking mscorjit.getJit might be useful for CE as well
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
Geri Moderator Reputation: 111
Joined: 05 Feb 2010 Posts: 5636
|
Posted: Sat Oct 26, 2013 2:17 pm Post subject: |
|
|
Though I am not the kind of guy who is digging in a game for a long time, because I get bored with them quickly, but it looks interesting.
_________________
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Mon Oct 28, 2013 2:26 pm Post subject: |
|
|
Ok, I've managed to do this using code of my own. (well, basically using the ICorDebugProcess interface)
Problem is there's WAY TO MUCH that can be done
I can get a list of all the JITed methods and pointers to the IL code, and if .NET 4.5 is installed enumerate every element in the Heap and even lookup objects manually by address and get every little bit of data about it. (classes that use it, layout of the types, and classes, etc...)
So not really sure what to add to ce (data overload)
And another downside is that the data lookup mechanism in .net is not capable of dissecting other architectures (meaning a 32-bit process needs a 32-bit dissector)
So if I add this to ce I'll need to use child processes that do the data gathering (I hate that)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Tue Oct 29, 2013 2:53 pm Post subject: |
|
|
Dark Byte wrote: | Ok, I've managed to do this using code of my own. (well, basically using the ICorDebugProcess interface)
Problem is there's WAY TO MUCH that can be done
I can get a list of all the JITed methods and pointers to the IL code, and if .NET 4.5 is installed enumerate every element in the Heap and even lookup objects manually by address and get every little bit of data about it. (classes that use it, layout of the types, and classes, etc...)
So not really sure what to add to ce (data overload)
|
Oh, Lord! I humbly bow before your enormous talent, DB. Seriously, the prospect of having some of that functionality in CE is freaking AMAZING.
I understand exactly what you mean about it being too much information. The thing that I'd guess would be most useful, probably, would be adding .net methods, globals, etc and corresponding addresses from the module to the symbol store like you would for a C++ class inside a DLL. My wish-list would include some way to populate the dissect window with a class's members, but that seems like a pretty huge job.
Dark Byte wrote: | And another downside is that the data lookup mechanism in .net is not capable of dissecting other architectures (meaning a 32-bit process needs a 32-bit dissector) | Given the difficulty I had in getting setup with a 32-bit version of msdbg and failures when using the 64-bit version, that makes sense. I've spent a little time trying to learn how as assembly is stored in a PE file, and AFAIK, it contains the same information and is the same for both 64-bit and 32-bit. I'd guess it's thusly possible to get this information without the ICorDBG, but since I can't quite do it myself I guess I can't reasonably suggest it as a good workaround. It would be awesome if any .NET stuff you added worked on Mono as well as CLR, since so many games are using mono via Unity these days, but I have no notion of Mono's debugging facilities.
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Tue Oct 29, 2013 3:30 pm Post subject: |
|
|
It's possible to do it manually yes, but I think that IcorDebug has inside knowledge of things (symbol addresses, hidden enum types, etc..) that are not normally exported/documented. So doing it yourself would be difficult
Mono also has debugging, but it's completly different from .net
Also, I found it easier to just recompile the mono dll (for unity based games) and add a function that just dumps all the generated Classes
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8516 Location: 127.0.0.1
|
|
Back to top |
|
|
friuns How do I cheat? Reputation: 0
Joined: 29 Oct 2013 Posts: 1
|
Posted: Wed Oct 30, 2013 10:49 am Post subject: |
|
|
Quote: | [base+1f0] - so, from this we can pretty safely infer the base address for the player class (figure 1)
|
what base is? edi? or eax, don't see it on screenshot, where you get 4c98340 address on second screenshot?
i tried self made .net app didn't work, "invalid class address"
this is what i get
hxxp://i.imgur.cxm/9ZHFbkW.png
hxxp://i.imgur.cxm/rDE6Q5b.png
hxxp://i.imgur.cxm/0mDC9Bm.png
can somebody make tutorial with Mono.Cecil?)
|
|
Back to top |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Wed Oct 30, 2013 11:58 am Post subject: |
|
|
friuns wrote: | Quote: | [base+1f0] - so, from this we can pretty safely infer the base address for the player class (figure 1)
|
what base is? edi? or eax, don't see it on screenshot, where you get 4c98340 address on second screenshot?
|
The base is the address of the health address -1f0. What we were looking for was a consistent offset that health was accessed using, which in turn gives us a notion for the base address of the class it belongs to.
friuns wrote: | i tried self made .net app didn't work, "invalid class address" |
That's pretty self-explanatory... you're giving the !do command the wrong address. If the class is instantiated on the heap, you can alternatively find it with the !dumpheap command. If it's static/global and you know the name, you can use the !name2ee command. If it's a temporary/auto scoped variable, you can use !dso to find it on the stack. I can't really tell you more w/o seeing the test .net app.
friuns wrote: | can somebody make tutorial with Mono.Cecil?) |
There's some sparse documentation on the Cecil homepage. If you wanna' talk about unrelated Cecil stuff in more detail, please start a new thread for it.
|
|
Back to top |
|
|
Rydian Grandmaster Cheater Supreme Reputation: 31
Joined: 17 Sep 2012 Posts: 1358
|
Posted: Wed Oct 30, 2013 4:05 pm Post subject: |
|
|
Ahhh, so THIS is what you were referring to when you mentioned debugging with SOS and such to read all the offsets! Very nice.
EDIT: As far as potentially adding functions to CE, the method used to get a dump of the offsets for a structure would fit in extremely nicely with the dissect data/structures tool, which I mainly use to try to map out stats for entities/players in various games.
EDIT2: Also in Part 2 you list "dumpheap -stat -type Terraria" without the exclamation point at the start.
|
|
Back to top |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Fri Nov 01, 2013 7:58 pm Post subject: |
|
|
Dark Byte wrote: | I found it easier to just recompile the mono dll (for unity based games) and add a function that just dumps all the generated Classes | Hah. That's clever. I'd be interested in seeing your mods, if you'd please share. I don't have cygwin installed anymore, and the mono build process looks like quite a chore.
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Fri Nov 01, 2013 8:16 pm Post subject: |
|
|
Cygwin isn't really needed. (From what i saw) there is a visual studio solution with several projects. If you build the proper prerequisite projects first eventually the monolib project will build and function as well
(I use separate projects because i use vs2008 and the sln was for 2010 or later)
You'll want to use https://github.com/Unity-Technologies/mono as it also contains some exports unity relies on
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Fri Nov 01, 2013 9:16 pm Post subject: |
|
|
Dark Byte wrote: | Cygwin isn't really needed. (From what i saw) there is a visual studio solution with several projects. If you build the proper prerequisite projects first eventually the monolib project will build and function as well
(I use separate projects because i use vs2008 and the sln was for 2010 or later)
You'll want to use https://github.com/Unity-Technologies/mono as it also contains some exports unity relies on |
Sweet. Thank you for the link and information.
|
|
Back to top |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Fri Nov 22, 2013 8:48 am Post subject: |
|
|
I took a look at this last night and darn near pulled all my hair out. I can't even figure out who to point a finger at, but I went over a LOT of sloppy code and horrid documentation. For example, the MSDN docs say that one need only define MSVER as 500 or more to use VectoredExceptions, but then the my Windows SDK have these functions unavailable to MSVER less than 501 (see errhandlingapi.h). The Unity Mono branch is in shambles, especially with regard to the "eglib" stuff - it's optional with Mono for the case that you'd prefer not to install it separately, but apparently required with the Unity fork (because of ugly hacks instead of proper framework design). Of course, it's not documented anywhere. Also lacking is any build documentation whatsoever and if you try to follow the instructions on the Mono page you'll fail miserably because the autoconf scripts are so badly hacked up. I finally got it built properly, but Jesus... I don't understand how a project so large, for a major distribution like Unity, is so totally repugnant. It doesn't help that there are unmaintained scripts of all manner (CMake, autoconf, pkg-config, perl, custom gentools) littered throughout the distribution just begging to waste your time. Someone on the team seriously needs to sit down on a fresh dev machine and troubleshoot/document every step to build.
I also took a look at using the ICorDBG interfaces, but quickly became quite sour on it as well... having to implement a /huge/ interface just to hook one or two callbacks is absurd. Even if one copies all the prototypes from the headers, that's a lot of scaffolding to build! I don't understand why the API authors didn't either subdivide the interface into smaller portions or perhaps offer a non-virtual skeleton base to overload. I'll tinker with it again later, but I walked away feeling frustrated that it wasn't something I could get anywhere near functional shape in one sitting (that's, IMHO, a failing of the API). Was it easier for you?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Fri Nov 22, 2013 9:01 am Post subject: |
|
|
I didn't have any problem with the libmono project after building the other projects. No code changes/define settings where needed. (I used the visual studio projects. I stayed clear of using any script)
ICorDebug does require a lot of coding, but it's not that hard. Also, if you only need to get data instead of actual debugging, then use the virtual process method. That way you only need to implement a few abstract methods.
Check out
http://code.google.com/p/cheat-engine/source/browse/trunk/Cheat%20Engine/DotNetDataCollector/DotNetDataCollector/
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|