  | 
				
				Cheat Engine The Official Site of Cheat Engine   
				
 
				 | 
			 
		 
		 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		Gear2ndGandalf Cheater
  Reputation: 0
  Joined: 22 Jan 2018 Posts: 36 Location: USA
  | 
		
			
				 Posted: Tue Mar 19, 2024 11:31 pm    Post subject: How Can I Store Values VIA AA Script? | 
				       | 
			 
			
				
  | 
			 
			
				I'm looking to scan last projectile fired on Halo 2, and then store its' value in an allocated storage.
 
 
I don't want duplicates of the same projectile IDs filling up all the ID slots, and I don't want the occupied ID slots to get overwritten with more recently fired projectile IDs.
 
 
The code I wrote works for several minutes before crashing the game randomly. There's got to be a better way to do this.
 
 
The purpose for this is every Halo .map has different values for all projectiles, and it would be asinine to play through every map to build a dropdown list. Please help!
 
 
Warning! Redundant Code Ahead!
 
 	  | Code: | 	 		  { Game   : mcc-win64-shipping.exe
 
  Version: 1.0
 
  Date   : 2024-03-02
 
  Author : Gear2
 
 
  Scans the last fired projectile and storges all the different type of projectile
 
  IDs. They are unique on every map.
 
}
 
 
[ENABLE]
 
 
{$lua}
 
if syntaxcheck then return end
 
messageDialog('INFO!', 'Each map has unique projectile IDs. Reactivate this script after each map to clear the storage IDs.', mtInformation, mbOK)
 
{$asm}
 
 
aobscanmodule(projectileRead,halo2.dll,45 33 C9 44 8B 80 90 00 00 00)
 
alloc(newmem,$10000,projectileRead)
 
alloc(scan,$48,projectileRead)
 
alloc(swapMode,$48,projectileRead)
 
alloc(converter,$48,projectileRead)
 
alloc(ID_1,$48,projectileRead)
 
alloc(ID_2,$48,projectileRead)
 
alloc(ID_3,$48,projectileRead)
 
alloc(ID_4,$48,projectileRead)
 
alloc(ID_5,$48,projectileRead)
 
alloc(ID_6,$48,projectileRead)
 
alloc(ID_7,$48,projectileRead)
 
alloc(ID_8,$48,projectileRead)
 
alloc(ID_9,$48,projectileRead)
 
alloc(ID_10,$48,projectileRead)
 
alloc(ID_11,$48,projectileRead)
 
alloc(ID_12,$48,projectileRead)
 
alloc(ID_13,$48,projectileRead)
 
alloc(ID_14,$48,projectileRead)
 
alloc(ID_15,$48,projectileRead)
 
alloc(ID_16,$48,projectileRead)
 
alloc(ID_17,$48,projectileRead)
 
alloc(ID_18,$48,projectileRead)
 
alloc(ID_19,$48,projectileRead)
 
alloc(ID_20,$48,projectileRead)
 
 
label(code)
 
label(store_1)
 
label(store_2)
 
label(store_3)
 
label(store_4)
 
label(store_5)
 
label(store_6)
 
label(store_7)
 
label(store_8)
 
label(store_9)
 
label(store_10)
 
label(store_11)
 
label(store_12)
 
label(store_13)
 
label(store_14)
 
label(store_15)
 
label(store_16)
 
label(store_17)
 
label(store_18)
 
label(store_19)
 
label(store_20)
 
label(return)
 
 
swapMode:
 
  db 1
 
 
ID_1:
 
  dq 00000000
 
 
ID_2:
 
  dq 00000000
 
 
ID_3:
 
  dq 00000000
 
 
ID_4:
 
  dq 00000000
 
 
ID_5:
 
  dq 00000000
 
 
ID_6:
 
  dq 00000000
 
 
ID_7:
 
  dq 00000000
 
 
ID_8:
 
  dq 00000000
 
 
ID_9:
 
  dq 00000000
 
 
ID_10:
 
  dq 00000000
 
 
ID_11:
 
  dq 00000000
 
 
ID_12:
 
  dq 00000000
 
 
ID_13:
 
  dq 00000000
 
 
ID_14:
 
  dq 00000000
 
 
ID_15:
 
  dq 00000000
 
 
ID_16:
 
  dq 00000000
 
 
ID_17:
 
  dq 00000000
 
 
ID_18:
 
  dq 00000000
 
 
ID_19:
 
  dq 00000000
 
 
ID_20:
 
  dq 00000000
 
 
converter:
 
  dq 00000000
 
 
newmem:
 
  mov [scan],rax
 
  cmp [swapMode],1
 
  je store_1
 
  cmp [converter],00000000
 
  je code
 
  push rcx
 
  mov ecx,[converter]
 
  mov [rax+90],ecx
 
  pop rcx
 
  mov r8d,[rax+90]
 
  jmp return
 
 
store_1:
 
  cmp [ID_1],00000000
 
  ja store_2
 
  push rdx
 
  mov edx,[rax+90]
 
  mov [ID_1],edx
 
  pop rdx
 
  jmp code
 
 
store_2:
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_1],ebx
 
  pop rbx
 
  je code
 
  cmp [ID_2],00000000
 
  ja store_3
 
  push rdx
 
  mov edx,[rax+90]
 
  mov [ID_2],edx
 
  pop rdx
 
  jmp code
 
 
store_3:
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_1],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_2],ebx
 
  pop rbx
 
  je code
 
  cmp [ID_3],00000000
 
  ja store_4
 
  push rdx
 
  mov edx,[rax+90]
 
  mov [ID_3],edx
 
  pop rdx
 
  jmp code
 
 
...(omitting extra code here for clarities sake)
 
 
store_20:
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_1],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_2],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_3],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_4],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_5],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_6],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_7],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_8],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_9],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_10],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_11],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_12],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_13],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_14],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_15],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_16],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_17],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_18],ebx
 
  pop rbx
 
  je code
 
  push rbx
 
  mov ebx,[rax+90]
 
  cmp [ID_19],ebx
 
  pop rbx
 
  je code
 
  push rdx
 
  mov edx,[rax+90]
 
  mov [ID_20],edx
 
  pop rdx
 
  jmp code
 
 
code:
 
  mov r8d,[rax+00000090]
 
  jmp return
 
 
projectileRead+3:
 
  jmp newmem
 
  nop 2
 
return:
 
registersymbol(projectileRead)
 
registersymbol(scan)
 
registersymbol(swapMode)
 
registersymbol(converter)
 
registersymbol(ID_1)
 
registersymbol(ID_2)
 
registersymbol(ID_3)
 
registersymbol(ID_4)
 
registersymbol(ID_5)
 
registersymbol(ID_6)
 
registersymbol(ID_7)
 
registersymbol(ID_8)
 
registersymbol(ID_9)
 
registersymbol(ID_10)
 
registersymbol(ID_11)
 
registersymbol(ID_12)
 
registersymbol(ID_13)
 
registersymbol(ID_14)
 
registersymbol(ID_15)
 
registersymbol(ID_16)
 
registersymbol(ID_17)
 
registersymbol(ID_18)
 
registersymbol(ID_19)
 
registersymbol(ID_20)
 
 
[DISABLE]
 
 
projectileRead+3:
 
  db 44 8B 80 90 00 00 00
 
 
unregistersymbol(*)
 
dealloc(*) | 	  
 
 
 
Please view attactments for code injection point, and Cheat Table showing intended way to use this script.
	
  
	 
	
	
		
	 
	
		|  Description: | 
		
			
			
				| Testing On Cairo Station Map. | 
			 
			 
		 | 
	 
	
		|  Filesize: | 
		 254.74 KB | 
	 
	
		|  Viewed: | 
		 13442 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
	 
	
	
		
	 
	
		|  Description: | 
		
			
		 | 
	 
	
		|  Filesize: | 
		 105.09 KB | 
	 
	
		|  Viewed: | 
		 13442 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
	 
	
	
		
	 
	
		|  Description: | 
		
			
		 | 
	 
	
		|  Filesize: | 
		 308.86 KB | 
	 
	
		|  Viewed: | 
		 13442 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
  Last edited by Gear2ndGandalf on Thu Mar 21, 2024 12:54 am; edited 3 times in total | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		ParkourPenguin I post too much
  Reputation: 152
  Joined: 06 Jul 2014 Posts: 4706
 
  | 
		
			
				 Posted: Wed Mar 20, 2024 2:50 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				wtf why did you unroll that loop like that
 
 
You don't need 0x48 bytes to store a 4 byte value
 
 
I guess `converter` is the "Output ID" memrec in Cheat_Functionality.jpg
 
 
Do you really need `swapMode`? You could just do both. Recording a new value and modifying the value in memory isn't mutually exclusive.
 
 
Why are you pushing and popping all those registers all the time? You should only need to push / pop each register once- push it at the beginning (back it up), use it as many times as you need, then pop it at the end (restore it)
 
 
I didn't really read those 1000+ lines of code in that unrolled loop. You should probably just edit your post and delete everything between `store_3:` and `store_20:`. Readers can figure out the rest
 
 
A bit better:
 
 	  | Code: | 	 		  ...
 
aobscanmodule(projectileRead,halo2.dll,45 33 C9 44 8B 80 90 00 00 00)
 
alloc(newmem,2048,projectileRead)
 
alloc(scan,8,projectileRead)
 
alloc(swapMode,4,projectileRead)
 
alloc(converter,4,projectileRead) 
 
alloc(projectileStorage,80,projectileRead)  // 4*20
 
 
label(checkStorage)
 
label(loop)
 
label(exitLoop)
 
label(recordValue)
 
label(originalCode)
 
 
scan:
 
  dq 0
 
swapMode:
 
  dd 0
 
converter:
 
  dd 0
 
projectileStorage:
 
  dd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  // 20 4-byte values
 
 
newmem:
 
  mov [scan],rax
 
 
  cmp dword ptr[swapMode],0
 
  je checkStorage
 
 
// try to swap: check value
 
  mov r8d,[converter]
 
  test r8d,r8d
 
  je originalCode
 
  
 
// swap game value w/ user-defined value
 
  mov [rax+90],r8d
 
  jmp return
 
 
checkStorage:
 
// loop through projectileStorage, record game value if not yet recorded
 
  push rcx
 
  push rdx
 
  // rbx is free right now
 
 
  mov r8d,[rax+90]  // r8d = game value
 
  lea rbx,[projectileStorage]
 
  xor ecx,ecx
 
 
loop:
 
  mov edx,[rbx+rcx*4]  // value in projectileStorage
 
  test edx,edx
 
  jz recordValue  // if projectileStorage slot is 0 (no record), use this slot
 
  cmp r8d,edx
 
  je exitLoop     // if value is already recorded, ignore it
 
 
  inc ecx
 
  cmp ecx,#20
 
  jb loop         // only check at most 20 items
 
 
exitLoop:
 
  pop rdx
 
  pop rcx
 
  jmp return
 
  
 
recordValue:
 
  mov [rbx+rcx*4],r8d
 
  jmp exitLoop
 
 
originalCode:
 
  mov r8d,[rax+90]
 
  jmp return
 
 
 
projectileRead+3:
 
  jmp newmem
 
  nop 2
 
return:
 
 
registersymbol(projectileRead)
 
registersymbol(scan)
 
registersymbol(swapMode)
 
registersymbol(converter)
 
registersymbol(projectileStorage) 
 
... | 	  
 
Memory record addresses should be `projectileStorage`, `projectileStorage+4`, `projectileStorage+8`, `projectileStorage+C`, ..., `projectileStorage+4C`
 _________________
 I don't know where I'm going, but I'll figure it out when I get there.  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Gear2ndGandalf Cheater
  Reputation: 0
  Joined: 22 Jan 2018 Posts: 36 Location: USA
  | 
		
			
				 Posted: Wed Mar 20, 2024 8:18 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				I went ahead and made the post much shorter like you suggested. Thanks for your help! I'm going over your example code now.
 
 
Your code is genius! Only thing is, the script is not storing the projectiles for some reason. When I fire all the addresses in [rbx+rcx*4] change to 00000000.
 
 
Issue_1: 1st Fired Weapon Results In All Storage IDs Equaling 00000000
 
Issue_2: 2nd Fired Weapon Results In All Storage ID's Equaling ??
 
 
Sorry to ask, but please help further if possible!
 
 
 
 
Please view attactments for clarity on current issue.
	
  
	 
	
	
		
	 
	
		|  Description: | 
		
			
			
				| 1st Fired Weapon Results In All Storage IDs Equaling 00000000 | 
			 
			 
		 | 
	 
	
		|  Filesize: | 
		 101.63 KB | 
	 
	
		|  Viewed: | 
		 13376 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
	 
	
	
		
	 
	
		|  Description: | 
		
			
			
				| 2nd Fired Weapon Results In All Storage ID's Equaling ?? | 
			 
			 
		 | 
	 
	
		|  Filesize: | 
		 80.75 KB | 
	 
	
		|  Viewed: | 
		 13376 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
	 
	
	
		
	 
	
		|  Description: | 
		
			
		 | 
	 
	
		|  Filesize: | 
		 150.69 KB | 
	 
	
		|  Viewed: | 
		 13376 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
 | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		ParkourPenguin I post too much
  Reputation: 152
  Joined: 06 Jul 2014 Posts: 4706
 
  | 
		
			
				 Posted: Wed Mar 20, 2024 10:25 pm    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				What does the "Change address" window of the memory records "Storage_ID_*" look like? They shouldn't be pointers; they should just be simple addresses. Like in your first post, "Cheat_Functionality.jpg"
 _________________
 I don't know where I'm going, but I'll figure it out when I get there.  | 
			 
		  | 
	 
	
		| Back to top | 
		 | 
	 
	
		  | 
	 
	
		Gear2ndGandalf Cheater
  Reputation: 0
  Joined: 22 Jan 2018 Posts: 36 Location: USA
  | 
		
			
				 Posted: Thu Mar 21, 2024 12:00 am    Post subject:  | 
				       | 
			 
			
				
  | 
			 
			
				I'll change them to see what I get. Thanks!
 
 
Edit: All is well! It was a blunder on my part using pointers. You're a mad genius Penguin thanks!
 
 
I will do test runs for each map. To clear the storage list I must deactivate and reactivate the script or set them all to zero when the map changes.
 
 
If players try to use IDs from the wrong map the game will crash. Any incorrect ID converted to output will crash the game.
	
  
	 
	
	
		
	 
	
		|  Description: | 
		
			
			
				| Storage IDs Improperly Using Pointers. | 
			 
			 
		 | 
	 
	
		|  Filesize: | 
		 24.84 KB | 
	 
	
		|  Viewed: | 
		 13357 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
	 
	
	
		
	 
	
		|  Description: | 
		
			
			
				| Storage IDs Properly Using Offsets But No Pointers. | 
			 
			 
		 | 
	 
	
		|  Filesize: | 
		 17.84 KB | 
	 
	
		|  Viewed: | 
		 13357 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
	 
	
	
		
	 
	
		|  Description: | 
		
			
			
				| All the projectiles are being stored and NOT overwritting or duplicating on the list! | 
			 
			 
		 | 
	 
	
		|  Filesize: | 
		 52.62 KB | 
	 
	
		|  Viewed: | 
		 13357 Time(s) | 
	 
	
		
  
 
  | 
	 
	 
	 
 | 
			 
		  | 
	 
	
		| 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
  | 
   
 
		 |