| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| BigCrock5 How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 26 Apr 2022
 Posts: 9
 
 
 | 
			
				|  Posted: Wed Apr 27, 2022 2:11 pm    Post subject: CREATETHREAD just crashes unity game |   |  
				| 
 |  
				| I'm trying to inject code into a unity game and run it using CREATETHREAD. 
 If I run the same code using a code injection hook, it runs fine.
 
 If I run it using CREATETHREAD, the game crashes instantly.
 
 Is there something I'm missing?
 
 
  	  | Code: |  	  | alloc(mycode,4096)
 CREATETHREAD(mycode);
 
 mycode:
 mov rcx,(PlayerOffset)         // Move player offset into rcx
 mov rcx,[rcx]                  // Dereference player offset
 mov eax,(float)100             // Move 100f into register
 movd xmm1,eax                  // Transfer to xmm1 as per calling convention
 call "GameAssembly.dll"+75DB30 // Call the heal function
 ret
 
 | 
 
 Edit: The crash code is a C0000005
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Wed Apr 27, 2022 5:00 pm    Post subject: |   |  
				| 
 |  
				| A quick search tells you C0000005 is an access violation. 
 You aren't passing the right arguments, globals aren't in the correct state, and/or there's a pointer path from some argument or global to some value that isn't in the correct state. Step into the code and figure it out. (a break-and-trace might help)
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| BigCrock5 How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 26 Apr 2022
 Posts: 9
 
 
 | 
			
				|  Posted: Wed Apr 27, 2022 5:14 pm    Post subject: |   |  
				| 
 |  
				| I was thinking it may be related to some registers not being available because it's running a new thread or something like that. 
 If I call the code from a hook it works perfectly, if I call the exact same code from a thread, it does not work.
 
 I created a small test app and hooked into it and called it on that and it worked, so I'm guessing there is some global state that cannot be accessed.
 
 Or unity has a certain time window where you can make these updates.
 
 But a buffer overflow sounds odd.
 
 EDIT:
 
 So I did some debugging, it fails on a piece of code:
 
 
  	  | Code: |  	  | movaps [rsp+30],xmm6 | 
 
 So it's either RSP or XMM6 that are the issue.
 
 Upon comparing the registers at this point, xmm6 in the main thread has a value, whereas it is 0 in my thread, I don't know if this could cause an error with the movaps op.
 
 So that leaves RSP, it has a value in both, so I'm not sure if this is the issue.
 
 Is it possible to copy the registers from the main game thread into my newly created thread? I hope this may help the consistency issues.
 
 EDIT AGAIN:
 
 It seems RSP is the issue, RSP+30 doesn't seem to be aligned to 32 bits like it says it should be in the docs. Not sure what the solution to this is
   
 FINAL UPDATE:
 
 I actually got something working?!
 
 It seems subbing 0x28 (#40) from RSP before calling will allow the function to work. NO IDEA WHY OR HOW.
 
 If anyone could enlighten me that would be much appreciated.
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Wed Apr 27, 2022 7:18 pm    Post subject: |   |  
				| 
 |  
				| Oh, right, my bad. In windows x64 ABI the stack must have a shadow store for the four register parameters (0x20 bytes) prior to a call as well as 16-byte alignment most of the time. https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170
 
 The 16-byte alignment is what's causing movaps ("move aligned packed singles") to fail. If you fixed that, it might still fail if the return address was corrupted.
 
 Allocating 0x28 bytes on the stack w/ `sub rsp,28` will give 0x20 bytes for the shadow store and align the stack to 0x10 bytes (the other 8 were from the return address of the call that called "mycode")
 
 I think you could also just do a tail call and everything will work:
 
 The stack is already aligned, and this re-uses the shadow store from the caller of "mycode". 	  | Code: |  	  | mycode: mov rcx,(PlayerOffset)
 mov rcx,[rcx]
 mov eax,(float)100
 movd xmm1,eax
 jmp "GameAssembly.dll"+75DB30
 | 
 It also has the added benefit that you can disable the script and deallocate memory even if the thread is still executing the call.
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| BigCrock5 How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 26 Apr 2022
 Posts: 9
 
 
 | 
			
				|  Posted: Wed Apr 27, 2022 7:20 pm    Post subject: |   |  
				| 
 |  
				| So `jmp` instead of `call` will work? 
 Just curious, how would this work if I wanted to call multiple functions? Once I've used jmp, I cannot get back?
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Wed Apr 27, 2022 7:35 pm    Post subject: |   |  
				| 
 |  
				| `call` works by pushing the return address (next instruction) on the stack. `ret` uses that to return to the caller. `jmp` simply branches to the target address. In general, there's no way to get back to where you started from.
 Look up "tail call" for more information.
 
 If you want to call several functions, then you can't generally do that with a single jmp. You'll have to allocate space on the stack to adhere to windows x64 calling conventions.
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Dark Byte Site Admin
 
  Reputation: 470 
 Joined: 09 May 2003
 Posts: 25807
 Location: The netherlands
 
 | 
			
				|  Posted: Thu Apr 28, 2022 1:43 am    Post subject: |   |  
				| 
 |  
				| Also, since it's unity, likely il2cpp?  you'll often have to call il2cpp_thread_attach to setup the TLS information for the current thread in case the routine you're calling wants to call something .net specific _________________
 
 Do not ask me about online cheats. I don't know any and wont help finding them.
 Like my help? Join me on Patreon so i can keep helping
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| BigCrock5 How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 26 Apr 2022
 Posts: 9
 
 
 | 
			
				|  Posted: Thu Apr 28, 2022 5:59 am    Post subject: |   |  
				| 
 |  
				| How can I observe the return value of a function if I’m using jmp? 
 I’d originally planned to mov output,rax  after the call but it seems that wont be possible with jmp.
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Dark Byte Site Admin
 
  Reputation: 470 
 Joined: 09 May 2003
 Posts: 25807
 Location: The netherlands
 
 | 
			
				|  Posted: Thu Apr 28, 2022 6:40 am    Post subject: |   |  
				| 
 |  
				| don't use jmp, use call _________________
 
 Do not ask me about online cheats. I don't know any and wont help finding them.
 Like my help? Join me on Patreon so i can keep helping
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| BigCrock5 How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 26 Apr 2022
 Posts: 9
 
 
 | 
			
				|  Posted: Thu Apr 28, 2022 6:57 am    Post subject: |   |  
				| 
 |  
				| And in that case, what should I sub from rsp? |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Dark Byte Site Admin
 
  Reputation: 470 
 Joined: 09 May 2003
 Posts: 25807
 Location: The netherlands
 
 | 
			
				|  Posted: Thu Apr 28, 2022 7:10 am    Post subject: |   |  
				| 
 |  
				| 28 
 8 to align and 20 for scratchspace
 _________________
 
 Do not ask me about online cheats. I don't know any and wont help finding them.
 Like my help? Join me on Patreon so i can keep helping
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| BigCrock5 How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 26 Apr 2022
 Posts: 9
 
 
 | 
			
				|  Posted: Sat Apr 30, 2022 9:18 am    Post subject: |   |  
				| 
 |  
				| I've made a lot of progress, but some functions don't seem to work, and others do. 
 For example, I can call the set_position function on a Unity Transform, but get_position just crashes the game.
 
 Seems to be an access violation again, this approach works for
 
 Component->get_gameObject
 
 GameObject -> get_transform
 
 but not
 
 Transform -> get_position
 
 Not really sure what to do next.
 
 I'm trying to run the following:
 
 
  	  | Code: |  	  | mov rcx,(PlayerOffset)
 mov rcx,[rcx]
 call GameAssembly.dll+D852B0 // Get the GameObject
 mov rcx,rax
 call GameAssembly.dll+D89E70 // Get transform
 mov rcx,rax
 call GameAssembly.dll+1466C10 // Get position
 
 | 
 
 The last call completely crashes the game.
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Dark Byte Site Admin
 
  Reputation: 470 
 Joined: 09 May 2003
 Posts: 25807
 Location: The netherlands
 
 | 
			
				|  Posted: Mon May 02, 2022 5:46 am    Post subject: |   |  
				| 
 |  
				| you're sure they take no parameters ? _________________
 
 Do not ask me about online cheats. I don't know any and wont help finding them.
 Like my help? Join me on Patreon so i can keep helping
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| BigCrock5 How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 26 Apr 2022
 Posts: 9
 
 
 | 
			
				|  Posted: Mon May 02, 2022 6:49 am    Post subject: |   |  
				| 
 |  
				| It's a C# property, so I'm assuming it just takes the thisPtr and nothing else. 
 
  	  | Code: |  	  | [Token(Token = "0x170001AB")] public Vector3 position
 {
 [Token(Token = "0x6000788")]
 [Address(RVA = "0x1466C10", Offset = "0x1465E10", VA = "0x181466C10")]
 get
 {
 return default(Vector3);
 }
 [Token(Token = "0x6000789")]
 [Address(RVA = "0x1467380", Offset = "0x1466580", VA = "0x181467380")]
 set
 {
 }
 }
 | 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Bloodybone Newbie cheater
 
 ![]() Reputation: 0 
 Joined: 07 Dec 2016
 Posts: 21
 Location: Germany
 
 | 
			
				|  Posted: Mon May 02, 2022 1:25 pm    Post subject: |   |  
				| 
 |  
				| When you have a funtion that returns a Vector3, the first parameter should be a memory location that can hold 3 Floats. 
 So using your code, you'll have to change it like so:
 
 
  	  | Code: |  	  | sub rsp,30 // 0x20 for Callees and the other 0x10 for the returned position later on. You'll have to sub rsp,38 if the stack isn't aligned yet mov rcx,(PlayerOffset)
 mov rcx,[rcx]
 call GameAssembly.dll+D852B0 // Get the GameObject
 mov rcx,rax
 call GameAssembly.dll+D89E70 // Get transform
 lea rcx,[rsp+20] // Space for returned postion
 mov rdx,rax
 call GameAssembly.dll+1466C10 // Get position
 // [rax] // [rsp+20] = X
 // [rax+4] // [rsp+24] = Y
 // [rax+8] // [rsp+28] = Z
 add rsp,30 // Free space
 | 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		|  |