Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Using msdbg with CE to hack .NET games.
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials
View previous topic :: View next topic  
Author Message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Fri Nov 22, 2013 12:02 pm    Post subject: Reply with quote

Dark Byte wrote:
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.


Dude, you are the man. Thank you for dropping some knowledge on me. I must revere you like a favorite professor. Thanks, too, for showing the code - I don't think I would've known where to look for said method.


Dark Byte wrote:

Check out
http://code.google.com/p/cheat-engine/source/browse/trunk/Cheat%20Engine/DotNetDataCollector/DotNetDataCollector/


I'm eager to study this and write up a simple client for testing. For someone who always claims to be allergic to C++, you sure write it well. Good stuff - the message passing interface is soooo much easier to code against than the MS stuff.

I can't think of any case where a client would call pipe's start and then exit before doing any real work, but I think it will cause your deconstructor to crash because the members aren't initialized to null. Just FYI.

Thanks again, DB.
Back to top
View user's profile Send private message
adaptusaaf
Advanced Cheater
Reputation: 0

Joined: 13 Jan 2008
Posts: 52

PostPosted: Tue Nov 26, 2013 8:25 am    Post subject: Reply with quote

Question on msdbg's PreJIT and JIT status

If something is PreJIT - we have no way attack it yet, right? (other than modifying raw IL data)

If something is JIT, then it's at the end stages (compiled) and ready for modification, right?

What if you had a target method which did this:


Code:
int get_TestValues()
        {
            return default(int);
        }


Which creates hundreds of different values for each instance of "TestValues"? Do we have to find the memory address for each value and overwrite them one by one, or is there a way to actually change the return value for all of them (and future ones) AFTER the "int get_TestValues()" has been JIT compiled??

I'm wondering if something is JIT compiled - are we modifying the source code IL/c# in machine code form, or are we merely modifying the results it has spat out from the function (with the hundreds of integers for TestValues already created).
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25281
Location: The netherlands

PostPosted: Tue Nov 26, 2013 8:49 am    Post subject: Reply with quote

When something is JIT compiled the IL code has been converted to assembler code

Code:

int get_TestValues()
{
            return default(int);
}



would have been converted to something similar to:
Code:

  push ebp
  mov ebp,esp

  push (int)
  call default
  pop ebp
  ret

It will not deal with the results of the function

_________________
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
View user's profile Send private message MSN Messenger
adaptusaaf
Advanced Cheater
Reputation: 0

Joined: 13 Jan 2008
Posts: 52

PostPosted: Tue Nov 26, 2013 8:02 pm    Post subject: Reply with quote

thanks db!

I installed the 32 bit version, attached to a .net 4 process, what's up with this error?

Got this error message after I tried a !name2ee command after I manually loaded sos.dll and clr.dll from "C:\Windows\Microsoft.NET\Framework\v4.0.30319" by using commands .load C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll and .load C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll:

Failed to find runtime DLL (clr.dll), 0x80004005
Extension commands need clr.dll in order to have something to do.

edit:

apparently it's because it's a silverlight+.net game, and in the silverlight folder, sos.dll is missing, and so is clr.dll. Instead there is a coreclr.dll I think I need to use instead, and for the sos.dll, to get it, as shown here: http://androidyou.blogspot.com/2011/06/how-to-get-sosdll-for-silverlight.html , I have to install visual studio 2010 and the silverlight sdk (not sure if I should use silverlight 4 sdk or silverlight 5 sdk, if there is one, will experiment and post back)
Back to top
View user's profile Send private message
adaptusaaf
Advanced Cheater
Reputation: 0

Joined: 13 Jan 2008
Posts: 52

PostPosted: Thu Nov 28, 2013 2:28 am    Post subject: Reply with quote

I got it all to work, getting familiar with windbg (it's great!), I've located the value I want to tinker with, but how do I find out the address in CE (or the array of bytes to search for) by what I'm looking at in windbg?

For example, pretend we're still in Terraria



And you want to change the value for "frozen" from "0" (false) to "1" (true). How would you find the address (or array of bytes to change the boolean to always true (always frozen) for all units) to do that? I know that's two different questions but it would help a lot!

I'm guessing it has something to do with either the MT, Field, or Offset, or a combination of them.. it just mystifies me.


EDIT:
I drilled down into the MethodDe and found a "codeaddr", used this for my array of bytes search in CE, the problem is, it never works (if I use just a tiny part of the byte array, it usually finds some results in CE, but the preceding/following bytes don't match.)

For example:
in windbg, it will show this:

Code:
System.Int32.CompareTo(Int32)
Begin 5637c300, size 1b
>>> 5637c300 55              push    ebp
5637c301 8bec            mov     ebp,esp
5637c303 3911            cmp     dword ptr [ecx],edx
5637c305 7d05            jge     5637c30c
5637c307 83c8ff          or      eax,0FFFFFFFFh
5637c30a 5d              pop     ebp
5637c30b c3              ret
5637c30c 3911            cmp     dword ptr [ecx],edx
5637c30e 7e07            jle     5637c317
5637c310 b801000000      mov     eax,1
5637c315 5d              pop     ebp
5637c316 c3              ret
5637c317 33c0            xor     eax,eax
5637c319 5d              pop     ebp
5637c31a c3              ret


in CE, only this aob scan will find a match in the same process windbg is attached to (can they not be attached same time, windbg and CE?):

b8 01 00 00 00 5d c3

but the jmps, and cmp dword ptr [ecx,] edx parts are what don't match.. any ideas whats happening?
Back to top
View user's profile Send private message
Hatschi
Master Cheater
Reputation: 2

Joined: 28 Jan 2010
Posts: 327

PostPosted: Thu Nov 28, 2013 4:43 am    Post subject: Reply with quote

Just take the base address of your player + the offset in WinDbg (write them down for example). Close the game open it again attach CE, find the base address, adding the offset to it and voila, you got the final address of what you're lookin for.

Now find out what writes or access to it and write a code injection. Remember to use the right type of value. Frozen for example is boolean, that means ist stored as BYTE in the game.
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Thu Nov 28, 2013 5:40 am    Post subject: Reply with quote

adaptusaaf wrote:
I drilled down into the MethodDe and found a "codeaddr", used this for my array of bytes search in CE

Hey, good job. You've successfully learned to use a new tool, and you're almost done with your hack.

adaptusaaf wrote:
the problem is, it never works (if I use just a tiny part of the byte array, it usually finds some results in CE, but the preceding/following bytes don't match.)

Huh? You're saying that you are seeing different things in CE than you're seeing in Windbg or just that you're having trouble creating a suitable aobscan or what?

adaptusaaf wrote:
in CE, only this aob scan will find a match in the same process windbg is attached to (can they not be attached same time, windbg and CE?)

Those bytes would correspond to pretty much any function that returns true on success, I'd think... there's probably a lot of them. In fact, if your hack requires modifying the default compare for system.int, you might want to try a new tactic (otherwise I'd guess there will be lots of side-effects).

They can both be attached to the process at the same time, but depending on the type of breakpoints you're setup to use in CE (this is a guess), you will probably only be able to handle breakpoints in Windbg (which precludes being able to use CE's functions that depend on them, as well).

adaptusaaf wrote:
but the jmps, and cmp dword ptr [ecx,] edx parts are what don't match.. any ideas whats happening?

Unless I'm missing something, you haven't really shown us enough to make any guesses. It should be as easy as doing a name2ee to get a listing of the function you identified earlier, then reading off the bytes (from a listing similar to the one you typed above, but for the correct function instead of the one you listed).

adaptusaaf wrote:
How would you find the address (or array of bytes to change the boolean to always true (always frozen) for all units) to do that?

It depends on the parameter. If it's a static member, then you can just find the address and change it directly. If it's an instance member, then you've got to somehow enumerate every "unit" and set it for each of them.
Back to top
View user's profile Send private message
adaptusaaf
Advanced Cheater
Reputation: 0

Joined: 13 Jan 2008
Posts: 52

PostPosted: Thu Nov 28, 2013 1:26 pm    Post subject: Reply with quote

thanks for your help guys! I feel close to getting this, but this is what's stumping me:

this is what windbg is telling me when I do a "!dumpheap -stat -type unitdata"



as you can see, there are 46 possible units in the game, it doesn't show any information except the address, mt, and size so far. If I click the address for the first one, which happens to be the most common unit in the game, it gives me this:

MT: 574171d4
Field: 400073d
Offset: 1c
Type: System.Int32
VT: 1
Attr: instance
Value: 0
Name: BonusHealth

so for example this particular unit has 0 bonus health (some have 10 bonus health), if I wanted to give this unit bonus health, I need to change this number from 0..

you are right justadude, it is an instance so I need to enumerate all the units of this type to have bonus health, but do you have any hints on how to do that?

furthermore, if I do a "!dumpmt -md 574171d4" on this bonushealth MT, I get this:




all "PreJIT" or "NONE".. and there are lots of possible things that look like it could be the int32 I need to change, highlighted above.

I tried, for example to click the MethodDe of the middle one, this one:



which gives me this information:



clicking on the CodeAddr (5723c2b0) I get this:



but if I search for these bytes as an array in CE, it finds nothing.
it finds four results for: "56 8b f9 8b f2 85 f6" which is the first part of this code, but as soon as I add the bytes for the "je 5723c2ca" which would be: 56 8b f9 8b f2 85 f6 74 10, CE finds nothing.
Same situation if I try to use the bytes for the "cmp dword ptr [esi],574171d4h" never finds it in CE, or for the other jmp's, or for the "call 57062150". Shouldn't these be found in CE?
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Thu Nov 28, 2013 2:52 pm    Post subject: Reply with quote

adaptusaaf wrote:
as you can see, there are 46 possible units in the game

We're just looking at things instantiated on the heap... There's no way for me to guess that there aren't more possible w/o more information.

adaptusaaf wrote:
If I click the address for the first one, which happens to be the most common unit in the game, it gives me this:
Code:
MT: 574171d4
Field: 400073d
Offset: 1c
Type: System.Int32
VT: 1
Attr: instance
Value: 0
Name: BonusHealth


Is that just one line of the output? It seems like there must be a whole class there if the field has a name.

adaptusaaf wrote:
you are right justadude, it is an instance so I need to enumerate all the units of this type to have bonus health, but do you have any hints on how to do that?

Just like any cheat, really... set a breakpoint on it and check out all the stuff that accesses it. You said that you've got a complete disassembly of the program - you can probably use some kind of more sophisticated static analysis, alternatively.

adaptusaaf wrote:
furthermore, if I do a "!dumpmt -md 574171d4" on this bonushealth MT, I get this:...

That all looks like scaffolding to me... stuff that probably got inherited from some base class for utility (promotion, serialization, etc).

adaptusaaf wrote:
I tried, for example to click the MethodDe of the middle one, this one:...
Yeah, but what's your objective?

Quote:
but if I search for these bytes as an array in CE, it finds nothing.
Yar, that's weird. You've got the right idea, and you can verify that CE sees the same thing by just opening up the memory window and browsing to the same location. If nothing else, this would verify that you've got the right process opened. You can then try searching from the memory window - search -> find memory -> begin at 0, array. I think there could be some scan settings that might impede your search and they'd be bypassed for a search from here, but I'm not 100% sure. Alternatively, try making a simple aobscript that just sets a symbol at the location or something.

So, the big question is: if, from studying the disassembly previously, you already have the name of the method that you need to hook, then why aren't you just going directly to it in memory with name2ee? In your last couple of posts, it looks like you're trying to modify methods that you probably shouldn't. If you want a condition to always be true, change (or completely bypass) the equation rather than changing the meaning of equals.
Back to top
View user's profile Send private message
adaptusaaf
Advanced Cheater
Reputation: 0

Joined: 13 Jan 2008
Posts: 52

PostPosted: Thu Nov 28, 2013 3:34 pm    Post subject: Reply with quote

You were right, I should have been using !dumpmt -md on the MT of all 46 units (which have the same MT) which gives me the JIT methods for all units, for example, all units BonusHealth passes through the below CodeAddr (which is finally JIT compiled as opposed to PreJIT or NONE).

Code:
Normal JIT generated code
Game.Service.UnitData.set_BonusHealth(Int32)
Begin 037b8a68, size 3a
>>> 037b8a68 55              push    ebp
037b8a69 8bec            mov     ebp,esp
037b8a6b 56              push    esi
037b8a6c 8bf1            mov     esi,ecx
037b8a6e 8d4654          lea     eax,[esi+54h]
037b8a71 3910            cmp     dword ptr [eax],edx
037b8a73 90              nop
037b8a74 90              nop
037b8a75 90              nop
037b8a76 90              nop
037b8a77 0f94c0          sete    al
037b8a7a 0fb6c0          movzx   eax,al
037b8a7d 90              nop
037b8a7e 90              nop
037b8a7f 90              nop
037b8a80 90              nop
037b8a81 85c0            test    eax,eax
037b8a83 751a            jne     037b8a9f
037b8a85 895654          mov     dword ptr [esi+54h],edx
037b8a88 b96c6f0000      mov     ecx,6F6Ch
037b8a8d e8167af800      call    047404a8 (A.OM.A(Int32), mdToken: 06000050)
037b8a92 90              nop
037b8a93 90              nop
037b8a94 90              nop
037b8a95 90              nop
037b8a96 8bce            mov     ecx,esi
037b8a98 8bd0            mov     edx,eax
037b8a9a e8f9f7ffff      call    037b8298 (Game.Service.ActiveRecordOfUnitDataCGxnkJlm.RaisePropertyChanged(System.String), mdToken: 06000d67)
037b8a9f 5e              pop     esi
037b8aa0 5d              pop     ebp
037b8aa1 c3              ret


Searching for these bytes works in CE and matches perfectly.
So now my issue is finding out how to override the function with an arbitrary int32 value (such as 999 for bonus health) instead of what it is doing, which appears to be searching for the bonus health on the sql database where unit data is stored (I believe that is the "ActiveRecordOfUnitData" business) and getting the "correct" bonus health for each individual unit type.

I did try to use CE and use "what accesses this address" and other functions as normal, the problem is this code appears to only be called once - when you begin the game, because these values never change.

So my question is, how can I rewrite that series of opcodes to give all units a bonus health of some arbitrary number (999) instead of what it is doing?

Here is what that same code looks like in C#, in reflector:

Code:
public void set_BonusHealth(int value)
{
    if (!this.BonusHealthField.Equals(value))
    {
        this.BonusHealthField = value;
        string propertyName = OM.A(0x6f6c);
        base.RaisePropertyChanged(propertyName);
    }
}



EDIT:
I got a little further, by NOPing these two lines:

Code:
037b8a77 0f94c0          sete    al
037b8a7a 0fb6c0          movzx   eax,al


it sets all BonusHealth for all units to 0. So that must be it, but I wonder why?

EDIT2:
Actually, just NOPing one of those two lines breaks the function (all BonusHealth becomes 0), I'm not sure if it's just "breaking" the code below it so that it returns 0, or if this is the correct target opcodes.

The first one (sete al) is set byte if equal, according to CE,
the second (movzx eax,al) is move with zero-extend according to CE,
so I'm thinking, the integer value must be in eax at this moment, so what I need to do is write
sete al
inc eax, 999
movzx eax,al
right?

EDIT3:
I think those two opcodes just break the function, inc eax and inc al tests didn't work.
I also noticed that only one opcode has anything show up when I ask CE "what accesses this address" when I start a game, and that is this one:

Code:
037b8a71 3910            cmp     dword ptr [eax],edx


which looks like this in CE's view:

Code:
05833FCD - 89 56 54              - mov [esi+54],edx


so I'm tinkering with this now.. but it keeps crashing the game.

EDIT4:

it works! I just kept tinkering with it until it didn't crash, I still don't know what exactly is going on, but trial and error (slowly) works after all.. any explanations from more knowledgeable people as to why it worked would greatly help me, and thanks to justadude you're my favorite person this thanksgiving Smile


Last edited by adaptusaaf on Thu Nov 28, 2013 4:13 pm; edited 1 time in total
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Thu Nov 28, 2013 4:12 pm    Post subject: Reply with quote

Code:

lea     eax,[esi+54h]
mov eax,#999 //value = 999;
cmp     dword ptr [eax],edx //if (!this.BonusHealthFie...
...
Back to top
View user's profile Send private message
adaptusaaf
Advanced Cheater
Reputation: 0

Joined: 13 Jan 2008
Posts: 52

PostPosted: Thu Nov 28, 2013 4:16 pm    Post subject: Reply with quote

hmm, I don't see what you're doing there?
the only thing I did which worked is:
change
mov [esi+54],edx to mov [esi+54],000000FF (255, I was in a hurry didn't know how to wrtie 999 in hex lol)
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Fri Nov 29, 2013 3:45 am    Post subject: Reply with quote

Yar, I meant edx and typed eax. My bad. Glad you got it to work, though. Congrats.
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 891

PostPosted: Sat Nov 30, 2013 2:38 am    Post subject: Reply with quote

adaptusaaf wrote:

Here is what that same code looks like in C#, in reflector:

Code:
public void set_BonusHealth(int value)
{
    if (!this.BonusHealthField.Equals(value))
    {
        this.BonusHealthField = value;
        string propertyName = OM.A(0x6f6c);
        base.RaisePropertyChanged(propertyName);
    }
}



As an aside, because I just saw this construct in another game, I'll note that the "string propertyName = OM.A(0x6f6c);" probably looked more like "string propertyName = "unitHealth"; or something before being obfuscated. The .A(int) construct is from the EAZfuscator obfuscator.

The crazy bit is that the dude selling it (for quite a large sum, considering how useless it is) claims that it runs without impeding performance and that it even actually improves performance. He cites optimizations he makes to simple statements, but doesn't even touch on the impact a hack like the one above has on performance - the call you show might be called /many/ times each frame and the string-int conversion provided requires looking at the stack frames, loading assemblies, and all manner of other nonsense.
Back to top
View user's profile Send private message
DefaultUser
How do I cheat?
Reputation: 0

Joined: 05 Feb 2014
Posts: 3

PostPosted: Mon Feb 10, 2014 9:21 pm    Post subject: Reply with quote

I am new to cracking .NET games. I read through this little how-to and thought I would give it a shot.

I dl'd WinDbg from the link in your tutorial, did the full install, and followed the instructions from there. I have my address from CE for Health in Terraria.

I opened and attached windbg to Terraria. After the dml command, I tried to enter the ".loadby sos clr" command, i got no reply. I phrased it ".load sos clr", and got this reply.

The call to LoadLibrary(sos clr) failed, Win32 error 0n2
"The system cannot find the file specified."
Please check your debugger configuration and/or network access]


I searched around online and tried to figure out the problem. No luck.

I am new to WinDbg and pretty much a noob on CE as well, but not entirely without understanding. The last program I used was T-Search, and Trainer Maker Kit, back in.. oohh.. 2002-3 Smile So bare with me. I ask a lot of questions, but I learn quickly! lol
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites