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 


A little help with a script?
Goto page Previous  1, 2
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Jiehfeng
Expert Cheater
Reputation: 0

Joined: 03 Jan 2014
Posts: 107

PostPosted: Sun May 22, 2016 10:40 am    Post subject: Reply with quote

ParkourPenguin wrote:
++METHOS wrote:
There are other things that you can try.
  • You can use a pointer address for your filter, inside of your script, for the value that you are trying to manipulate.
  • You can use pointer trees inside of the data structure to find something viable.
  • You can shift the data structure (+ or -) and/or expand its size to find something useful.
  • You can use the structure spider to find workable strings and/or for comparative analysis.
  • You can check the register values by attaching the debugger or setting a breakpoint to see if something can be used for your filter.
  • You can check to see if there are any instructions that are exclusive to the address/value that you are trying to manipulate and store the address for your filter by creating a second injection point.
  • You can check to see if there are any instructions that are exclusive to any other address/value inside of the data structure for the address/value that you are trying to manipulate and store the address for your filter by creating a second injection point.
  • You can analyze assembly code to see if an identifier is being checked or assigned somewhere.
  • Et al.


Oh? There's a way to change a pointer's value in a script? Any tutorials on that?

_________________
I know you're reading this, Hitler.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sun May 22, 2016 10:46 am    Post subject: Reply with quote

You just read pointers like any other memory address. Apply offsets as needed.
For example, if the pointer path to the address of some value is [[game.exe+13C]+24]+D4, then:
Code:
mov eax,[game.exe+13C]
mov eax,[eax+24]
lea ebx,[eax+D4]  // the address of the value
mov eax,[eax+D4]  // the value itself
// in other words, at this point, [ebx] == eax

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

Joined: 03 Jan 2014
Posts: 107

PostPosted: Sun May 22, 2016 11:01 am    Post subject: Reply with quote

ParkourPenguin wrote:
You just read pointers like any other memory address. Apply offsets as needed.
For example, if the pointer path to the address of some value is [[game.exe+13C]+24]+D4, then:
Code:
mov eax,[game.exe+13C]
mov eax,[eax+24]
lea ebx,[eax+D4]  // the address of the value
mov eax,[eax+D4]  // the value itself
// in other words, at this point, [ebx] == eax


Alright if my pointer were:

Code:

40     //offsets in order
80
5f4
668
5d4

"ac_client.exe"+0010A280        //process


How would it look like? And in your code, where did eax and ebx come from?

_________________
I know you're reading this, Hitler.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sun May 22, 2016 11:12 am    Post subject: Reply with quote

eax and ebx are registers. They didn't come from anywhere as they are always available for use as general-purpose registers.

Assuming you wrote those offsets down as they appear when you change the address field of a memory record:
Code:
mov eax,["ac_client.exe"+0010A280]
mov eax,[eax+5d4]
mov eax,[eax+668]
mov eax,[eax+5f4]
mov eax,[eax+80]
lea ebx,[eax+40]  // ebx = address of the value
mov eax,[eax+40]  // eax = the value

Note that if you're doing this in a code injection you'll probably need to back up any registers you modify (use push/pop).

_________________
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
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Sun May 22, 2016 3:34 pm    Post subject: Reply with quote

If you're going to use a pointer, then there's no point in using a script unless you are using it for filtering purposes, as an ID, or you need it in order to perform some additional work. I don't usually recommend going this route because it is less reliable than some of the alternatives as you are relying on something that is more likely to break, especially if the target gets updated. Assuming the offsets are in the correct order:

Code:
push rdi
push rdx
lea rdi,[[[[[["ac_client.exe"+0010A280]+5D4]+668]+5F4]+80]+40]
lea rdx,[rax+28]
cmp rdi,rdx
pop rdx
pop rdi
je money
jmp originalcode


You can also compare the value of [rax+28] against the value of money using your pointer. However, this is not a recommended approach because there may be other addresses that happen to have the same value as money when you run your script.

Please note: I have not actually tried it this way using lea (not sure if CE supports it or not), so you may have to write it out as ParkourPenguin has shown above:

Code:
push rdi
push rdx
mov rdi,["ac_client.exe"+0010A280]
mov rdi,[rdi+5D4]
mov rdi,[rdi+668]
mov rdi,[rdi+5F4]
mov rdi,[rdi+80]
lea rdi,[rdi+40]
lea rdx,[rax+28]
cmp rdi,rdx
pop rdx
pop rdi
je money
jmp originalcode
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sun May 22, 2016 3:51 pm    Post subject: Reply with quote

That notation is perfectly valid for any r/m32, as CE will evaluate the address currently being pointed at when it assembles that instruction. The only reason why I don't use that is because CE will only assemble it once. If the value of any address in the pointer path changes, that instruction will no longer point to the correct address. Even if that's not a concern for a particular game, it's still good for beginners to know how to traverse a pointer path manually.
_________________
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
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Sun May 22, 2016 4:47 pm    Post subject: Reply with quote

ParkourPenguin wrote:
The only reason why I don't use that is because CE will only assemble it once. If the value of any address in the pointer path changes, that instruction will no longer point to the correct address.
-That seems unexpected. Why will the address values not get updated each time the instruction is executed when written out this way...why is it a one-time thing?

I normally write out my pointers manually, as you say, but have, on occasion, performed some simple compares using this less-preferred method...but that was a long time ago.

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

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sun May 22, 2016 6:20 pm    Post subject: This post has 1 review(s) Reply with quote

Because there is no possible way to encode that type of memory access with the ModR/M or SIB bytes. When CE comes across that in an AA script, CE evaluates the pointer path itself and uses the end address as a disp32 in the instruction. For example, let's say the pointer [game.exe+7C]+14 points to the address 0170A400:
Code:
// CE would assemble this:
mov eax,[[game.exe+7C]+14]
// ...the same way it would this:
mov eax,[0170A400]

If the address that pointer points to changes, you'll have to execute the script again in order to reflect that change.

CE would be hard pressed to keep track of the pointer path itself and manually update the address in the instruction. A timer wouldn't work: in the time it takes CE to notice the change, the instruction could be executed. Breakpoints wouldn't be that good of an option. Calling any kind of subroutine to run before running that instruction would beg the question of why even do this in the first place, as manually dereferencing the pointer path would be less cpu-intensive.

Now, if you can identify what triggers a pointer's value to be changed, you wouldn't need to use any pointers and could just update the dynamic memory address via a code injection. However, the overhead might outweigh the difference it would make.

Of course, if the address the pointer points to doesn't change, then most of this is irrelevant and using that shorthand notation is the best way of accessing it.

_________________
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
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Sun May 22, 2016 6:57 pm    Post subject: Reply with quote

Thanks. I get the gist of what you're saying, however:

ParkourPenguin wrote:
Because there is no possible way to encode that type of memory access with the ModR/M or SIB bytes.


...this part is currently over my head, so I'm still not quite sure why it needs to be that way. I appreciate you taking the time to explain it. I will certainly take consideration of this when writing out examples in the future. Thanks.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sun May 22, 2016 8:02 pm    Post subject: Reply with quote

To put it simply, that means x86 processors don't support it. It's like trying to do a memory-to-memory move (e.g. mov [eax],[ebx]) or something. It just doesn't exist.

The ModR/M and SIB bytes are sometimes used in instructions that refer to memory locations (e.g. mov eax,[ebx]). They're used for giving the processor information on what that [ebx] operand is. If you'd like more information, check out Intel's Software Developer's Manual Volume 2 section 2.1.3.

_________________
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
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Sun May 22, 2016 8:17 pm    Post subject: Reply with quote

If I understand you correctly, the process of 'interpreting' that pointer data is being done only once, by CE, upon script execution, similar to other things, such as assigning labels and such, and is not performed each time the instruction is executed?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sun May 22, 2016 9:03 pm    Post subject: Reply with quote

Exactly. I suppose it works kind of like define(token,replace) in that the token is a pointer and it's automatically replaced with the address it's pointing at.
_________________
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
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Sun May 22, 2016 9:54 pm    Post subject: Reply with quote

That makes a lot of sense. Thanks! Very Happy
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 Previous  1, 2
Page 2 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