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 


Need help adding a XP multiplier

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Zephyr_92
How do I cheat?
Reputation: 0

Joined: 11 Nov 2022
Posts: 3

PostPosted: Fri Nov 11, 2022 3:54 pm    Post subject: Need help adding a XP multiplier Reply with quote

Hello, I am new to CE and am currently trying to do a XP multiplier script in Strangers of Paradise but no luck so far.

I managed to find the address for the XP and what writes/access that address. When I kill an enemy, I get 550 xp, so I tried to add the xp multiplier above the "7FF60C0B0A79 - 49 01 38 - add [r8],rdi " instruction but when I enable the script and kill an enemy my game crashes. Tried the same script for the other 2 addresses as well but that doesn't work either. Am I injecting into the wrong address? Or is my script wrong?

There seems to be a lot of jmp and lea instructions before "add [r8],rdi" which seems to be some calculation I think. Hope you can help me in some regard, mostly just want to learn.

Also sorry about the length of this post, I don't seem to be able to collapse the code in some way.

Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"SOPFFO.exe"+590A79)
alloc(xpmulti,4,"SOPFFO.exe"+590A79)
label(returnhere)
label(originalcode)
label(exit)
label(xpmulti)
registerSymbol(xpmulti)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here

xpmulti:
dd (float)2

imul rdi,[xpmulti]

originalcode:
add [r8],rdi
mov edx,ebp

exit:
jmp returnhere

"SOPFFO.exe"+590A79:
jmp newmem
returnhere:


 
 
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
dealloc(xpmulti)
unregisterSymbol(xp)
"SOPFFO.exe"+590A79:
add [r8],rdi
mov edx,ebp
//Alt: db 49 01 38 8B D5





Code:
SOPFFO.exe+5CE5C3:
7FF60C0EE5BF - 49 8B C1  - mov rax,r9
7FF60C0EE5C2 - C3 - ret
7FF60C0EE5C3 - 4D 8B 48 08  - mov r9,[r8+08] <<
7FF60C0EE5C7 - 49 8B C1  - mov rax,r9
7FF60C0EE5CA - C3 - ret

RAX=0000000000000023
RBX=00007FF6100DF958
RCX=00007FF60C0EE5C3
RDX=00007FF60BB20000
RSI=00007FF60FB47E00
RDI=0000000000000226
RSP=000000DE14F6ED88
RBP=0000000000000061
RIP=00007FF60C0EE5C7
R8=00007FF6100DF958
R9=00000000000007D0
R10=0000000000000000
R11=00000238A8CE4A50
R12=0000000000000000
R13=8000000000000000
R14=00007FF60FB47E00
R15=0000000000000000


First seen:22:31:45
Last seen:22:31:45


Code:
SOPFFO.exe+590A79:
7FF60C0B0A70 - EB 07 - jmp SOPFFO.exe+590A79
7FF60C0B0A72 - 4C 8D 83 20010000  - lea r8,[rbx+00000120]
7FF60C0B0A79 - 49 01 38  - add [r8],rdi <<
7FF60C0B0A7C - 8B D5  - mov edx,ebp
7FF60C0B0A7E - 48 8B CE  - mov rcx,rsi

RAX=00007FF60BB20000
RBX=00007FF6100DF958
RCX=0000000000000023
RDX=00007FF60C0B0925
RSI=00007FF60FB47E00
RDI=0000000000000226
RSP=000000DE14F6ED90
RBP=0000000000000061
RIP=00007FF60C0B0A7C
R8=00007FF6100DF960
R9=00000238A968C150
R10=0000000000000000
R11=47AE147AE147AE15
R12=0000000000000000
R13=8000000000000000
R14=0000000000000002
R15=0000000000000000


First seen:22:31:45
Last seen:22:31:45


Code:
SOPFFO.exe+5AAAA1:
7FF60C0CAA9A - 8B CB  - mov ecx,ebx
7FF60C0CAA9C - E8 7375AEFF - call SOPFFO.NVSDK_NGX_Parameter_GetI+3142
7FF60C0CAAA1 - 48 39 07  - cmp [rdi],rax <<
7FF60C0CAAA4 - 76 03 - jna SOPFFO.exe+5AAAA9
7FF60C0CAAA6 - 48 89 07  - mov [rdi],rax

RAX=000000000001EC12
RBX=0000000000000061
RCX=00000000000015D6
RDX=00000000000000FA
RSI=00007FF60FB47E00
RDI=00007FF6100DF960
RSP=000000DE14F6ED60
RBP=0000000000000061
RIP=00007FF60C0CAAA4
R8=000000000000001E
R9=000000000000001D
R10=00000238A863E140
R11=000000000000001D
R12=0000000000000000
R13=8000000000000000
R14=0000000000000002
R15=0000000000000000


First seen:22:31:45
Last seen:22:31:45



cheatengine-x86_64-SSE4-AVX2_2022-11-11_22-29-39.png
 Description:
 Filesize:  106.43 KB
 Viewed:  1346 Time(s)

cheatengine-x86_64-SSE4-AVX2_2022-11-11_22-29-39.png


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

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Fri Nov 11, 2022 4:28 pm    Post subject: Reply with quote

Zephyr_92 wrote:
Code:
"SOPFFO.exe"+590A79:
jmp newmem

`"SOPFFO.exe"+590A79` is the injection point. `jmp newmem` overwrites the code that was originally there and jumps to your allocated memory.
Zephyr_92 wrote:
Code:
newmem:

xpmulti:
dd (float)2

imul rdi,[xpmulti]
...
At newmem, there is nothing. Literally nothing. No code, no data, it's just 00 bytes that memory gets initialized with. Jumping to zero-initialized memory will almost certainly crash the game.

All the code you wrote is under the `xpmulti` alloc.

`imul` is for signed integer multiplication and [xpmulti] is a float (not an integer). Use SSE for floating point arithmetic, and convert from/to an int using cvtsi2ss / cvttss2si.

If you don't want to use the AOB injection template, use the full injection template. It will assert the code you're overwriting is what you expect it to be, and it will have a comment at the bottom showing the code around the injection point. Both of these are very important if the game ever updates.

I'd use doubles instead of floats, but that's not too important.
Code:
alloc(xpmulti,8,...)  // changed 4 to 8
...

newmem:
  cvtsi2sd xmm0,rdi
  mulsd xmm0,[xpmulti]
  cvttsd2si rdi,xmm0
originalcode:
  add [r8],rdi
  mov edx,ebp
exit:
  jmp returnhere

xpmulti:
  dq (double)2.0

_________________
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
Zephyr_92
How do I cheat?
Reputation: 0

Joined: 11 Nov 2022
Posts: 3

PostPosted: Fri Nov 11, 2022 6:09 pm    Post subject: Reply with quote

ParkourPenguin wrote:
Zephyr_92 wrote:
Code:
"SOPFFO.exe"+590A79:
jmp newmem

`"SOPFFO.exe"+590A79` is the injection point. `jmp newmem` overwrites the code that was originally there and jumps to your allocated memory.
Zephyr_92 wrote:
Code:
newmem:

xpmulti:
dd (float)2

imul rdi,[xpmulti]
...
At newmem, there is nothing. Literally nothing. No code, no data, it's just 00 bytes that memory gets initialized with. Jumping to zero-initialized memory will almost certainly crash the game.

All the code you wrote is under the `xpmulti` alloc.

`imul` is for signed integer multiplication and [xpmulti] is a float (not an integer). Use SSE for floating point arithmetic, and convert from/to an int using cvtsi2ss / cvttss2si.

If you don't want to use the AOB injection template, use the full injection template. It will assert the code you're overwriting is what you expect it to be, and it will have a comment at the bottom showing the code around the injection point. Both of these are very important if the game ever updates.

I'd use doubles instead of floats, but that's not too important.
Code:
alloc(xpmulti,8,...)  // changed 4 to 8
...

newmem:
  cvtsi2sd xmm0,rdi
  mulsd xmm0,[xpmulti]
  cvttsd2si rdi,xmm0
originalcode:
  add [r8],rdi
  mov edx,ebp
exit:
  jmp returnhere

xpmulti:
  dq (double)2.0


Thanks for the help, ParkourPenguin! I have seen you help others a couple times when I googled stuff about CE!

It seems I have made quite a few rookie mistakes. At first I tried writing the xpmulti: dd (float)2 above newmem: because it wouldn't let me disable the script and left my allocated memory in there until I restarted the game so I figured I would put it below newmem:. Also I first thought I have to use mul/imul because I saw nothing that makes use of float/xmm registers, didn't know you could convert this stuff (only started learning yesterday). Since a lot of the stuff like xp/money etc is in 4bit Integer, was the xmm register not being used, thus being able to make use of these yourself?

Anyway, I tried the stuff you said but I am unable to enable the script. This is what I got:

Have I made mistakes somewhere again? Embarassed

Code:
define(address,"SOPFFO.exe"+590A79)
define(bytes,49 01 38 8B D5)

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat

 
 
assert(address,bytes)
alloc(newmem,$1000,"SOPFFO.exe"+590A79)
alloc(xpmulti,8,"SOPFFO.exe"+590A79)

label(code)
label(return)
label(xpmulti)
registerSymbol(xpmulti)


newmem:
  cvtsi2sd xmm0,rdi
  mulsd xmm0,[xpmulti]
  cvttsd2si rdi,xmm0

code:
  add [r8],rdi
  mov edx,ebp
  jmp return

address:
  jmp newmem

xpmulti:
  dq (double)2.0

return:

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
address:
  db bytes
  // add [r8],rdi
  // mov edx,ebp

dealloc(newmem)
dealloc(xpmulti)
unregisterSymbol(xpmulti)

{
// ORIGINAL CODE - INJECTION POINT: SOPFFO.exe+590A79

SOPFFO.exe+590A4C: EB 2B                 - jmp SOPFFO.exe+590A79
SOPFFO.exe+590A4E: 4C 8D 83 00 01 00 00  - lea r8,[rbx+00000100]
SOPFFO.exe+590A55: EB 22                 - jmp SOPFFO.exe+590A79
SOPFFO.exe+590A57: 4C 8D 83 08 01 00 00  - lea r8,[rbx+00000108]
SOPFFO.exe+590A5E: EB 19                 - jmp SOPFFO.exe+590A79
SOPFFO.exe+590A60: 4C 8D 83 10 01 00 00  - lea r8,[rbx+00000110]
SOPFFO.exe+590A67: EB 10                 - jmp SOPFFO.exe+590A79
SOPFFO.exe+590A69: 4C 8D 83 18 01 00 00  - lea r8,[rbx+00000118]
SOPFFO.exe+590A70: EB 07                 - jmp SOPFFO.exe+590A79
SOPFFO.exe+590A72: 4C 8D 83 20 01 00 00  - lea r8,[rbx+00000120]
// ---------- INJECTING HERE ----------
SOPFFO.exe+590A79: 49 01 38              - add [r8],rdi
// ---------- DONE INJECTING  ----------
SOPFFO.exe+590A7C: 8B D5                 - mov edx,ebp
SOPFFO.exe+590A7E: 48 8B CE              - mov rcx,rsi
SOPFFO.exe+590A81: E8 D3 B5 AC FF        - call SOPFFO.NVSDK_NGX_Parameter_GetUI+1F22
SOPFFO.exe+590A86: 4D 8D 04 37           - lea r8,[r15+rsi]
SOPFFO.exe+590A8A: 41 83 FC 08           - cmp r12d,08
SOPFFO.exe+590A8E: 72 03                 - jb SOPFFO.exe+590A93
SOPFFO.exe+590A90: 4C 8B C6              - mov r8,rsi
SOPFFO.exe+590A93: 49 81 C0 58 7B 59 00  - add r8,00597B58
SOPFFO.exe+590A9A: 8B D5                 - mov edx,ebp
SOPFFO.exe+590A9C: 48 8B CE              - mov rcx,rsi
}
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Fri Nov 11, 2022 7:07 pm    Post subject: Reply with quote

Zephyr_92 wrote:
Code:
label(return)
...
address:
  jmp newmem

xpmulti:
  dq (double)2.0

return:
You put the return label after the xpmulti alloc. Technically, the script should've enabled anyway, but it would also crash for the same reason as the code in your first post: executing zero-initialized memory.

Put `return:` after `jmp newmem`- that's where your code injection is suppose to return to.

Zephyr_92 wrote:
Code:
alloc(xpmulti,...)
...
label(xpmulti)
The label is unnecessary. I think this is the reason the script is complaining: `xpmulti` is defined to be both its own alloc and a label under the address "SOPFFO.exe"+590A79. CE could've been more clear about that...

If CE still doesn't like the script, assign it to the cheat table (by force if needed) and try to enable it. Right click on the script and the reason why it failed should be at the top of the right click menu.

_________________
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
Zephyr_92
How do I cheat?
Reputation: 0

Joined: 11 Nov 2022
Posts: 3

PostPosted: Sat Nov 12, 2022 12:38 pm    Post subject: Reply with quote

ParkourPenguin wrote:
Zephyr_92 wrote:
Code:
label(return)
...
address:
  jmp newmem

xpmulti:
  dq (double)2.0

return:
You put the return label after the xpmulti alloc. Technically, the script should've enabled anyway, but it would also crash for the same reason as the code in your first post: executing zero-initialized memory.

Put `return:` after `jmp newmem`- that's where your code injection is suppose to return to.

Zephyr_92 wrote:
Code:
alloc(xpmulti,...)
...
label(xpmulti)
The label is unnecessary. I think this is the reason the script is complaining: `xpmulti` is defined to be both its own alloc and a label under the address "SOPFFO.exe"+590A79. CE could've been more clear about that...

If CE still doesn't like the script, assign it to the cheat table (by force if needed) and try to enable it. Right click on the script and the reason why it failed should be at the top of the right click menu.


Thank you, it worked. It indeed was the label that made it unable to enable the script.

So, I tried to do a xp multiplier script for Elden Ring as well but am facing some issues there as well.

I found the Rune(xp) address, found out what accesses that address but all that appears are mov instructions that are updated(?) constantly.


Code:
7FF66813BCC0 - 44 8B 49 6C  - mov r9d,[rcx+6C]
7FF66813BCFA - 89 41 6C  - mov [rcx+6C],eax
7FF66813BD4E - 8B 41 6C  - mov eax,[rcx+6C]
7FF66896C3F5 - 8B 7B 6C  - mov edi,[rbx+6C]
7FF66863314E - 8B 47 6C  - mov eax,[rdi+6C]
7FF668689DBD - 41 8B 46 6C  - mov eax,[r14+6C]


[rcx+6c] is the Rune address and I thought eax is the register for the Rune(xp) that gets added/moved to my Rune address but if I multiply eax then I get a super high Rune number, very likely due to the instructions constantly moving stuff.

Here is a script from another user (not sure if I am allowed to credit them on here) that does what I want but I have no clue how that person wrote it.

Code:
[ENABLE]

aobscanmodule(rune_multiplier,eldenring.exe,f3 0f 59 c1 f3 0f 2c f8 48 8b 8b) // should be unique
alloc(newmem,$1000,rune_multiplier)

label(code)
label(return)
label(rn_mult)
registersymbol(rn_mult)

newmem:
  movss xmm0, [rn_mult]
code:
  mulss xmm0,xmm1
  cvttss2si edi,xmm0
  jmp return

rn_mult:
 dd (float)2

rune_multiplier:
  jmp newmem
  nop 3
return:
registersymbol(rune_multiplier)

[DISABLE]

rune_multiplier:
  db F3 0F 59 C1 F3 0F 2C F8

unregistersymbol(*)
dealloc(*)

{
// ORIGINAL CODE - INJECTION POINT: eldenring.exe+630CB3

eldenring.exe+630C90: 74 37                 - je eldenring.exe+630CC9
eldenring.exe+630C92: E8 29 B8 DB FF        - call eldenring.exe+3EC4C0
eldenring.exe+630C97: 84 C0                 - test al,al
eldenring.exe+630C99: 74 2E                 - je eldenring.exe+630CC9
eldenring.exe+630C9B: 40 84 F6              - test sil,sil
eldenring.exe+630C9E: 74 1B                 - je eldenring.exe+630CBB
eldenring.exe+630CA0: 48 8B 8B 78 01 00 00  - mov rcx,[rbx+00000178]
eldenring.exe+630CA7: E8 64 83 EB FF        - call eldenring.exe+4E9010
eldenring.exe+630CAC: 66 0F 6E CF           - movd xmm1,edi
eldenring.exe+630CB0: 0F 5B C9              - cvtdq2ps xmm1,xmm1
// ---------- INJECTING HERE ----------
eldenring.exe+630CB3: F3 0F 59 C1           - mulss xmm0,xmm1
// ---------- DONE INJECTING  ----------
eldenring.exe+630CB7: F3 0F 2C F8           - cvttss2si edi,xmm0
eldenring.exe+630CBB: 48 8B 8B 70 05 00 00  - mov rcx,[rbx+00000570]
eldenring.exe+630CC2: 8B D7                 - mov edx,edi
eldenring.exe+630CC4: E8 37 77 C2 FF        - call AddSoul_Call
eldenring.exe+630CC9: 48 8B 5C 24 30        - mov rbx,[rsp+30]
eldenring.exe+630CCE: 48 8B 74 24 38        - mov rsi,[rsp+38]
eldenring.exe+630CD3: 48 83 C4 20           - add rsp,20
eldenring.exe+630CD7: 5F                    - pop rdi
eldenring.exe+630CD8: C3                    - ret
eldenring.exe+630CD9: CC                    - int 3
}


How can I find out myself that edi or xmm0/1 has something to do with Runes when it didn't show up in "find out what accesses/writes to this address"? Are there other methods to find this stuff?
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 Nov 12, 2022 2:02 pm    Post subject: Reply with quote

Code:
mov [rcx+6C],eax
This is the only one that writes to the address.
`mov` simply moves values around. It doesn't add or subtract anything. Given that, `eax` must be the new value of runes. If you multiply this by some amount, you'd be multiplying your total runes and not the change in runes. e.g. if the old runes (`[rcx+6C]`) is 100 and new runes (`eax`) is 104, multiplying new runes by 2 would give you 208 runes, not 108.

As for that other script, they probably figured out where it got the new amount to add. In the comment, the instruction `call AddSoul_Call` says a lot: rcx and edx are clearly parameters (see windows x64 calling convention), so perhaps the write to the runes address occurs in that function call.

If you didn't already have that information, I'd start by scrolling up from the write. Look at what happens between `7FF66813BCC0 - mov r9d,[rcx+6C]` (read from the runes) and `7FF66813BCFA - mov [rcx+6C],eax` (write to the runes). Track down where it calculates some amount to add and figure out where it comes from. This might involve some parameter to the function, in which case you can use a breakpoint, step out to the caller, and analyze from there. Break-and-trace might help too (step over w/ lower trace count)- just make sure either that instruction only accesses the address you want or you set a start condition.

Identifying function parameters starts getting into the very basics of reverse engineering, and it might be quite difficult for beginners.

_________________
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
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