  | 
				
				Cheat Engine The Official Site of Cheat Engine   
				
 
				 | 
			 
		 
		 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		gamerp Newbie cheater
  Reputation: 0
  Joined: 20 Mar 2024 Posts: 10
 
  | 
		
			
				 Posted: Wed Mar 20, 2024 9:01 pm    Post subject: Questions about setting up editable values | 
				       | 
			 
			
				
  | 
			 
			
				Just picking up on the more advanced side of CE and I prefer to understand the code rather than just copying and pasting blindly  
 
 
 	  | Code: | 	 		  [ENABLE]
 
 
assert(address,bytes)
 
alloc(newmem,$1000,"TaxiLife-Win64-Shipping.exe"+187F173)
 
 
label(code)
 
label(return)
 
 
// based on CE Wiki, Tutorial CodeInjection/EditableValues
 
label(paymultiplier)
 
registersymbol(paymultiplier)
 
 
newmem:
 
  pop eax
 
  mov eax, edi
 
//  mov edx, 2
 
  mov edx, [paymultiplier]
 
  mul edx // eax = eax * edx
 
  mov edi, eax
 
  push eax
 
 
code:
 
  add ecx,edi
 
  mov [rbx+00000328],ecx
 
  jmp return
 
 
 // notice this is after jmp return
 
align 10 cc // fill 10 bytes with cc
 
paymultiplier:
 
  dd (int)2 // notice there's no space between the type casting and value
 
  jmp return //needed here or it'll keep running into address...?
 
 
address:
 
  jmp newmem
 
  nop 3
 
return:
 
 
[DISABLE]
 
 
address:
 
  db bytes
 
  // add ecx,edi
 
  // mov [rbx+00000328],ecx
 
 
dealloc(newmem)
 
dealloc(paymultiplier)
 
unregistersymbol(paymultiplier) | 	  
 
 
1. When I call "align 10 cc", does this always happen before the label after it? i.e. in this case "paymultiplier"? Otherwise I don't see how it would run when it's in between a jmp return and a label.
 
 
2. I only need enough space for a 4 byte integer here. Does this mean instead of align 10, it would be make more sense to align 4 if I wanted to be more optimal?
 
 
3. Do I need a "jmp return" in the "paymultiplier" block? If it's not there, it would just flow into the next "address" block, won't it?
 
 
So if "jmp return" wasn't there the code flow would be:
 
 
address > newmem > code > return > pay > address > newmem > code > return
 
 
With the return it wouldn't do the extra round, just the following?
 
 
address > newmem > code > return > pay > return | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		ParkourPenguin I post too much
  Reputation: 152
  Joined: 06 Jul 2014 Posts: 4706
 
  | 
		
			
				 Posted: Wed Mar 20, 2024 10:17 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				1. `align 10 cc` writes some number of bytes with the value 0xCC into memory. The number of bytes written will be such that the next address is aligned to a specified amount. In your case, an alignment of 0x10 means the address `paymultiplier` will end in a 0.
 
Example:
 
 	  | Code: | 	 		  alloc(foo,4096)
 
 
foo:
 
  xor eax,eax
 
  align 10 CC
 
  ret
 
 
{  OUTPUT
 
FFFF0000- 31 C0                 - xor eax,eax   // foo
 
FFFF0002- CC                    - int 3
 
FFFF0003- CC                    - int 3
 
//...
 
FFFF000F- CC                    - int 3
 
FFFF0010- C3                    - ret
 
} | 	  
 
This is important mostly because some instructions (particularly SIMD) require the data to be aligned to a certain amount; otherwise, it will crash. There's also the possibility that an unaligned value spans across two cache lines, making the access take significantly longer; however, that's negligible to most people.
 
 
2. Yes. Technically, something aligned to 0x10 bytes is also aligned to 0x4 bytes, but an alignment of 4 is "more correct" for a 4-byte value.
 
Also, contiguous values of the same size are inherently aligned if the first value is aligned.
 
 	  | Code: | 	 		  alloc(mem,1024)
 
label(val1)
 
label(val2)
 
 
mem:
 
  ...
 
 
align 4 CC
 
val1:
 
  dd 0
 
val2:   // already aligned
 
  dd 0 | 	  
 
 
3. No. That's not an instruction that's going to be executed by the game- it's just data.
 
 
There's two different "executions" of this script: the first is when CE assembles instructions and writes the bytes into memory, and the second is when the game eventually goes to execute the code that CE assembled.
 
 
CE tutorial, step 2. When you press the "Hit me" button, this is some of the code that the game runs:
 
 	  | Code: | 	 		  ...
 
Tutorial-x86_64.exe+2B4AF - B9 05000000           - mov ecx,00000005
 
Tutorial-x86_64.exe+2B4B4 - E8 5747FEFF           - call Tutorial-x86_64.exe+FC10
 
Tutorial-x86_64.exe+2B4B9 - 83 C0 01              - add eax,01
 
Tutorial-x86_64.exe+2B4BC - 29 83 F8070000        - sub [rbx+000007F8],eax  // Injecting here
 
Tutorial-x86_64.exe+2B4C2 - 48 8D 4D F8           - lea rcx,[rbp-08]
 
Tutorial-x86_64.exe+2B4C6 - E8 45DAFDFF           - call Tutorial-x86_64.exe+8F10
 
Tutorial-x86_64.exe+2B4CB - 8B 8B F8070000        - mov ecx,[rbx+000007F8]
 
... | 	  
 
After you enable some script that hooks the `sub` instruction, this is now what the game executes when the button is pressed:
 
 	  | Code: | 	 		  ...
 
Tutorial-x86_64.exe+2B4AF - B9 05000000           - mov ecx,00000005
 
Tutorial-x86_64.exe+2B4B4 - E8 5747FEFF           - call Tutorial-x86_64.exe+FC10
 
Tutorial-x86_64.exe+2B4B9 - 83 C0 01              - add eax,01
 
Tutorial-x86_64.exe+2B4BC - E9 3F4BFBFF           - jmp FFFE0000
 
 
  FFFE0000 - 31 C0                                - xor eax,eax  // your newmem code
 
  FFFE0002 - E9 BBB40400                          - jmp Tutorial-x86_64.exe+2B4C2
 
 
Tutorial-x86_64.exe+2B4C2 - 48 8D 4D F8           - lea rcx,[rbp-08]
 
Tutorial-x86_64.exe+2B4C6 - E8 45DAFDFF           - call Tutorial-x86_64.exe+8F10
 
Tutorial-x86_64.exe+2B4CB - 8B 8B F8070000        - mov ecx,[rbx+000007F8]
 
... | 	  
 
Data like `dd (int)2` doesn't get executed by the game like code does. CE will write the value into memory, and other code can refer to that value (i.e. `mov edx, [paymultiplier]`); however, simply referring to a value doesn't mean it gets executed. _________________
 I don't know where I'm going, but I'll figure it out when I get there.  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		gamerp Newbie cheater
  Reputation: 0
  Joined: 20 Mar 2024 Posts: 10
 
  | 
		
			
				 Posted: Thu Mar 21, 2024 7:46 am    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				Ah, so initialisation runs all the data related instructions while the injection hook only runs all the processing related instructions. Kind of like constructors in OOP I'm guessing.
 
 
Thanks for the detailed explanation!   | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
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
  | 
   
 
		 |