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 


Need help regarding word ptr

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
Kajih
Cheater
Reputation: 1

Joined: 08 Feb 2021
Posts: 32

PostPosted: Mon Jan 10, 2022 6:38 pm    Post subject: Need help regarding word ptr This post has 1 review(s) Reply with quote

Hi, I would like to understand what exactly this opcode is doing, I tried goggling some of this but I have a hard time understanding what the difference is between mov and movzx and what exactly is word ptr :

Code:
movzx ecx,word ptr [rdx+r8*2]


when I look up what addresses this instruction accesses, I can see a new address whenever I move my cursor in the game inventory screen and I can see the value (amount of item). but when I try to save this address to a symbol I created in a script, I am not seeing the same address being returned and the value is incorrect. this is my injected code:

Code:

push rax
mov rax,[rdx+r8*2]
mov [itemPTR],rax
pop rax


In cheatEngine when I add the address manually and put in [itemPTR], but it's not the correct address that appears. Even if I enter itemPTR, the value matches but the address doesn't change when I update the inventory item in the game.

I hope I am making sense. I'd appreciate any help in explaining what I am not understanding. Thank you in advance.
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Mon Jan 10, 2022 7:50 pm    Post subject: Re: Need help regarding word ptr This post has 1 review(s) Reply with quote

Kajih wrote:
Hi, I would like to understand what exactly this opcode is doing, I tried goggling some of this but I have a hard time understanding what the difference is between mov and movzx and what exactly is word ptr :

Code:
movzx ecx,word ptr [rdx+r8*2]


when I look up what addresses this instruction accesses, I can see a new address whenever I move my cursor in the game inventory screen and I can see the value (amount of item). but when I try to save this address to a symbol I created in a script, I am not seeing the same address being returned and the value is incorrect. this is my injected code:

Code:

push rax
mov rax,[rdx+r8*2]
mov [itemPTR],rax
pop rax


In cheatEngine when I add the address manually and put in [itemPTR], but it's not the correct address that appears. Even if I enter itemPTR, the value matches but the address doesn't change when I update the inventory item in the game.

I hope I am making sense. I'd appreciate any help in explaining what I am not understanding. Thank you in advance.


MOVZX is move with zero extended, basically it converts a value size of X bits to a value size of Y bits. WORD is a value size (2 bytes), basically you have bit (smallest unit), nibble (4 bits), byte (8 bits), word (2 bytes), dword (4 bytes), qword (8 bytes), and there are others for larger data sizes. You can find more on that here. And since it's using ECX (a 32 bit register or dword) and "word ptr" (word pointer) it's converting a word to a dword with zero extended.

With "mov rax,[rdx+r8*2]" you are moving a qword value at the address of "rdx+r8*2" to RAX. So in the end you are storing a value of the wrong data size and not the address. In this case you want to use LEA (load effective address), i.e. "lea rax,[rdx+r8*2]" will set RAX to the address so you can store it. Then you'll need to set the value type to 2 bytes, if you look in the "see what addresses this instruction accesses" window at the bottom the value type is likely set to 2 bytes.

_________________
Back to top
View user's profile Send private message Visit poster's website
Kajih
Cheater
Reputation: 1

Joined: 08 Feb 2021
Posts: 32

PostPosted: Tue Jan 11, 2022 6:28 am    Post subject: Reply with quote

Oh! now I get it. I still keep getting mixed up between value and address when moving into a register. This was quite a beginner mistake again, since I'm not using assembly every day and just learning as I go, I should really sit down through a more structured learning approach and practice (outside of cheatEngine) to at least get some of these basics ingrained in my head.

Thanks for the explanation, this helped a lot.
Back to top
View user's profile Send private message
Kajih
Cheater
Reputation: 1

Joined: 08 Feb 2021
Posts: 32

PostPosted: Sat Jan 15, 2022 10:56 am    Post subject: Reply with quote

I have a quick follow up question that is related to MOVZX I believe. I have an injection location that updates a value every frame:

Code:

newmem:
code:
  mov [rsi+4C],di
  test r12d,r12d
  jmp return


This is a shared instruction so I am comparing if it's the player and if so simply retaking the current value and placing it into di:

Code:

newmem:
  cmp [rsi+A4],0
  je code
  mov di,[rsi+4C]
code:
  mov [rsi+4C],di
  test r12d,r12d
  jmp return


However i noticed that the max value for this is located at offset 28, so it's basically [***+4C] / [***+28]. The problem is that the value at +28 is a 2-byte value and the current value is a 4-byte. I figured I would try to use MOVZX here as well to move my 2-byte value into the 4-byte:

Code:

newmem:
  cmp [rsi+A4],0
  je code
  movzx di,word ptr [rsi+28]
code:
  mov [rsi+4C],di
  test r12d,r12d
  jmp return


This doesn't work. I read up a bit on di and si and somewhat understand their purpose but I am having a bit of a hard time wrapping my head around it. I don't believe this is a string manipulation so I am guessing it's used to copy memory from another location. What is why can't I do a movzx with [rsi+28] but I can do a mov with [rsi+4C]. Unless I shouldn't be doing mov di,[rsi+4C] either?

Last and foremost, how can I go about making my injection take the 2-byte value stored at [rsi+28] and store it in the 4-byte location at [rsi+4C]?

Thanks for your time.

EDIT:
I resolved my issue by doing:

Code:
newmem:
  cmp [rsi+A4],0
  je code
  push rax
  movzx rax,word ptr [rsi+28] //max mp
  mov [rsi+4C],rax
  pop rax
  jmp return
code:
  mov [rsi+4C],di
  test r12d,r12d
  jmp return


but for some reason, this breaks another value somewhere else, it looks like I HAVE to do mov [rsi+4C],di for some reason... but I don't understand why.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sat Jan 15, 2022 1:26 pm    Post subject: Reply with quote

`cmp [rsi+A4],0` is ambiguous. The size of the value being compared against is unknown. CE defaults to a 32-bit value which is fine if you want that.

Kajih wrote:
The problem is that the value at +28 is a 2-byte value and the current value is a 4-byte.
If the instruction `mov [rsi+4C],di` is the original code writing to your current health, then the game says the current health is a 2-byte value. di is a 2-byte register

`movzx di,word ptr [rsi+28]` doesn't work because movzx zero-extends a smaller value to a larger one. `word ptr` means it should access 2 bytes of memory, and di is a 2-byte register. They're the same size- movzx can't work because there's nothing to extend. Just use mov like the original code does.

`mov [rsi+4C],rax` is bad because you're overwriting unknown data. rax is an 8-byte register, so CE infers it should be writing 8 bytes to the address. The current health is only 2 bytes. You don't know what the other 6 bytes are for. This could crash the game or have other side effects.

_________________
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
Kajih
Cheater
Reputation: 1

Joined: 08 Feb 2021
Posts: 32

PostPosted: Sat Jan 15, 2022 1:56 pm    Post subject: Reply with quote

ParkourPenguin wrote:
`cmp [rsi+A4],0` is ambiguous. The size of the value being compared against is unknown. CE defaults to a 32-bit value which is fine if you want that.


I added this check just to differentiate between player and monster, did a quick commonality scan and noticed this offset was always 0 for a monster while the players (in the party was a higher number). Should I go about the check another way? I usually do it this way so please do let me know if there would be a better way.

ParkourPenguin wrote:
If the instruction `mov [rsi+4C],di` is the original code writing to your current health, then the game says the current health is a 2-byte value. di is a 2-byte register

`movzx di,word ptr [rsi+28]` doesn't work because movzx zero-extends a smaller value to a larger one. `word ptr` means it should access 2 bytes of memory, and di is a 2-byte register. They're the same size- movzx can't work because there's nothing to extend. Just use mov like the original code does.

`mov [rsi+4C],rax` is bad because you're overwriting unknown data. rax is an 8-byte register, so CE infers it should be writing 8 bytes to the address. The current health is only 2 bytes. You don't know what the other 6 bytes are for. This could crash the game or have other side effects.


This makes so much sense now, the game is Final Fantasy 12 and I was tracking MP for party members. The extra 6 bytes are used to keep track of how many Mist Bars (limit breaks) are filled and I can see this now whenever a mist bar was filled, 0x10000 was added to the value. It's clear now that I was not writing to the 2 bytes that was holding my mp but essentially overwriting the information for the bars as well. which messed up the whole game.

Thanks for the help!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sat Jan 15, 2022 10:48 pm    Post subject: Reply with quote

Kajih wrote:
Should I go about the check another way? I usually do it this way so please do let me know if there would be a better way.
It's fine. I was just asking about the size of the value at [rsi+A4]. If it's a 4-byte value, it's' fine the way it is; if it's something else, you'll need to qualify the memory access. e.g. if it's a 2-byte value, use `cmp word ptr [rsi+A4],0`
_________________
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
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking 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