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 


Comparison Instruction Not Working as Expected
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Tue Oct 01, 2024 4:53 pm    Post subject: Comparison Instruction Not Working as Expected Reply with quote

Could someone tell me why the 2nd comparison code below is not working?

The first one works, but the offset always changes any time the game is restarted, so I tried something different with the 2nd comparison.

1st Comparison:

Code:
 cmp [ebx+5CE70EC],1
  je code
  jmp return
code:
  mov [ebx+05CE70A0],eax
  jmp return


I have a health pointer, so I figured I could use it somehow in my script, just needed to figure out how. So, I found a way thanks to the CE Help guide.

The suggestion was something like this:
Code:
lea eax,[[[[[["Executable.exe"+00123ABC]+4]+56]+0]+789]+DEF]


For my script I needed to add an offset of 0x4C to get to the "Team" address.
The disassembler shows it's pointing to the correct "Team" address, so at least I know it's working and reading the correct address, though it seems the compare instruction is failing. I'm assuming it must be storing the address of the pointer rather than the value, and thus the cmp is always false.

2nd Comparison:

Code:
 lea ecx,[["ioquake3.x86.exe"+01995A88]+604+4c]
  cmp ecx,1
  je code
  jmp return
code:
  mov [ebx+05CE70A0],eax
  jmp return


But now for whatever reason, nobody dies. It's as if the "value" of ecx is not being compared correctly.
The disassembler shows the correct address for the "team" value, as I've pasted it here:
8D 0D 40E7CF05 - lea ecx,[05CFE740]

And when I add this 05CFE740 address to the address list, it shows the correct team number.

So why might the 2nd comparison not be working correctly?
Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 240

PostPosted: Tue Oct 01, 2024 5:27 pm    Post subject: Reply with quote

First I can see two mistakes here:
Quote:
Code:
 lea ecx,[["ioquake3.x86.exe"+01995A88]+604+4c]


First thing, 604+4C = 650 Did you mean you put 650 or did you mean to put 604]+4C]

Second, using LEA (Load effective address) would give the address of this pointer and not its content. And I assume you need its content to compress like the first example. Use MOV instruction instead to get the content of your pointer.

And, fix the offsets if that was needed.
Also for further inspection, you can put a breakpoint at the instruction to see what's going on and if everything is going as expected

You can watch YouTube to learn more in-depth
Back to top
View user's profile Send private message Visit poster's website
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Tue Oct 01, 2024 6:50 pm    Post subject: Reply with quote

Game Hacking Dojo wrote:
First I can see two mistakes here:
Quote:
Code:
 lea ecx,[["ioquake3.x86.exe"+01995A88]+604+4c]


First thing, 604+4C = 650 Did you mean you put 650 or did you mean to put 604]+4C]

Second, using LEA (Load effective address) would give the address of this pointer and not its content. And I assume you need its content to compress like the first example. Use MOV instruction instead to get the content of your pointer.

And, fix the offsets if that was needed.
Also for further inspection, you can put a breakpoint at the instruction to see what's going on and if everything is going as expected

You can watch YouTube to learn more in-depth


Yes, the +604+4c] is intentional, as it's just an offset to the "team" value that I use for the cmp instruction.

I realized after posting that using lea will grab the address, rather than the value, so I have changed it, though for some reason it's still pulling all zeros for the ecx register I'm using.

I verified it by setting a break on the instruction. Originally, it was showing the address as expected, but now with using the mov, it's showing all zeros, though no matter if I'm shooting the enemy or if he is shooting me.

Here are two pics of the break as I step through it. This is from shooting the enemy, so ecx should equal 1 for "enemy team" as it worked for the first comparison, but you can clearly see it never changes from 00000000.

Also, the EBX value that is used with all the health, shields, etc appears to never change from 17654. So it’s easy to deduct what the changing offset is by just subtracting the Health Pointer address from the EBX value, as it equals the offset value.



Shooting enemy, ECX should equal 1.PNG
 Description:
Step 1: Shooting enemy, ECX should equal 1
 Filesize:  16.8 KB
 Viewed:  3902 Time(s)

Shooting enemy, ECX should equal 1.PNG



Shooting enemy, ECX still equals 0.PNG
 Description:
Step 2: Shooting enemy, ECX still equals 0
 Filesize:  16 KB
 Viewed:  3902 Time(s)

Shooting enemy, ECX still equals 0.PNG


Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 147

Joined: 06 Jul 2014
Posts: 4570

PostPosted: Wed Oct 02, 2024 12:20 am    Post subject: Reply with quote

Quote:
Code:
lea eax,[[[[[["Executable.exe"+00123ABC]+4]+56]+0]+789]+DEF]
Instructions like that kind of work but not really

That pointer path gets evaluated when the AA script is assembled and not at runtime. Sometimes this is fine, but if any node in the pointer path changes, this won't work

Traverse the pointer path at runtime:
Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+650]
cmp ecx,1
...
If that doesn't work, try this:
Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+604]
mov ecx,[ecx+4C]
cmp ecx,1
...

If it still doesn't work, set a breakpoint at the first `mov` instruction and step through the code to see the pointer path get evaluated at runtime. Contrast that against the working pointer in the address list (double click the address field in the address list).

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 240

PostPosted: Wed Oct 02, 2024 9:45 am    Post subject: Reply with quote

Thanks to ParkourPenguin I realised that I forgot to tell you to never dereference a pointer in one line.

And his first example (I believe) should fix it
Back to top
View user's profile Send private message Visit poster's website
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Wed Oct 02, 2024 4:47 pm    Post subject: Reply with quote

ParkourPenguin wrote:
Quote:
Code:
lea eax,[[[[[["Executable.exe"+00123ABC]+4]+56]+0]+789]+DEF]
Instructions like that kind of work but not really

That pointer path gets evaluated when the AA script is assembled and not at runtime. Sometimes this is fine, but if any node in the pointer path changes, this won't work

Traverse the pointer path at runtime:
Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+650]
cmp ecx,1
...
If that doesn't work, try this:
Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+604]
mov ecx,[ecx+4C]
cmp ecx,1
...

If it still doesn't work, set a breakpoint at the first `mov` instruction and step through the code to see the pointer path get evaluated at runtime. Contrast that against the working pointer in the address list (double click the address field in the address list).


I thought this might help, but it didn't; it actually causes the game to crash, and I tried multiple times making sure I didn't mistype anything.

The mov ecx,[ecx+650] crashes, but if I do the mov ecx,[ecx+604], it doesn't crash, at least not until I add the mov ecx,[ecx+4C].

I noticed when stepping through it, the ecx register for the mov ecx,[ecx+604] was showing my health value, which is correct, but as soon as the next offset of +4C is read (team player), it always crashes!

I did some more experimenting, and I think I have narrowed the issue down, but it's beyond me with my limited knowledge of ASM how to resolve it.

I started thinking, why is the compare always false or equal to 0, then it dawned on me. The cmp ecx,1 which remember 1 = the ENEMY Team, is always comparing itself to the address at ["ioquake3.x86.exe"+01995A88]+604+4C]. This address is the value of the player's team or my team, which is 0. So, the above compare instruction is always going to fail to equal 1.

But then that got me thinking...how does it work in my first comparison I provided. It too, uses the same or very similar comparison like so: cmp [ebx+5EBE0EC],1
And that also points to my team/player's team, but yet it can somehow differentiate between the teams getting shot. Remember, the only reason I'm not using it is because the offset 5EBE0EC in the cmp changes with every restart of the game, hence why I'm trying to insert a PTR to get around it.

So anyways, I tested my theory, and it worked, which is not good, though I guess it narrows down what the issue is hopefully.

I changed the mov ecx,["ioquake3.x86.exe"+01995A88]+604+4C] to point to the Enemy Team's address, and now every one dies, because we are all treated as the enemy. Just as the other way, no one dies, because we are all treated as the player.


Any suggestions on how I might be able to resolve this?

Thanks!
Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 240

PostPosted: Wed Oct 02, 2024 5:58 pm    Post subject: Reply with quote

Try this one, this must be the safest version and it shouldn't crash:
Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
cmp [ecx+650],1


Let's see if this works


If it doesn't work show us the assembly around the injection point
Back to top
View user's profile Send private message Visit poster's website
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Thu Oct 03, 2024 11:59 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
Try this one, this must be the safest version and it shouldn't crash:
Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
cmp [ecx+650],1


Let's see if this works

If it doesn't work show us the assembly around the injection point


I tried your suggestion, and it did not crash, though the compare still is not working correctly as no one can die.

After stepping through the breakpoint, I noticed the value of ECX was all zeros for the first instruction mov ecx,["ioquake3.x86.exe"+01995A88]
I'm still learning, but is the instruction processed on the same line, or only after stepping in to the next instruction?

For the 2nd step, the cmp [ecx+650],1 the ECX value was 05DE80F0, which is the current base address for my player's health (add 0x604 get's my player's actual health, and add 0x4C to that to get my player's team).

Anyhow, I thought it was odd that ECX was only showing the base health address; it's as if it's not processing or calculating the +650.

To test this, I tried it as cmp [ecx+604],1 and also as cmp [ecx],1.

Both times ECX still equaled my base address for health 05DE80F0. It never changed! Any thoughts on this?

As requested, here is a snapshot of the instructions around the injection point:

Again, thanks for trying to help with this. I will understand if you have better things to do than look over a bunch of ASM code for a stranger Smile



Assembly around the injection point.PNG
 Description:
 Filesize:  87.52 KB
 Viewed:  3723 Time(s)

Assembly around the injection point.PNG


Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 240

PostPosted: Thu Oct 03, 2024 4:01 pm    Post subject: Reply with quote

First, I think you're trying to solve a problem ahead of your level.

The problem is easy to solve I believe.

an instruction like mov/cmp [ecx+650],1 won't change the value of ecx or compare to it. It will compare the or move into the content of ecx+650

Let's say ecx = 0x1000 a cmp instruction will calculate the sum of ecx + 0x650 and go to that address to see what it contains. But never changes the content of the register (the 0x1000 in this example)

I want you to go to the compression line cmp [ecx+650],1 right click it and choose "Find out what addresses this instruction accesses"

Play the game and get to the point where this line gets executed to see what these addresses are. This way you can have a better idea of what is happening here in real time.

You can also right-click the addresses that have populated in the window and choose "Show registers" to see what the registers were holding at the first time of execution

If you failed in achieving your goal show me a screenshot of the mess I just described

Keep me updated let's see
Back to top
View user's profile Send private message Visit poster's website
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Fri Oct 04, 2024 12:23 pm    Post subject: Reply with quote

Game Hacking Dojo wrote:
First, I think you're trying to solve a problem ahead of your level.

The problem is easy to solve I believe.

an instruction like mov/cmp [ecx+650],1 won't change the value of ecx or compare to it. It will compare the or move into the content of ecx+650

Let's say ecx = 0x1000 a cmp instruction will calculate the sum of ecx + 0x650 and go to that address to see what it contains. But never changes the content of the register (the 0x1000 in this example)

I want you to go to the compression line cmp [ecx+650],1 right click it and choose "Find out what addresses this instruction accesses"

Play the game and get to the point where this line gets executed to see what these addresses are. This way you can have a better idea of what is happening here in real time.

You can also right-click the addresses that have populated in the window and choose "Show registers" to see what the registers were holding at the first time of execution

If you failed in achieving your goal show me a screenshot of the mess I just described

Keep me updated let's see


Probably more like "ahead of my level" x2, if not more. I mean I don't want to discredit myself too much as I have done a few script comparisons and other small tweaks with other games that worked.

Also, thanks for sticking with me so far. I would have replied sooner, but I'm not allowed yet to double post which I believe is 8 hours.

I don't know if this is important but I remember reading somewhere that Quake 3 Arena is ran in a VM and uses Bytecode, though I have no idea if that makes it more or less difficult to write scripts for it in CE.

I did the "Find out what addresses this instruction accesses" on the cmp [ecx+650],1 instruction.

There is only one address shown to be accessed, and the counter for it counts up anytime I damage myself, I shoot the enemy, or when the enemy shoots me. So basically, anytime someone is getting shot at, this address is accessed.

I did it individually for when I shoot the enemy, and the enemy shoots me, and attached the two screenshots. They are very similar and only the EAX and EBX values change. I feel like it probably won't be very helpful since it's only one address, but keeping my fingers crossed.


Quick Note:

Regarding the original instruction from the game, mov [ebx+05EBE0A0],eax the offset which is currently 0x05EBE0A0 is the only part of the instruction that changes each game or restart.

And this offset can easily be calculated for a new game, so if you or someone knows how to implement it in a script somehow, then I could just use the 1st compare method that I originally provided that works.


The simple calculation:

Health PTR Address - 0x17654 = Changing Offset + 4C The 0x4C is for the Team Player offset.

You may wonder where the 0x17654 value came from. The MOV instruction above that is always written to when attacked or attacking an enemy, stores this 0x17654 value in EAX. And so far it has never changed for this instruction.

Any thoughts on this approach?



q3-enemy_shooting_me.PNG
 Description:
 Filesize:  13.27 KB
 Viewed:  3626 Time(s)

q3-enemy_shooting_me.PNG



q3-me_shooting_enemy.PNG
 Description:
 Filesize:  9.67 KB
 Viewed:  3626 Time(s)

q3-me_shooting_enemy.PNG


Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 240

PostPosted: Fri Oct 04, 2024 2:08 pm    Post subject: Reply with quote

Is the address populated in the window the same address representing your team? It would help if you had that added to your address list to check against

You don't need to calculate anything just reassemble().
To include the original code despite it changing you can use the reassemble()

reassemble() reassembles the line at the given address

example:
Code:
aobscan(name_of_the_script, 48 51 52 53 EB)
registersymbol(name_of_the_script)
...
originalCode:
reassemble(name_of_the_script)
reassemble(name_of_the_script + 4)    //hex
...
Back to top
View user's profile Send private message Visit poster's website
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Sat Oct 05, 2024 10:54 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
Is the address populated in the window the same address representing your team? It would help if you had that added to your address list to check against

You don't need to calculate anything just reassemble().
To include the original code despite it changing you can use the reassemble()

reassemble() reassembles the line at the given address

example:
Code:
aobscan(name_of_the_script, 48 51 52 53 EB)
registersymbol(name_of_the_script)
...
originalCode:
reassemble(name_of_the_script)
reassemble(name_of_the_script + 4)    //hex
...


I do have the player's team address, as well as the enemy's team address saved to the Address List.
No, that 0x0090609D is not the player's team. Currently the player's team is 0x05E640EC. The 0x0090609D address is in a much lower range of memory compared to the others, and is mostly just 00 00 add [eax],al instructions. So, I'm not sure why it's accessing this address. Your thoughts? Also, I noticed it does not change, as I have reboot the PC since, and today I tried it again, and it's the same address.

I'm not familiar with the reassemble() function. I'll have to read up on it and see if it's something I can do at my level.



q3_address is blank in memory.png
 Description:
 Filesize:  11.92 KB
 Viewed:  3526 Time(s)

q3_address is blank in memory.png


Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 240

PostPosted: Sat Oct 05, 2024 11:06 am    Post subject: Reply with quote

So now we know what the problem is. You are not dereferencing the pointer correctly resulting in a wrong address. To solve this problem have the address you want to mimic in the address list open see its base address and offsets. Write a level at a time in the script and check if the destination is the matching the correct one.

Cheat Engine provides you with a clear view of how the pointer is dereferenced in real-time. You can see that next to each offset. Compare your script dereferencing route to this using breakpoints.



Screenshot 2024-10-05 190101.png
 Description:
 Filesize:  24.38 KB
 Viewed:  3521 Time(s)

Screenshot 2024-10-05 190101.png


Back to top
View user's profile Send private message Visit poster's website
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Sat Oct 05, 2024 12:13 pm    Post subject: Reply with quote

Game Hacking Dojo wrote:
So now we know what the problem is. You are not dereferencing the pointer correctly resulting in a wrong address. To solve this problem have the address you want to mimic in the address list open see its base address and offsets. Write a level at a time in the script and check if the destination is the matching the correct one.

Cheat Engine provides you with a clear view of how the pointer is dereferenced in real-time. You can see that next to each offset. Compare your script dereferencing route to this using breakpoints.


Could the way my Team Player PTR is setup be contributing to the issue of my script dereferencing the wrong address?

Here's a snapshot of it. I know it doesn't look typical, but that is how I always get the correct address to my team player.



q3-team player PTR.PNG
 Description:
 Filesize:  8.76 KB
 Viewed:  3508 Time(s)

q3-team player PTR.PNG


Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 240

PostPosted: Sat Oct 05, 2024 12:56 pm    Post subject: Reply with quote

This doesn't seem to be the same as you shared with us the first time
This is how you dereference this in assembly:

Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
cmp [ecx-17004],1     // -(17654-604-4C) = -(17004)
...
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 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