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 


HowTo:Find/Change only my values, when 1 code writes to all!

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials
View previous topic :: View next topic  
Author Message
Zhoul
Master Cheater
Reputation: 1

Joined: 19 Sep 2005
Posts: 394

PostPosted: Sun Dec 04, 2005 8:51 am    Post subject: HowTo:Find/Change only my values, when 1 code writes to all! Reply with quote

http://forum.cheatengine.org/viewtopic.php?p=28308&sid=805b54b3ae77d226a164f67d31b58c1d#28308
...continued from the above thread. It started out as me asking a question, but then I realised, with a few modifications, it could also be a tutorial. The sad thing is: I could have probably answered my own questions in the time it took to write this. But hey, At least ya'll get a tutorial outta the deal. Cool

What does this tutorial cover?: Code Caves, and how to create and use them to determine when a piece of code that writes to all things (i.e. health) is reading/writing to your values, then act accordingly. More importantly, how not to use them. d0h!

WTFux is a Code Cave?: The word 'Cave' is used, because you are basically trying to find a place in memory where you can stash your own code. Auto-Assemble scripts are also a form of code caves and *much* easier to implement, then an old skewl code cave (as you'll find out below). Your next task is to find a piece of code that the game executes frequently, and create a jump or call to your code cave. Furthermore: You usually want to do this in an area of 'like' code, as you can use the registers in your calculations and evil haxXx

What game was used?: Need for Speed - Most Wanted - Black Edition (v1.2, outta the box, non-cracked).

Do I need the game to understand all this?: IMHO, the game isn't needed, but then again... I have it, so who am I to say? The description is indeed thick enough to gather at least the ideals.

What does the bedspreads for unintelligible means havening you are do?: You're asking the wrong guy... (bonus points to the person that can define the source of the non-word 'havening').
*note* - Using google to find this out would be considered cheating.
*note 2* - Using Cheat Engine on the instance of IE/Firefox that is using google to search for the answer wouldn't be cheating. It'd just be stupid.

What awesome hack is used as the example?: "No Collision Mode". Inspired by our very own cparty (tm).

"No Collision Mode" is something that a lot of games incorporate. It usually occurs when you do something like 'reset your car', or the first few seconds after spawning in a first person shooter. It gives the player the ability to pass through other player models, or any model in general (telephone poles, light posts, germans, cows). It's also usually accompanied by a highly annoying "blink" of the player characters model/car/goat/whatever. What we're going for here, is a way to toggle this ability on and off at will - specifically for the players car only. I quick-scripted a version of this previously, but as cparty pointed out... 'it's not working, and all the cars seem to be affected. p.s. Zhoul is Da MAN!' (or something to that effect). I later found that if all cars are in No Collision Mode, then they can infact, collide. Like having 2 separate dimensions that can see eachother. I thought it worked just fine, as I passed through both germans and cows with ease.

As for the method of picking out only the player to give no collision to, I've found many ways. At one point while debugging, I noticed that 2 registers held the same value, every time it was going to read/write to my value (and never the same, when writing to other cars). In this case, we can test and react, like so...

cmp edx, edi
"Compare" - to - "The Value of EDX" - the - "Value of EDI" ( We are comparing EDI *to* EDX in this example. This is important later on, if we use something like "Jump if above". In this case, EDI would have to be above EDX, in order to Jump if above)

I would then use the various jumps to re-direct the code.

JNE <address>
Jump if not equal.

JE <address>
Jump if equal

JA <address>
Jump if above

(There are at least 15 different types of jumps, those are just a few).

In another part of code, I noticed that register EDX happened to be 00000001, when writing to my value (and never 00000001, when writing to other cars). In this case, we can use cmp again... I like cmp, as opposed to test, simply because it usually takes up much less byte-space.

cmp edx, 01

I'd then use the various jumps to dictate the reaction.

Since this games code is 'packed in tight', leaving little room to work with, I'm currently trying to shrink down my 32 bytes of code, to a much simpler version. In most games, I can find a good 32 bytes of code-cave room, but that is proving difficult with a console ported to PC game. Until this point, I havn't considered jumping on the Alloc/AutoAssembler band wagon, as my goal is to produce trainers, quickly. As of late, I hear 5.2 supports these scripts in the trainer maker , w00t.

cparty - Are you any good with the auto-assembler? Would love to see an example in a game I've already hacked up. Not that I fear it in any way - I just like learning at a speed greater then light, when possible Idea Surely - 32 bytes of code would fit rather nicely in an alloc'd auto-assembled script, rather then scattered in between the crevices of game code.

If you (or anyone) is up to it, I offer a suggested point which you could use to 'inject' to, and the reasoning. This is also a mini-tutorial on the creation and use of code caves *and* how to determine who the code is affecting at any given time, as some people still can't grasp the idea that it's possible to determine just who is being affected by a piece of code that writes to a lot of entities/players/sheep/whatever.


Original Game Code Snippet: Raw Format: Suggested insertion point, as it is the 'first' code that reads/writes from/to our values, each cycle.
----------------------------------------------------------------------------------
0068c7c0 - push ecx
0068c7c1 - push esi
0068c7c2 - mov esi,ecx
0068c7c4 - mov ecx,[esi+0000015c]
0068c7ca - mov eax,[esi+00000174]
0068c7d0 - inc ecx
0068c7d1 - test eax,eax
0068c7d3 - There is a great deal of code past here, in this specific code block. Omitted because I never pass this point, with the modification.
----------------------------------------------------------------------------------

Original Game Code Snippet (same as avove): +Zhoul commentary...
----------------------------------------------------------------------------------
- 0068c7c0 - push ecx
First Line of code block, self explanitory.

- 0068c7c1 - push esi
Second Line of the code block (/yawn)

- 0068c7c2 - mov esi,ecx
ECX held the result of the pointer path for a while... He passes it on to ESI, as he has determined he has more important matters to deal with, then mere pointer holding. (If I were ESI, I'd throw an access violation on the spot, then have a word with General Protection)

- 0068c7c4 - mov ecx,[esi+0000015c]
I believe this line is reading 'what car we're currently dealing with', or is at least used to help determine 'current car', as it's incremented by 1 each 'cycle'. It has nothing to do with 'time'. Oddly, this is *not* the value I use to determine player VS other cars, as it doesn't start at 1 and appears to have a variable starting value as old cars are chucked from memory, and new ones added.

- 0068c7ca - mov eax,[esi+00000174]
This line reads either a 0 or 1 (4 byte value) from esi+174... 1, meaning "No Collision Enabled". Don't fool yourself. esi+174 is actually read later on *once more*. It'd be too easy, if it were only read once. There are also about 3 pieces of code that write 0 to the value (based on time expiration, etc).

Furthermore: The above line is the one that I over-write later, with a jump, as EDX, the register I use to determine if it's the players car or not, will soon be written to in just a few lines of code past this one, thus screwing this whole idea up.

+1 to ECX. Yay... This also happens to be the 6th line of code, for those keeping count. (dorks)
- 0068c7d0 - 41 - inc ecx

Is the current car currently in "No Collision" mode?
- 0068c7d1 - test eax,eax
- 0068c7d3 - From here forward, the code is applying most of what was read from memory, mostly checking to see if it's 'time' to remove the no collision property from the current car. I'd usually find the 1-2 jumps that need NOP'n or change'n, but there are to many calculations and jumps to deal with, especially since we're trying to single out the player, VS all the other cars.
----------------------------------------------------------------------------------

When creating a code cave, you obviously want to write the code that will be called or jumped to, in memory, before you change the original code, to call/jump to it. Why? Jumping to code that doesn't exist yet is hazardous to your game's health. If the code cave were a horse, then the jump to it, would surely be the cart.

32 bytes of Working Code.
----------------------------------------------------------------------------------
0ffd0e48 - (1-byte) - int 3
offd0e49 - (1-byte) - int 3
0ffd0e4a - (3-bytes) - cmp edx,01
0ffd0e4d - (2-bytes) - jne 0ffd0e5f
0ffd0e4f - (6-bytes) - mov [esi+00000174],edx
0ffd0e55 - (10-bytes) - mov [esi+00000178],40a00000
0ffd0e5f - (6-bytes) - mov eax,[esi+00000174]
0ffd0e65 - (1-byte) - ret
0ffd0e66 - (1-byte) - int 3
offd0e67 - (1-byte) - int 3
----------------------------------------------------------------------------------

Code Cave Commentary:
----------------------------------------------------------------------------------
The following 2 lines are 'padding'. Use padding just as the game uses padding, as bytes before code can actually change code. If you're confused about padding, just do it, dont worry about it, you'll figure out the why's when you get better with assembly.
0ffd0e48 - (1-byte) - int 3
offd0e49 - (1-byte) - int 3

So I found out that EDX, at least in the first few lines before it's used for other things, equals 1, when the code is working with 'my' car. Furthermore: I found that nearly *all* code executes on the player first, so you can usually find a register that = 1, or two registers that = the same thing (as seen in the 2nd insertion point, way below all this). I also believe that EDX being 1 here, is only a coincidence, because it is not used by the code to determine what car to read/write from/to. I find this happens in a lot of games though, so keep an eye out for it, as this is one method that can easily separate you... from the rest...

So, I compare edx to 1 to determine what route to go next. I would usually do this before the jump to a code cave, but there just wasn't enough room.
- 0ffd0e4a - cmp edx,01

If EDX does not equal 1, then jump to 0ffd0e5f (3 lines below). The code at that location happens to be the original 'read' code. This is my attempt at preserving the original code, while adding my own to it.
- 0ffd0e4d - jne 0ffd0e5f

If EDX was 1, then it will reach this point. These 2 lines of code below, could probably be done in much less 'byte space', I simply lack extensive kowledge with 'register pieces', such as al ax, etc, and the assembly used to work with them.

Their function?

Since we know that EDX is 1, and I need a 1 really bad right now, I use it to force-write the 'No Collision' flag to our car. This is my feeble attempt at preserving precious bytes of space, and time.
- 0ffd0e4f - mov [esi+00000174],edx

This line writes 5 (seconds), in 4-byte float form, to the value that determines the length of our 'No Collision" ability. Since it's looped every frame, I chose 5 seconds, so when the user disables it, they have 5 more seconds of invulnerability.
- 0ffd0e55 - mov [esi+00000178],40a00000

And finally, the original read code is applied. This is where the code will jump to, if EDX was not 1. Even if EDX was 1, it will eventually make it to this point as well.
- 0ffd0e5f - mov eax,[esi+00000174]
Why did we just duplicate code that already exists? Because we're going to replace the original, with a jump to this code block, here in just a minute.

Return to the code that called this code cave. As I wasn't sure where I'd put this code when I wrote it, I chose the call/return method.
- 0ffd0e65 - ret

These last 2 lines are end padding.
0ffd0e66 - (1-byte) - int 3
offd0e67 - (1-byte) - int 3

----------------------------------------------------------------------------------

Now that we have our code cave, we can now modify the original code to call it into action (erm, assuming we've found a nice home for the code-cave). We will replace this line 'mov eax,[esi+00000174]' , as it was re-created in the code-cave.

Modified Code:
0068c7c0 - push ecx < Same
0068c7c1 - push esi < Same again...
0068c7c2 - mov esi,ecx < Wouldn't want to change this one...
0068c7c4 - mov ecx,[esi+0000015c] < Or this one...
0068c7ca - call 0FFD0E4A <-- A-Ha.. A call to my new code cave.
0068c7cf - nop <--- <description for this line omitted. Reason: A haxX0r NOP'd it>
0068c7d0 - inc ecx <-- Same as before.
0068c7d1 - test eax,eax <--- unchanged as well.
0068c7d3 - I wouldn't touch anything past here, with a 10 foot debugger.

To get all this working... I would...
- Write my code cave first and foremost.
- Note the differences between the original code and the new code, in byte form, and use this as a 'trigger' or 'on/off' switch.
- For use in a trainer, I would have the "on" button write my code cave then write the jump/nop. The "off" button would restore the original bytes/code, *then* un-write the code cave. Note the reverse order, between on and off.
----------------------------------------------------------------------------------

- Here are the two addresses you want to add to CE's table.

Address: 0FFD0E48 (Array of Bytes - 32 in length)
Code Cave 1 - (Orig: 0000000000000000000000000000000000000000000000000000000000000000 New: CCCC83FA017510899674010000C786780100000000A0408B8674010000C3CCCC )

Address: 0068C7CA (Array of Bytes - 6 in length)
Code Cave Toggle - (Orig: 8B8674010000 New: E87B46940F90 )


- Change Code Cave 1 to it's new value.
- Change Code Cave Toggle to it's new value.
- Now you have infinite no collision mode
- If you want to turn it off, just change Code Cave Toggle back to its orig value.

- Z


Last edited by Zhoul on Wed Dec 07, 2005 10:44 pm; edited 16 times in total
Back to top
View user's profile Send private message AIM Address
cparty
Expert Cheater
Reputation: 0

Joined: 01 Dec 2005
Posts: 219

PostPosted: Sun Dec 04, 2005 9:44 am    Post subject: Reply with quote

Wow, many thanks Zhoul Smile
As I only discovered CE a few days ago, I'm not yet familiar with code caves and auto assembler scripts, but I hope to get there soon.
Back to top
View user's profile Send private message
Zhoul
Master Cheater
Reputation: 1

Joined: 19 Sep 2005
Posts: 394

PostPosted: Sun Dec 04, 2005 10:50 am    Post subject: Reply with quote

cparty wrote:
Wow, many thanks Zhoul Smile
As I only discovered CE a few days ago, I'm not yet familiar with code caves and auto assembler scripts, but I hope to get there soon.


Code Caves and especially Auto Assembler are your boon, where as pointer paths (in games not ported from console) will surely be your bane at first, so get as much info on them as ye can.

cparty feigns ignorance wrote:
As I only discovered CE a few days ago, I'm not yet familiar with...

Surely, you were already a coder, at least to some extent Wink I myself picked up CE only a few months back, so you'll get there sooner then you think, maybe faster then you could hope, and possibly quicker then you could ever dream. There is a certain thrill in disassembling code, after having assembled it for so many years.

Keep posting here: You seem to give me Idea ideas Idea for Question some Question reason, most likely because of the two opposite Razz sides Twisted Evil we approach a situation. Cool
Back to top
View user's profile Send private message AIM Address
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Tue Dec 06, 2005 3:46 am    Post subject: Reply with quote

Nice job and hella big motha tutorial Smile. I have a new way of passing through all this, which is simpler than what you're always using. I'm using the stack, while you use a register compare and write the ammount of seconds...

See this :

cmp xxx,xxx
jne xxxxxx
mov [eax+00000178],40a00000
jmp main

That's what you're using. Let me ask you this. Then, if all cars had ECX=1, what would you do ? Dun tell me you woulda looked for other registers; assuming they all use same stuff...

My solution :

mov [eax+00000174],edx
push edx [to stack]
***
do the compare stuff here, related to stack positions on break [u'll need windowed mode :S - i wish some1 fixed the bloody xp vga ints]
***
pop edx
jmp main

I'll do that at home, following your tutorial, and also post the 'stack' solution Wink Again, swell job...
Back to top
View user's profile Send private message
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Wed Dec 07, 2005 7:09 am    Post subject: Reply with quote

Yellow belly, it works, just pay more attention next time :

0ffd0e4a - (3-bytes) - cmp edx,01
0ffd0e4d - (2-bytes) - jne 0ffd0e5f
0ffd0e4f - (6-bytes) - mov [eax+00000174],edx // eax -> esi
0ffd0e55 - (10-bytes) - mov [eax+00000178],40a00000 // eax -> esi
0ffd0e5f - (6-bytes) - mov eax,[esi+00000174]
0ffd0e65 - (1-byte) - ret

Out...
Back to top
View user's profile Send private message
Zhoul
Master Cheater
Reputation: 1

Joined: 19 Sep 2005
Posts: 394

PostPosted: Wed Dec 07, 2005 6:57 pm    Post subject: Reply with quote

SunBeam wrote:
Yellow belly, it works, just pay more attention next time :

0ffd0e4a - (3-bytes) - cmp edx,01
0ffd0e4d - (2-bytes) - jne 0ffd0e5f
0ffd0e4f - (6-bytes) - mov [eax+00000174],edx // eax -> esi
0ffd0e55 - (10-bytes) - mov [eax+00000178],40a00000 // eax -> esi
0ffd0e5f - (6-bytes) - mov eax,[esi+00000174]
0ffd0e65 - (1-byte) - ret

Out...


So what you're saying is that it does work, I just accidentally was using EAX instead of ESI?

Not that I'd be dumb enough to re-create the code again, using EAX, it was just a mistake on my part, right right?

I changed the places in the tutorial where I acceidentally used EAX instead of ESI. Now, to test it out and mod the tutorial saying it works, if indeed it does.

SunBeam wrote:
[u'll need windowed mode :S - i wish some1 fixed the bloody xp vga ints]

No I won't. Not since I use 2 PC's, remote desktop'n from my 2nd to my 1st.

P.S. - I had been up for about 48 hours when I created this - and when I wrote the tutorial Wink Gimme a break....
Back to top
View user's profile Send private message AIM Address
Zhoul
Master Cheater
Reputation: 1

Joined: 19 Sep 2005
Posts: 394

PostPosted: Wed Dec 07, 2005 7:31 pm    Post subject: Reply with quote

0068c7c9 - call 0FFD0E49 <-- A-Ha.. A call to my new code cave. *CRASH* Wink


This line was also wrong, but only by 1 character...

You see, when I was testing this, I had offset the entire code block by 1, so it started on an even number...

It should be...


0068c7ca - call 0FFD0E4A <-- A-Ha.. A call to my new code cave. *No More Crash* Wink


I have changed the tutorial a bit, but will modify it to state that it does work. I am currently 'testing' this right now, and everything is working as it should.

--------------------------------------------------------------
Working!!
--------------------------------------------------------------

Address: 0FFD0E48 (Array of Bytes - 32 in length)
Code Cave 1 - (Orig: 0000000000000000000000000000000000000000000000000000000000000000 New: CCCC83FA017510899674010000C786780100000000A0408B8674010000C3CCCC )

Address: 0068C7CA (Array of Bytes - 6 in length)
Code Cave 2 - (Orig: 8B8674010000 New: E87B46940F90 )

*Edit*

Tutorial has been updated. Tutorial should work, unless there is some kind of other over-sight. SunBeam found one, I found another in the previous tutorial. sunbeam, care to run through it and see if I left something out? Everything is working great on my side.
Back to top
View user's profile Send private message AIM Address
SunBeam
I post too much
Reputation: 65

Joined: 25 Feb 2005
Posts: 4022
Location: Romania

PostPosted: Thu Dec 08, 2005 8:17 am    Post subject: Reply with quote

No comment, all fine Wink Just the freakin' blink bug, that lets the police catch you Smile... Working on it...
Back to top
View user's profile Send private message
Zhoul
Master Cheater
Reputation: 1

Joined: 19 Sep 2005
Posts: 394

PostPosted: Thu Dec 08, 2005 11:58 pm    Post subject: Reply with quote

SunBeam wrote:
No comment, all fine Wink Just the freakin' blink bug, that lets the police catch you Smile... Working on it...


There's a lotta ways to work this one out. One thing I've found is that it's surely the 'distance' from you to the cop that determines the rate at which they catch you. So of course, if you cannot be 'hit' due to no-collide, they catch you damn near instantly as they pass through your car. I found in mem, 4 byte values that determine their distance from you to them. Unfortunately, I was working on something else at the time and crashed before I had a chance to find out what writes to those values. I would guess that killing the updates to these numbers, or writing larger numbers to the values would fix that issue entirely. I just havn't had time to re-investigate it.

The 4 byte values decrease as a copper nears your location.

There's gotta be another value that determines if the cop can see you or not, but I'm guessing the 'distance' calculation over-rides this.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials All times are GMT - 6 Hours
Page 1 of 1

 
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