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 


Mono Adress for Code injection ends in wrong position

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Mac99
Newbie cheater
Reputation: 0

Joined: 13 Sep 2022
Posts: 14

PostPosted: Tue Sep 13, 2022 3:25 pm    Post subject: Mono Adress for Code injection ends in wrong position Reply with quote

I am not new to cheat engine, but this is my first time trying to make a persistent code injection.

I am doing this on a fairly new game called Disney Dreamlight Valley which is based on Unity. I've a found an instruction that accesses the Player's Stamina. On the base of the address of this instruction, I want to do a code injection and thus change the stamina. In my test example, I just wanted to do a code injection that shouldn't change anything. Unfortunately, my injected code end up in the wrong address and crashes the game.
The targeted instruction is "cmp [rcx+00000088],edx" which follows a Mono "address". The name of the Mono address is "Meta.ProfilePlayer.HasEnoughMana" and with a offset of 2 it hits my targeted instruction.

Maybe I am completely misunderstanding how code injection works in cheat engine, so I need the help of an experienced person.

This is my code
Code:

define(address,Meta.ProfilePlayer.HasEnoughMana)
[ENABLE]

alloc(newmem,$1000)

label(code)
label(return)

newmem:

code:
  cmp [rcx+00000088],edx
  jmp return


address+2:
  jmp code
  nop
return:
registersymbol(address)
dealloc(newmem)

[DISABLE]

address+02:
  db 89 83 88 00 00 00

unregistersymbol(address)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: GameAssembly.dll+93D7BD

GameAssembly.dll+93D78E: E8 6D E6 A6 FF           - call GameAssembly.dll+3ABE00
GameAssembly.dll+93D793: 48 8D 0D 36 A3 19 04     - lea rcx,[GameAssembly.dll+4AD7AD0]
GameAssembly.dll+93D79A: E8 61 E6 A6 FF           - call GameAssembly.dll+3ABE00
GameAssembly.dll+93D79F: C6 05 3C DF 51 04 01     - mov byte ptr [GameAssembly.dll+4E5B6E2],01
GameAssembly.dll+93D7A6: 48 89 7C 24 60           - mov [rsp+60],rdi
GameAssembly.dll+93D7AB: 8B B3 88 00 00 00        - mov esi,[rbx+00000088]
GameAssembly.dll+93D7B1: 3B F5                    - cmp esi,ebp
GameAssembly.dll+93D7B3: 0F 8C A7 00 00 00        - jl GameAssembly.dll+93D860
GameAssembly.dll+93D7B9: 8B C6                    - mov eax,esi
GameAssembly.dll+93D7BB: 2B C5                    - sub eax,ebp
// ---------- INJECTING HERE ----------
GameAssembly.dll+93D7BD: 89 83 88 00 00 00        - mov [rbx+00000088],eax
// ---------- DONE INJECTING  ----------
GameAssembly.dll+93D7C3: 48 8B 0D 06 A3 19 04     - mov rcx,[GameAssembly.dll+4AD7AD0]
GameAssembly.dll+93D7CA: E8 71 E7 A6 FF           - call GameAssembly.dll+3ABF40
GameAssembly.dll+93D7CF: 33 D2                    - xor edx,edx
GameAssembly.dll+93D7D1: 48 8B C8                 - mov rcx,rax
GameAssembly.dll+93D7D4: 48 8B F8                 - mov rdi,rax
GameAssembly.dll+93D7D7: E8 94 B6 AA FF           - call System.Text.EncoderExceptionFallbackBuffer..ctor
GameAssembly.dll+93D7DC: 48 85 FF                 - test rdi,rdi
GameAssembly.dll+93D7DF: 0F 84 96 00 00 00        - je GameAssembly.dll+93D87B
GameAssembly.dll+93D7E5: 89 6F 10                 - mov [rdi+10],ebp
GameAssembly.dll+93D7E8: 48 8B AC 24 80 00 00 00  - mov rbp,[rsp+00000080]
}
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 Sep 13, 2022 4:00 pm    Post subject: Reply with quote

Just use a template. Highlight the instruction in the disassembler, open up an Auto Assembler window, and select Template -> AOB Injection

If you don't want to do an aobscan, use the full injection template instead.

alloc should have a third parameter in 64-bit targets. (avoids rip-relative addressing problems)

The original instruction appears to be `mov`, not `cmp`

_________________
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
Mac99
Newbie cheater
Reputation: 0

Joined: 13 Sep 2022
Posts: 14

PostPosted: Wed Sep 14, 2022 2:18 am    Post subject: Reply with quote

I've tried an aob injection, but I've never found any pair of instructions that is unique enough.

I also don't know how to even select the right instruction when aob scan tries to match more than one instruction, where my desirable instruction is one of them.

The Original Code used to change another instruction, but since then I've changed the instruction. Since aob didn't work, I tried a code injection with the Mono address as a base.
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 941

PostPosted: Wed Sep 14, 2022 4:01 am    Post subject: Reply with quote

Try change
Code:

define(address,Meta.ProfilePlayer.HasEnoughMana)
[ENABLE]
alloc(newmem,$1000)

to
Code:

[ENABLE]
//// 'address'   SHOULD USE a more UNIQUE NAME
AOBScanRegion(address,Meta.ProfilePlayer.HasEnoughMana,Meta.ProfilePlayer.HasEnoughMana+100, ?? ?? 89 83 88 00 00 00)  //// ^ [89 83 88 00 00 00] shoudl be your original code of 'cmp [rcx+00000088],edx'
alloc(newmem,$1000,address)


The aobscan assure the right pattern, and 3rd parameter of 'alloc' set to 'address' have a NEAR cave so that the jmp instruction is 5 bytes long.
If the function has no overloaded, it should work.

_________________
- Retarded.
Back to top
View user's profile Send private message
Mac99
Newbie cheater
Reputation: 0

Joined: 13 Sep 2022
Posts: 14

PostPosted: Wed Sep 14, 2022 11:38 am    Post subject: Reply with quote

Thx for your help, I got it working, but it seems like code injection doesn't work in this game the way it is normally used.

I've tried several instructions that change Gold, Stamina, Dreamlight and whenever I use code injection I just change the displayed value not the real value.

I've also checked that this is also the instruction that reads the real value, not the displayed one.

I really don't know what to do at this point.
Back to top
View user's profile Send private message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Wed Sep 14, 2022 2:40 pm    Post subject: Reply with quote

Half the time that happens you just need the change the value it is writing from instead of the value it is writing to. The rest of the time you need to backtrace the instructions to find where the originating value is stored to change it at the source.

For example if it was mov eax, ebx. You could write into eax and have it not work because the game uses ebx, so you should write ebx instead.
Back to top
View user's profile Send private message
Mac99
Newbie cheater
Reputation: 0

Joined: 13 Sep 2022
Posts: 14

PostPosted: Wed Sep 14, 2022 5:54 pm    Post subject: Reply with quote

cooleko wrote:
Half the time that happens you just need the change the value it is writing from instead of the value it is writing to. The rest of the time you need to backtrace the instructions to find where the originating value is stored to change it at the source.

For example if it was mov eax, ebx. You could write into eax and have it not work because the game uses ebx, so you should write ebx instead.


That is a good idea, but I can't get the variable to be stored in my pointer. Somehow, my pointer is never defined.
I thought that in a mov eax, ebx both variables have the same byte length.
So the defined bytes for my pointer shouldn't change.
I also checked the temporary variable (r15) for storing ebx is also always 0 so I don't accidentaly overwrite anything.
Maybe my way of saving ebx in a pointer is just old school and there is a better method.
Maybe you got a good advice for me?

Code:

[ENABLE]

aobscanmodule(INJECT1,GameAssembly.dll,FF CC CC CC CC 48 89 51 28 C3) // should be unique
alloc(newmem,$1000,INJECT1)

label(code)
label(return)

globalalloc(gold,4)

newmem:

code:
  push r15
  mov r15, gold
  mov [r15],rdx
  pop r15
  mov [rcx+28],rdx
  ret
  jmp return

INJECT1+05:
  jmp newmem
return:
registersymbol(INJECT1)

[DISABLE]

INJECT1+05:
  db 48 89 51 28 C3

unregistersymbol(INJECT1)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: 7FF889191920

7FF88919190D: CC              - int 3
7FF88919190E: CC              - int 3
7FF88919190F: CC              - int 3
7FF889191910: 48 83 C1 18     - add rcx,18
7FF889191914: 48 89 11        - mov [rcx],rdx
7FF889191917: E9 64 A0 EA FF  - jmp 7FF88903B980
7FF88919191C: CC              - int 3
7FF88919191D: CC              - int 3
7FF88919191E: CC              - int 3
7FF88919191F: CC              - int 3
// ---------- INJECTING HERE ----------
7FF889191920: 48 89 51 28     - mov [rcx+28],rdx
// ---------- DONE INJECTING  ----------
7FF889191924: C3              - ret
7FF889191925: CC              - int 3
7FF889191926: CC              - int 3
7FF889191927: CC              - int 3
7FF889191928: CC              - int 3
7FF889191929: CC              - int 3
7FF88919192A: CC              - int 3
7FF88919192B: CC              - int 3
7FF88919192C: CC              - int 3
7FF88919192D: CC              - int 3
}
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 Sep 14, 2022 7:28 pm    Post subject: Reply with quote

`globalalloc(gold,4)` - rdx is 64 bits (8 bytes)

You're saving the value rdx and not the address rcx

The memory record should be a pointer- base address is gold, only offset is 28

Remember to activate the script and do whatever you need to do in game for the code injection to run

_________________
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
Mac99
Newbie cheater
Reputation: 0

Joined: 13 Sep 2022
Posts: 14

PostPosted: Sat Sep 17, 2022 8:53 am    Post subject: Reply with quote

ParkourPenguin wrote:
`globalalloc(gold,4)` - rdx is 64 bits (8 bytes)

You're saving the value rdx and not the address rcx

The memory record should be a pointer- base address is gold, only offset is 28

Remember to activate the script and do whatever you need to do in game for the code injection to run


When I look up the value for rdx in the assembler code as a pointer address it's always undefinded (?), so rdx doesn't seem to be a pointer to address nor does it hold any reasonable value.

The real issue it seems to me is that the methods for gold, mana and stamina are called by the real value and the displayed values.
When the last method call was for the displayed value, I always get the fake value mapped in my pointer.
I've tried to find some registers that differ to make sure I only save a pointer to the real value,
but after every game restart there is too much randomness in it.

I've invested a lot of time now and learned a lot about cheat engine, but whatever method I tried, it never succeeded.
It's really frustrating, and it might the end to my short experience since I don't see any solution anymore.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Sat Sep 17, 2022 9:39 am    Post subject: Reply with quote

Mac99 wrote:
When I look up the value for rdx in the assembler code as a pointer address it's always undefinded (?), so rdx doesn't seem to be a pointer to address nor does it hold any reasonable value.
ParkourPenguin wrote:
You're saving the value rdx and not the address rcx
AKA: rcx is the pointer you want
_________________
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
Mac99
Newbie cheater
Reputation: 0

Joined: 13 Sep 2022
Posts: 14

PostPosted: Sat Sep 17, 2022 11:59 am    Post subject: Reply with quote

ParkourPenguin wrote:
Mac99 wrote:
When I look up the value for rdx in the assembler code as a pointer address it's always undefinded (?), so rdx doesn't seem to be a pointer to address nor does it hold any reasonable value.
ParkourPenguin wrote:
You're saving the value rdx and not the address rcx
AKA: rcx is the pointer you want


Yes, rcx is the pointer to the memory address where my value is stored.
Issue still is that this method gets called multiple times, so this method as well as my injected code gets called multiple times with different rcx.
Some hold wrong pointers that I don't want, and only one of them is the right pointer.
rdx is the value that gets written in rcx. I've wondered why rdx is such a big hex value, that as pointer points to nowhere, it isn't a pointer.
rdx is just coded in UINT32 as well as rcx which means the last only the 4 digits are the value I want. You probably can see in the image my try to get some sense in the value of rdx.

I need a safe indication that tells my code this is the rcx value that points to the right address.
I've tried to scan for commonalities among the register values but not success.



Screenshot 2022-09-17 194440.png
 Description:
 Filesize:  241.15 KB
 Viewed:  1869 Time(s)

Screenshot 2022-09-17 194440.png


Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 941

PostPosted: Sat Sep 17, 2022 4:05 pm    Post subject: Reply with quote

I'm not sure, if rcx is an instance of a class, may [rcx] be point to the vtable of the class?
I don't know if il2cpp can get the vtable by name, but I think if above is true, you can alternatively log this [rcx] from the target class's unique function eg, Update()? Then you can compare the logged vtable with the [rcx] in your inject point.

_________________
- Retarded.
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
Page 1 of 1

 
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