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 Previous  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 08, 2024 9:40 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
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)
...


I apologize, that is actually one of my earlier pointers that I thought pointed to the player's team. Though, I did try it, but of course nobody died.

I did a Dissect Data/Structures on the health address for the player and the enemy, and the results confirm the original offsets are correct as you can see in the snapshot provided.

I also provided snippets of the PTRs for Player Health and the Enemy Health so you can confirm if I used them correctly in Dissect Data.

Group1=Player & Group2=Enemy

Hope this helps clear up any confusion. If it doesn't, and you're ready to jump ship, I will understand. Thanks again!



q3-enemyHealth.PNG
 Description:
 Filesize:  6.74 KB
 Viewed:  3878 Time(s)

q3-enemyHealth.PNG



q3-playerHealth.PNG
 Description:
 Filesize:  6.67 KB
 Viewed:  3878 Time(s)

q3-playerHealth.PNG



q3-dissect data-PlyerandEnemyTeam.PNG
 Description:
 Filesize:  28.71 KB
 Viewed:  3878 Time(s)

q3-dissect data-PlyerandEnemyTeam.PNG


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

Joined: 17 Sep 2023
Posts: 229

PostPosted: Tue Oct 08, 2024 9:58 am    Post subject: Reply with quote

There is a problem with the logic of your script. You're always comparing a constant value against another constant. You're dereferencing the team of your player which is going to stay the same and has to (otherwise there's another problem with the logic) against 0 or 1 (whatever that number is)

What you have to do is at the injection point check if the team of the entity processed by the instruction matches your team or not.

And that should be like this

Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+650]
cmp[ebx+05CE70A0],ecx   //assuming you're comparing against the base address of the entity held by (ebx) plus the offset to the team address
je ....


ebx must be changing and cycling through all the entities for this script to work. Or at least all the entities may be processed through this institution by some game triggers (shooting, jumping, killing, etc)
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 08, 2024 10:55 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
There is a problem with the logic of your script. You're always comparing a constant value against another constant. You're dereferencing the team of your player which is going to stay the same and has to (otherwise there's another problem with the logic) against 0 or 1 (whatever that number is)

What you have to do is at the injection point check if the team of the entity processed by the instruction matches your team or not.

And that should be like this

Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+650]
cmp[ebx+05CE70A0],ecx   //assuming you're comparing against the base address of the entity held by (ebx) plus the offset to the team address
je ....


ebx must be changing and cycling through all the entities for this script to work. Or at least all the entities may be processed through this institution by some game triggers (shooting, jumping, killing, etc)


Interesting, because I had touched on that in my 6th post, but you never responded to that part so I figured it wasn't really an issue. And I'm still confused how my first compare script is able to differentiate between the teams using that one compare instruction, while these alternative attempts seem to compare it only as a constant.

I tried to use your suggestion, but I get a warning that not all code is injectable, and it's pointing at your compare instruction. Also, I changed your 05CE70A0 to the current changing offset, 05D070A.



q3-script injection error.PNG
 Description:
 Filesize:  34.49 KB
 Viewed:  3858 Time(s)

q3-script injection error.PNG


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

Joined: 17 Sep 2023
Posts: 229

PostPosted: Tue Oct 08, 2024 11:51 am    Post subject: Reply with quote

I didn't say anything about it the first time because I didn't know what the approach was. When you want a problem solved next time post the whole script and code snapshot (especially if you're a beginner) so we know what is happening and where the issue is.

I thought at first that the pointer points to something dynamic. And I expected you to know enough to deal with logic.

What I have written is just an example and I don't know where the entities' base addresses are. That's something you have to know and you have to figure out. As I've told you, you're already trying to do something way ahead of your level.

You have to see in which register at this point holding which entity's base address and then you know that that register holds involved entities is x register and you compare to that like so:

Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+650]
cmp [x+650[,ecx
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 09, 2024 11:15 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
I didn't say anything about it the first time because I didn't know what the approach was. When you want a problem solved next time post the whole script and code snapshot (especially if you're a beginner) so we know what is happening and where the issue is.

I thought at first that the pointer points to something dynamic. And I expected you to know enough to deal with logic.

What I have written is just an example and I don't know where the entities' base addresses are. That's something you have to know and you have to figure out. As I've told you, you're already trying to do something way ahead of your level.

You have to see in which register at this point holding which entity's base address and then you know that that register holds involved entities is x register and you compare to that like so:

Code:
mov ecx,["ioquake3.x86.exe"+01995A88]
mov ecx,[ecx+650]
cmp [x+650[,ecx


It sucks being a beginner because you're not always sure what or how to ask for help and how much information to provide without overwhelming anyone. I do hate that I may have made it more involved than it needed to be because it was definitely not my intentions. Obviously, I need to learn more about this subject, and honestly I'm trying; it's just a lot to take in.

When you say I need to find the entity base addresses, I assume that means I need to find a PTR for them? If so, then I already have it as explained below.

Is the following approach for PTRs frowned upon?

Instead of finding PTRs for all the entities, I figured I could just find one, like health. Then I could copy it multiple times, and then edit the offsets so they point to the other entities like armor, ammo, the enemy, etc. That's what I've been doing, and it seems to work fine for me now, but I'm curious if it will make things more complicated going forward?

One last thing regarding the differences between the two compare instructions that caught my attention yesterday, though I couldn't post about it b/c I'm still not allowed to double post yet.

Remember that offset for Team Player that I said was a mistake a few posts back? I now see where I got that offset of 604-17654+4C for Team Player, and I don't think it's actually wrong.

If you take the Changing Offset and add 0x4C to it, it supposedly gives you the Team Player. I say "supposedly" only because I was confident the Dissect Data image I posted confirms it's a different address, yet when I use the original compare instruction (the one that works), it's actually using these offsets 604-17654+4C from the Player's Health address. And this address is different than the one Dissect Data shows, which is only +0x4C from Player's Health address.

So, how does the first compare script work by using Player's Health+604-17654+4C?
And since it does work, then doesn't that mean I should be using the 604-17654+4C offsets, even though Dissect Data shows its only +0x4C from Player's Health?

Interestingly, these two different Team Player's addresses have a difference of 0x17654. The same as the middle offset above.
Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 229

PostPosted: Wed Oct 09, 2024 1:15 pm    Post subject: Reply with quote

My solution to you is, to take a rest from this. As you said you're trying to learn but it's overwhelming and difficult to know where to start. I'd say if you're interested then you will learn it. But you have to be patient On this forum you can learn a lot of random things. But if you want to learn a good portion then watch tutorials. I make videos on YouTube you can start there knowing that I might not be the best at representing but I'm good enough to teach computer science.

https://www.youtube.com/@GameHackingDojo

Once, you've learnt enough you can ask me again and I'll be pleased to answer you.
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 09, 2024 2:26 pm    Post subject: Reply with quote

Game Hacking Dojo wrote:
My solution to you is, to take a rest from this. As you said you're trying to learn but it's overwhelming and difficult to know where to start. I'd say if you're interested then you will learn it. But you have to be patient On this forum you can learn a lot of random things. But if you want to learn a good portion then watch tutorials. I make videos on YouTube you can start there knowing that I might not be the best at representing but I'm good enough to teach computer science.

Once, you've learnt enough you can ask me again and I'll be pleased to answer you.


Thanks! I will definitely check them out! And thanks again for staying with me as long as you did. Much appreciated!
Back to top
View user's profile Send private message
Modify_This
Newbie cheater
Reputation: 0

Joined: 24 Sep 2024
Posts: 23

PostPosted: Fri Oct 11, 2024 9:29 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
My solution to you is, to take a rest from this. As you said you're trying to learn but it's overwhelming and difficult to know where to start. I'd say if you're interested then you will learn it. But you have to be patient On this forum you can learn a lot of random things. But if you want to learn a good portion then watch tutorials. I make videos on YouTube you can start there knowing that I might not be the best at representing but I'm good enough to teach computer science.

https://www.youtube.com/@GameHackingDojo

Once, you've learnt enough you can ask me again and I'll be pleased to answer you.


Good news!

After watching some of your videos, specifically the "Resident Evil 4 Remake Infinite Health Part 2" that talks about using the registers for comparison, finally helped me achieve the end result I was looking for. And it was as simple as adding this instruction:
cmp ebx,17654
17654 is always player1, while enemies appear to be 1732C, though I only need to compare against player1.

Now I just realized I have one small issue I have to figure out. The original mov instruction that the cmp jumps to for the enemies is still using a Changing Offset anytime the game is restarted. So for now I still have to constantly edit the script to update this offset. Fortunately, I have a pointer in the Address List for it, so I can just copy it quickly to the script each time, but I know there has to be a way to code this in the script. Do any of your videos go over anything of this nature? Or would the Reassemble() function you mentioned prior likely assist with this?

Original MOV instruction:
mov [ebx+05DFF0A0],eax
Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 229

PostPosted: Fri Oct 11, 2024 12:10 pm    Post subject: Reply with quote

Good job. Share your entire script and I'll help you resolve the issue
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 12, 2024 8:06 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
Good job. Share your entire script and I'll help you resolve the issue


Thanks again, and here is the script, it's really pretty basic:

Code:
[ENABLE]
aobscan(INJECT,29 47 FC 83 EF 04 8B 07 8B 5F FC 89 83 xx xx xx 05 83 EF 04 8D 86 78)
alloc(newmem,$1000)

label(code)
label(return)

newmem:
  cmp ebx,17654
  jne code
  jmp return

code:
  mov [ebx+05DB90A0],0
  jmp return

INJECT+0B:
  jmp newmem
  nop

return:
registersymbol(INJECT)

[DISABLE]
INJECT+0B:
  db 89 83 A0 70 CE 05

unregistersymbol(INJECT)
dealloc(newmem)


The Changing Offset is the "05DB90A0". For example, I just restarted the game, and now the new offset is 05E840A0.

If it helps, this is the PTR I use in my Address List to generate this offset:



q3_Game's changing offset.PNG
 Description:
 Filesize:  8.38 KB
 Viewed:  2147 Time(s)

q3_Game's changing offset.PNG


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

Joined: 17 Sep 2023
Posts: 229

PostPosted: Sat Oct 12, 2024 8:15 am    Post subject: Reply with quote

Code:
[ENABLE]
aobscan(INJECT,29 47 FC 83 EF 04 8B 07 8B 5F FC 89 83 xx xx xx 05 83 EF 04 8D 86 78)      //Give a better name for your scripts, more distinctive names
alloc(newmem,$1000)

label(code)
label(return)

newmem:
  cmp ebx,17654
  jne code
  jmp return

code:
  reassemble(INJECT+0B)      //mov [ebx+05DB90A0],0      //We added +0B because the injection address equals the result of the aobscan(INJECT) + 0B
  //reassemble() will reassemble the entire line at the given address. To use reassemble for the next instruction you add the size of the instruction(s) above it
  jmp return

INJECT+0B:
  jmp newmem
  nop

return:
registersymbol(INJECT)

[DISABLE]
INJECT+0B:
  db 89 83 A0 70 CE 05

unregistersymbol(INJECT)
dealloc(newmem)


Of course, you can always try to find a better injection point if possible to avoid having addresses or offsets in the script altogether
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 12, 2024 3:44 pm    Post subject: Reply with quote

Game Hacking Dojo wrote:
Code:

code:
  reassemble(INJECT+0B)      //mov [ebx+05DB90A0],0      //We added +0B because the injection address equals the result of the aobscan(INJECT) + 0B
  //reassemble() will reassemble the entire line at the given address. To use reassemble for the next instruction you add the size of the instruction(s) above it
  jmp return


Is there something extra I'm suppose to do or figure out about this reassemble() to make it work? I tried it as it is, but nobody dies, so I've been trying to make sense of how exactly it's suppose to work.

You did mention "to use reassemble for the next instruction you add the size of the instruction(s) above it." But there are no other instructions for this script that need to be reassembled.

I looked over the CE help guide and there is not much on this function as it looks pretty basic and it only accepts registered symbols and addresses.

Also, I don't understand how the actual mov [ebx+05DB90A0],0 instruction is even still present in the disassembler since the mov instruction has been commented out in the script.

Is reassemble() reading the mov instruction before the script is actually enabled somehow? Please explain how this works, because the CE help file I'm looking at does not mention anything about this.

My luck, it's probably something simple and I'm just overlooking it.

Update: Added a snapshot (notice the changing offset 05CE70A is an older value)



q3-reassemble_test1.PNG
 Description:
 Filesize:  18.92 KB
 Viewed:  1889 Time(s)

q3-reassemble_test1.PNG


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

Joined: 17 Sep 2023
Posts: 229

PostPosted: Sat Oct 12, 2024 4:54 pm    Post subject: Reply with quote

Reassemble() is simple to use yet very useful. If you give reassemble() an address it will replicate that address's instruction at the location it was called. Why is that useful? Sometimes you can't predict what the exact instruction is going to be at the injection point and other use cases as well.

Nobody dies:
Apparently, you are moving 0 to the health of the enemies (filtered-out addresses) thus you've changed the original code and reassemble() is only going to rewire the original code as it was.

How do I solve this? First, make sure you have "show symbols" and "show module address" to be ticked.
If they aren't ticked then tick them and make a new script and that should fix it.

Otherwise, we have to do something else. Try this for now.

Lastly, you don't have to wait 8 hours to reply. Replying is possible if someone else posts something after you



Screenshot 2024-10-13 004646.png
 Description:
 Filesize:  65.84 KB
 Viewed:  1877 Time(s)

Screenshot 2024-10-13 004646.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: Sun Oct 13, 2024 10:47 am    Post subject: Reply with quote

Game Hacking Dojo wrote:
Reassemble() is simple to use yet very useful. If you give reassemble() an address it will replicate that address's instruction at the location it was called. Why is that useful? Sometimes you can't predict what the exact instruction is going to be at the injection point and other use cases as well.

Nobody dies:
Apparently, you are moving 0 to the health of the enemies (filtered-out addresses) thus you've changed the original code and reassemble() is only going to rewire the original code as it was.

How do I solve this? First, make sure you have "show symbols" and "show module address" to be ticked.
If they aren't ticked then tick them and make a new script and that should fix it.


At first I thought that makes sense, but then I realized that my one instruction that adds zero to the enemy's health is not executed since it's commented out. So, only the original code is being reassembled, correct?

Also, "show symbols" and "show module addresses" were already checked.

When no one dies, that is one of the effects of not updating the Changing Offset. I know this too well because I've done it a few times forgetting to copy the new offset to the mov instruction. So, I have a feeling the reassemble() is not working correctly for this mov instruction.

Yeah, I realized that a few posts back regarding the 8 hour wait. I have "notify me when a reply is posted", yet I never get a notification. I need to try to figure out why.
Back to top
View user's profile Send private message
Game Hacking Dojo
Expert Cheater
Reputation: 1

Joined: 17 Sep 2023
Posts: 229

PostPosted: Sun Oct 13, 2024 3:05 pm    Post subject: Reply with quote

Yes the original code at the injection pointer is reassembled in the hook. To do the effect of writing 0 to the health without the ability to change the instruction itself since we used reassemble, you can use move 0 to eax to before the instruction executes.

Code:
mov eax,0       //there are multiple ways to move 0 to a register but this is easier for you to understand and change
reassemble(INJECT+0B)      //mov [ebx+05DB90A0],eax


If the previous method of using reassemble didn't help you or you didn't like it. Then we can use the pointer you found. Despite using pointers is less reliable in my opinion.


Code:
push ecx       //save the value held in ecx on the stack
mov ecx,"ioquake3.x86.exe"+01995A88
mov ecx,[ecx]
lea ecx,[ecx+17050]
mov [ebx+ecx],eax      //this is now the health address you can do whatever you want
pop ecx        //load the last stored value to ecx
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 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