|
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: Fri Nov 22, 2013 12:02 pm Post subject: |
|
|
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.
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 |
|
|
adaptusaaf Advanced Cheater Reputation: 0
Joined: 13 Jan 2008 Posts: 52
|
Posted: Tue Nov 26, 2013 8:25 am Post subject: |
|
|
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 |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25295 Location: The netherlands
|
Posted: Tue Nov 26, 2013 8:49 am Post subject: |
|
|
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 |
|
|
adaptusaaf Advanced Cheater Reputation: 0
Joined: 13 Jan 2008 Posts: 52
|
Posted: Tue Nov 26, 2013 8:02 pm Post subject: |
|
|
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 |
|
|
adaptusaaf Advanced Cheater Reputation: 0
Joined: 13 Jan 2008 Posts: 52
|
Posted: Thu Nov 28, 2013 2:28 am Post subject: |
|
|
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 |
|
|
Hatschi Master Cheater Reputation: 2
Joined: 28 Jan 2010 Posts: 327
|
Posted: Thu Nov 28, 2013 4:43 am Post subject: |
|
|
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 |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Thu Nov 28, 2013 5:40 am Post subject: |
|
|
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 |
|
|
adaptusaaf Advanced Cheater Reputation: 0
Joined: 13 Jan 2008 Posts: 52
|
Posted: Thu Nov 28, 2013 1:26 pm Post subject: |
|
|
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 |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Thu Nov 28, 2013 2:52 pm Post subject: |
|
|
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 |
|
|
adaptusaaf Advanced Cheater Reputation: 0
Joined: 13 Jan 2008 Posts: 52
|
Posted: Thu Nov 28, 2013 3:34 pm Post subject: |
|
|
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
Last edited by adaptusaaf on Thu Nov 28, 2013 4:13 pm; edited 1 time in total |
|
Back to top |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Thu Nov 28, 2013 4:12 pm Post subject: |
|
|
Code: |
lea eax,[esi+54h]
mov eax,#999 //value = 999;
cmp dword ptr [eax],edx //if (!this.BonusHealthFie...
...
|
|
|
Back to top |
|
|
adaptusaaf Advanced Cheater Reputation: 0
Joined: 13 Jan 2008 Posts: 52
|
Posted: Thu Nov 28, 2013 4:16 pm Post subject: |
|
|
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 |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Fri Nov 29, 2013 3:45 am Post subject: |
|
|
Yar, I meant edx and typed eax. My bad. Glad you got it to work, though. Congrats.
|
|
Back to top |
|
|
justa_dude Grandmaster Cheater Reputation: 23
Joined: 29 Jun 2010 Posts: 891
|
Posted: Sat Nov 30, 2013 2:38 am Post subject: |
|
|
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 |
|
|
DefaultUser How do I cheat? Reputation: 0
Joined: 05 Feb 2014 Posts: 3
|
Posted: Mon Feb 10, 2014 9:21 pm Post subject: |
|
|
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 So bare with me. I ask a lot of questions, but I learn quickly! lol
|
|
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
|
|