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 


Address Changes During Gameplay
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Thu Jan 03, 2019 4:22 pm    Post subject: Address Changes During Gameplay Reply with quote

I have been trying to find the base static pointer that represents "lives" in a game for 2 or 3 weeks now. To make things a little more complicated, lives are are not represented by equivalent integer values. For example:

Quote:
1072693248 = 0 lives
1073741824 = 1 life
1074266112 = 2 lives
1074790400 = 3 lives
...


The base static pointer that I found has 4 offsets, & works when the game is first started. But eventually, I have to find a different address to manage the lives value. So, now I have multiple pointers that the game seems to switch back & forth to to represent this value. But it seems no matter how many I find, it eventually switches to a different address.

Is it possible that this game does not have a single base pointer that I can use & will have to find all of the top-level pointers? Or perhaps, the game will constantly change pointers no matter how long I play?

Note: Even if I am not using pointers, the address changes.

Note: I have found permanent top-level pointers for other values.


Last edited by AntumDeluge on Wed Jan 16, 2019 4:48 am; edited 1 time in total
Back to top
View user's profile Send private message
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Wed Jan 16, 2019 4:47 am    Post subject: Address Changes During Gameplay Reply with quote

I didn't find any info on bumping threads in the FAQs (still can't post URLs). My first post is a couple weeks old with no replies, so I hope this is okay.

I'm not sure if the original post is clear, & perhaps it really has nothing to do with pointers. As I said before, I am having trouble finding a permanent top-level pointer for the "Lives" value in a game. But even without using pointers, the address for the value continually changes during gameplay. I hope I can be clear in my description.

Starting a new game with an empty Cheat Engine table, I find the address for the "Lives" value which is 0867943C (not a pointer). I can change the value & lock it just fine. I can play that way for a few minutes. But eventually, that address no longer manages the "Lives" value. Altering or locking does not work. I have to find the new address that now manages the value. In my testing case, it is 086790CC. Even if the value of the old address was locked, it still changes to the new address. Again, I can play like that for a few minutes but the address eventually changes. I search again & find that the lives value is now found at the address 086797AC.

Is there any way to prevent this address changing? Or is there a pattern that I am missing?

Edit: Going over step 5 (code finder) in the tutorial.

Edit: Okay, did step 5 but it didn't help. Address still changes.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Wed Jan 16, 2019 9:48 am    Post subject: Reply with quote

That's not an integer: it's the upper half of a double. It'll make more sense if you subtract 4 from the address and change the value type to "double".

AntumDeluge wrote:
But even without using pointers, the address for the value continually changes during gameplay.
Pointers are a solution to that problem. That statement is similar to "even without fuel, my car still won't run."

Try the pointer scanner.

If that fails, search for changed/unchanged values when the address changes.

Code injection is always an option.

_________________
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
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Thu Jan 17, 2019 12:24 am    Post subject: Reply with quote

Thank you ParkourPenguin. Double is the correct type & makes the values readable. But, it does not solve the pointer address changing during gameplay issue. I will have to play around with code injection & see if I can figure that out.

Edit: I'm guessing what I will need to do is inject code that catches the pointer address change & set it to the previous address?

Edit: If anyone is interested in looking at my table/trainer, I can send you a link (can't post links yet). But warning, it's messy right now.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Thu Jan 17, 2019 10:06 am    Post subject: Reply with quote

AntumDeluge wrote:
I'm guessing what I will need to do is inject code that catches the pointer address change & set it to the previous address?
No. Search for "injection copy"- there are a couple YouTube videos and some old forum posts that go over it (e.g. YT, CEF).
_________________
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
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Tue Jan 22, 2019 1:59 pm    Post subject: Reply with quote

Okay, I've been looking over the YouTube tutorial you linked to & another that I found. But I've run into some speed bumps:

First off, the instruction that he gets from the debugger is
Code:
mov [ecx+00000978],eax


Whereas mine is
Code:
fst qword ptr [eax+edx+08]


The other thing is that my instruction accesses hundreds of addresses (see attached "Accessed addresses list" image).

This is the auto assemble script that I have come up with. Not working, & I'm not going to pretend like I understand exactly what it is doing. Note: In the tutorial, it said to allocate 4 bytes for the globalalloc line. I wasn't sure if this should be different because the data type is double, so I put it at 16. I really don't know if it's necessary:
Code:
[ENABLE]
aobscanmodule(INJECT,SFXMMv2_US.exe,DD 54 10 08 83 C2 10)
alloc(mem,$1000)
label(code)
label(return)
registersymbol(INJECT)

globalalloc(lives,16)

mem:
  mov [lives],eax
  jmp code

code:
  fst qword ptr [eax+edx+08]
  add edx,10
  jmp return

INJECT:
  jmp mem
  nop
  nop

return:

[DISABLE]

INJECT:
  db DD 54 10 08 83 C2 10

unregistersymbol(INJECT)
dealloc(mem)



addresses_accessed_by_instruction.png
 Description:
Accessed addresses list
 Filesize:  24.81 KB
 Viewed:  6921 Time(s)

addresses_accessed_by_instruction.png


Back to top
View user's profile Send private message
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 84

PostPosted: Tue Jan 22, 2019 7:11 pm    Post subject: Reply with quote

I do see ... some points here

- 26157 count? while you are running an fst code directly after - are you sure any value you do set manually isn't being overwritten faster than you can set it? it would be better to comment that fst (if it is what you want to hack), and make s.t. proper like (ftsp st(0); fld [eax+edx+08]) if that's rly the instruction you need to change.
- I don't believe any of the part "from the debugger is .... Whereas mine is". Clearly shows not even diff offset but every register is different. Could you post screenshots of the debugger and the memory viewer of that section (few entries before/after)
- are you sure the aobscanmodule results just 1 address?
- as for the allocation: yeah overlooked that it's an address, was late so 4B in that case (8 Bytes would be enough for double, typical use cases:)
Code:
define byte     db   1B   AL/AH   Int
define word     dw   2B   AX      Int
define dword    dd   4B   EAX     Int/float
define qword    dq   8B   RAX     Double
define oword    do? 16B   XMMO    // never did need to alloc 16B yet so I wouldn't know, and xmm registers are 128B long, depends on instructions used against

- that jmp code instruction is basically useless, follow the jmp once you activate the script and u'll know why.


Last edited by salumor on Wed Jan 23, 2019 6:54 am; edited 2 times in total
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Tue Jan 22, 2019 7:53 pm    Post subject: Reply with quote

Is this an emulator? What are the values of eax and edx when that instruction is executed? (click on "More Information" in the accessed / writes to window)

If it's not an emulator, try to find another instruction that only accesses that address.

AntumDeluge wrote:
Note: In the tutorial, it said to allocate 4 bytes for the globalalloc line. I wasn't sure if this should be different because the data type is double, so I put it at 16.
4 is still fine. You're storing an address, not the value stored at an address.
In a 32-bit process, addresses take up 32 bits (i.e. 4 bytes), so only allocating 4 is fine. If this were a 64-bit process, addresses would take up 64 bits, so you'd need to allocate 8 bytes.

_________________
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
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Wed Jan 23, 2019 9:48 am    Post subject: Reply with quote

salumor wrote:
that jmp code instruction is basically useless, follow the jmp once you activate the script and u'll know why.


Thank you, I had actually figured that out after I posted this. Smile

ParkourPenguin wrote:
Is this an emulator?


No. It is a native Win32 game.

ParkourPenguin wrote:
4 is still fine. You're storing an address, not the value stored at an address.
In a 32-bit process, addresses take up 32 bits (i.e. 4 bytes), so only allocating 4 is fine. If this were a 64-bit process, addresses would take up 64 bits, so you'd need to allocate 8 bytes.


Thank you, that clarifies things for me.

I apologize that I really don't understand the terminology & how all this works. I am uploading a video to YouTube to demonstrate all that I am doing (trying to follow the tutorials). I hope that it is not against the forum rules to link to such video since it shows which game I am working with.

I don't think I can post links yet, so I will have to post a non-canonical (if that is the right term) URL. The video is located here: youtube dot com slash watch?v=WYcWXYuwwpw

-- Edit --

salumor wrote:
Could you post screenshots of the debugger and the memory viewer of that section (few entries before/after)


The video should show that. Please let me know if there is anything else you want to see.

ParkourPenguin wrote:
If it's not an emulator, try to find another instruction that only accesses that address.


I haven't successfully been able to do that yet.
Back to top
View user's profile Send private message
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 84

PostPosted: Wed Jan 23, 2019 10:13 am    Post subject: Reply with quote

Ah, okay. So why do you like to have eax (above) or edx (video) only?

If you take look at 7:15 it does show:

EDX = FFFFFE10
EAX = 086B9620
EDX+EAX = 1086B9430 (but since you do store at 4B address it's only 086B9430 )

The wanted address is 086B9438. Now there is a +8 for the offset you did add correctly and .....

I think something like the following should work (or may even something before all that add/subs):

Code:
  mov [lives],edx
  add [lives],eax


Oh, and since this is a shared instruction you might act. want to compare to something, before moving.

No, what i act. do wonder: why the list of changed addresses do check non 32Bit addresses. Would that be a bug?
Back to top
View user's profile Send private message
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Wed Jan 23, 2019 10:37 am    Post subject: Reply with quote

salumor wrote:
Ah, okay. So why do you like to have eax (above) or edx (video) only?

I'm sorry. I don't understand. Crying or Very sad

salumor wrote:
The wanted address is 086B9438.

Does that mean in the table entry I want use 086B9438 instead of lives?

-- Edit --
salumor wrote:
Code:
  mov [lives],edx
  add [lives],eax


Adding that line does cause the script to update the "Lives" table entry, but the value is wrong. So, the address must be wrong?
Code:
...
globalalloc(lives,4)

newmem:
  mov [lives],edx
  add [lives],eax

code:
  fst qword ptr [edx+eax+08]
  add edx,10
  jmp return
...


Edit: Not sure if this is helpful, but I have attached a screenshot of a few more lines up in the Memory Viewer.



4F56_DD_54_02_08.png
 Description:
 Filesize:  49.3 KB
 Viewed:  6839 Time(s)

4F56_DD_54_02_08.png


Back to top
View user's profile Send private message
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 84

PostPosted: Wed Jan 23, 2019 10:59 am    Post subject: Reply with quote

AntumDeluge wrote:
salumor wrote:
Ah, okay. So why do you like to have eax (above) or edx (video) only?

I'm sorry. I don't understand. Crying or Very sad
You did store either edx or eax as base address, but you act. need to store both, or the sum.

You did "mov [lives],eax" but you'd need to have something like "mov [lives],eax+edx". But that's invalid, mov can't calculate.

AntumDeluge wrote:
salumor wrote:
The wanted address is 086B9438.

Does that mean in the table entry I want use 086B9438 instead of lives?
No, wanted as in .... temporary. Only during that session the script/lives value should point to 086B9438, but it will probably change once you restart game.

AntumDeluge wrote:
Adding that line does cause the script to update the "Lives" table entry, but the value is wrong. So, the address must be wrong?
Yeah because it's a shared instruction. You need to make sure to compare to a state at which the stack does hold the address to lives. You saw at changed address list, that the function does write to many addresses. Some example below. But if you are unfamiliar search for some tutorial on shared instructions.

Code:
newmem:
  pushf              //preserves flags, always do that when you compare!
  cmp [eax+30],#24   // 30 -> CompareableOffset // I use it to differe between enemy and player, only player should have inf. health
  je short @f        //jump to next label (@@) if equal, because I would not want next code to execute ('ecx' contains the new decreaced health value). Since I do know it will be second to next instr. I can do a short jump, as it's inbetween 127/125 Byte range
  mov [eax+14],ecx

@@:
  popf               // restore flags
Back to top
View user's profile Send private message
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Wed Jan 23, 2019 11:14 am    Post subject: Reply with quote

salumor wrote:
You did store either edx or eax as base address, but you act. need to store both.

Okay, I think I'm starting to understand. The add eax adds that address to the edx address stored at lives address. Does that mean that I should allocate 8 bytes instead of 4? E.g.:
Code:
globalalloc(lives,8)


Looking up info on "shared instructions"...
Back to top
View user's profile Send private message
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 84

PostPosted: Wed Jan 23, 2019 12:05 pm    Post subject: Reply with quote

AntumDeluge wrote:
salumor wrote:
Okay, I think I'm starting to understand. The add eax adds that address to the edx address stored at lives address. Does that mean that I should allocate 8 bytes instead of 4?
No! It's still a 32Bit/4B game. (See ParkourPenguin's reply above.) You do not have any use for 64Bit/8B addresses. It would be s.t. else, if you would store values. But addresses never leave their addressed space. (well, I can think of few options like compatibility, but let's keep it simple)

Let's go back to: "EDX+EAX = 1086B9430 (but since you do store at 4B address it's only 086B9430 )". 1B is up to hex FF, 2B: FF FF, 3B: FF FF FF, 4B: FF FF FF FF. Thus 1 08 6B 94 30 can't be stored in a 4B address. Since it will be read from right to left, the "1" will be dropped, only 086B9430 would be stored. Think of it as .... you are allowed to count between 0 and 99. Once you are at 99+1 - you do know it would be 100, but in a world between 0 and 99 it's 00.

With the "neg edx" instruction it will be most likely to overflow. But I am yet not that experienced to read that add/sub section without the registers at start or better debugging through each step, or why it's done this way.
Back to top
View user's profile Send private message
AntumDeluge
Cheater
Reputation: 0

Joined: 20 Dec 2018
Posts: 48

PostPosted: Wed Jan 23, 2019 12:17 pm    Post subject: Reply with quote

Okay, it's just beyond my understanding at this point. It's going to take a while to sink in. I was thinking something like edx = 4B address & eax = 4B address, so I would need to allocate enough memory for 2x4B addresses. And I wasn't paying close attention when you wrote:
salumor wrote:
EDX = FFFFFE10
EAX = 086B9620
EDX+EAX = 1086B9430 (but since you do store at 4B address it's only 086B9430 )


The "1" being dropped doesn't cause address conflict issues?

I think I found another tutorial that may be helpful for me: youtube dot com/watch?v=06t_hoWGa5c

-- Edit --
Using the structure dissect, the offset "10" appears to be where "lives" value is stored (attached screenshot).



lives_offset-structure_dissect.png
 Description:
 Filesize:  31.62 KB
 Viewed:  6813 Time(s)

lives_offset-structure_dissect.png


Back to top
View user's profile Send private message
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  Next
Page 1 of 2

 
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