 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
anom7 How do I cheat?
Reputation: 0
Joined: 02 Jul 2024 Posts: 5
|
Posted: Thu Jul 24, 2025 4:12 am Post subject: How to show the value of hover/selected item on inventory? |
|
|
Hello, I'm testing with a rpg game were I have different items in the inventory. I can find any address (and value) of any item but I can't see how to add this on a cheat engine entry (a script one?) in order to see the selected value.
Correct me if this is wrong, but I found the addresses of the items following this steps:
1 Find any item address
2 Find wich code access to that address when I hover/select that item
3 In that code, click on "Find out what addresses this instruction accesses" and a popup will show me each address and value (item quantity) each time I hover/select any item
So, al works perfect, but I saw in other Cheat Engine Tables that there is a way to automatically show that address (and value) in a script entry.
I could not find any tutorial showing how to do it, I don't know if I'm searching with the correct words with "hover/selection".
How can I create a entry that automatically shows the address and value of the selected item that shows the pop up of "Find out what addresses this instruction accesses" function?
Thanks!
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4691
|
Posted: Thu Jul 24, 2025 11:55 am Post subject: |
|
|
Search "injection copy"
The code injection should copy the address of the value being accessed to some memory CE knows about (e.g. registersymbol or globalalloc).
Post the instruction accessing the addresses if you want more help.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
anom7 How do I cheat?
Reputation: 0
Joined: 02 Jul 2024 Posts: 5
|
Posted: Thu Jul 24, 2025 3:49 pm Post subject: |
|
|
Thanks, that was useful!
I knew "injection copy", I did it sometimes, but I did not know that I could create a variable and assign an address like [rax] to my new variable. So, that new variable is the one I can use as a pointer and see the quantity of the selected item.
I've seen a few videos, but this is the one I saw doing exactly this, and I found it useful: youtu.be/GeDv8_474HI?t=411
Now I can see that when the script is active the new pointer shows the address and value of the current selected item. Also, I can change the value of that address/item and change the item quantity with no problem
BUT I don't know why, If I active the script and enter to the inventory screen, the game crashes. I need to activate the script being on the inventory and then works ok. Even I can go back to the menu or the game. But I can't enter inventory with script activated.
It's not a big deal because the cheat is working, but I can't leave it on all the time (a hotkey should do the work for a easy use).
Even so, I really don't understand why is crashing:
- The aobscanmodule address to search is unique.
- Even if I create a "Template/AOB Injection" with NO modification, the game still crashes even no changes are done on the code. Well, there is a jump to the new code that it's identical, you know what I mean.
- I have also tried with "Template/Cheat Table Framework Code" + "Template/Code Injection" also with NO modification with same results.
About the code, just a simple example to see what is changing:
AOB Injection (scanning 44 8B 40 04 48 89 F1 89 DA wich is unique)
Script code disabled/original code (does not crash):
Code: | mov r8d,[rax+04]
mov rcx,rsi
mov edx,ebx
call 7FF6A6AD4B30 (code continues)
|
Script code enabled (it crashes when entering inventory):
Code: | jmp 7FF6A39F0000 (newmem automatically created, that is empty)
mov r8d,[rax+04]
mov rcx,rsi
jmp 7FF6A6D66013 (jump on next line)
mov edx,ebx
call 7FF6A6AD4B30 (code continues as before) |
I tried to debug but it crashes even before starting to execute the first line of changed code: "mov r8d,[rax+04]". So, I don't understand what's is going on. Some allocated/unallocated variable that default templates creates and I need to do something with them?
If anyone knows how to fix it, I'd appreciate it.
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4691
|
Posted: Fri Jul 25, 2025 1:16 am Post subject: |
|
|
Post the full script.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
anom7 How do I cheat?
Reputation: 0
Joined: 02 Jul 2024 Posts: 5
|
Posted: Fri Jul 25, 2025 2:39 am Post subject: |
|
|
Yes, this is the full script, I've just recreated from "Template/AOB Injection" just to be sure no modification has been done from my side:
Code: | { Game : granblue_fantasy_relink.exe
Version:
Date : 2025-07-25
Author : anom7
This script does blah blah blah
}
[ENABLE]
aobscanmodule(INJECT,granblue_fantasy_relink.exe,44 8B 40 04 48 89 F1 89 DA) // should be unique
alloc(newmem,$1000,INJECT)
label(code)
label(return)
newmem:
code:
mov r8d,[rax+04]
mov rcx,rsi
jmp return
INJECT:
jmp newmem
nop 2
return:
registersymbol(INJECT)
[DISABLE]
INJECT:
db 44 8B 40 04 48 89 F1
unregistersymbol(INJECT)
dealloc(newmem)
{
// ORIGINAL CODE - INJECTION POINT: granblue_fantasy_relink.exe+335600C
granblue_fantasy_relink.exe+3355FF0: 48 39 D1 - cmp rcx,rdx
granblue_fantasy_relink.exe+3355FF3: 74 1B - je granblue_fantasy_relink.exe+3356010
granblue_fantasy_relink.exe+3355FF5: 48 8B 49 08 - mov rcx,[rcx+08]
granblue_fantasy_relink.exe+3355FF9: 39 59 10 - cmp [rcx+10],ebx
granblue_fantasy_relink.exe+3355FFC: 75 F2 - jne granblue_fantasy_relink.exe+3355FF0
granblue_fantasy_relink.exe+3355FFE: 4C 39 C9 - cmp rcx,r9
granblue_fantasy_relink.exe+3356001: 74 0D - je granblue_fantasy_relink.exe+3356010
granblue_fantasy_relink.exe+3356003: 48 8B 41 18 - mov rax,[rcx+18]
granblue_fantasy_relink.exe+3356007: 48 85 C0 - test rax,rax
granblue_fantasy_relink.exe+335600A: 74 04 - je granblue_fantasy_relink.exe+3356010
// ---------- INJECTING HERE ----------
granblue_fantasy_relink.exe+335600C: 44 8B 40 04 - mov r8d,[rax+04]
// ---------- DONE INJECTING ----------
granblue_fantasy_relink.exe+3356010: 48 89 F1 - mov rcx,rsi
granblue_fantasy_relink.exe+3356013: 89 DA - mov edx,ebx
granblue_fantasy_relink.exe+3356015: E8 16 EB D6 FF - call granblue_fantasy_relink.exe+30C4B30
granblue_fantasy_relink.exe+335601A: 49 8B 95 C0 01 00 00 - mov rdx,[r13+000001C0]
granblue_fantasy_relink.exe+3356021: 49 39 95 C8 01 00 00 - cmp [r13+000001C8],rdx
granblue_fantasy_relink.exe+3356028: 0F 84 B4 00 00 00 - je granblue_fantasy_relink.exe+33560E2
granblue_fantasy_relink.exe+335602E: B8 08 00 00 00 - mov eax,00000008
granblue_fantasy_relink.exe+3356033: 31 C9 - xor ecx,ecx
granblue_fantasy_relink.exe+3356035: EB 31 - jmp granblue_fantasy_relink.exe+3356068
granblue_fantasy_relink.exe+3356037: 66 0F 1F 84 00 00 00 00 00 - nop word ptr [rax+rax+00000000]
}
|
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4691
|
Posted: Fri Jul 25, 2025 12:30 pm Post subject: |
|
|
The conditional jump instructions above the injection point, `je granblue_fantasy_relink.exe+3356010`, are causing the crash.
The jump to your code (newmem) takes up 5 bytes, but `mov r8d,[rax+04]` only consists of 4 bytes. CE has to pull in the next instruction to have at least 5 bytes. After the jump is assembled, the byte at `granblue_fantasy_relink.exe+3356010` is now in the middle of a `jmp` instruction, and trying to execute code at that address would be nonsense.
Try injecting at `granblue_fantasy_relink.exe+335600A`, and put the code that copies the address after the `je`. I think nothing should jump to `granblue_fantasy_relink.exe+335600C` directly. I'd also change the original `je` instruction to jump to the `jmp return` instruction in the code injection, but it's probably fine.
Also, change INJECT to something else. Registered symbols need to be unique across scripts unless you have a good reason to share them.
Then you can start adding code from that video. Pointers in 64-bit applications are 8 bytes (64 bits), so you need to alloc 8 bytes for the stored address.
In 64-bit code, most instructions can't directly access an address that's far away, so in general, you'd have to refer to that allocated memory indirectly through a register.
Code: | [ENABLE]
...
label(exit)
globalalloc(currentInventoryItem,8)
newmem:
je exit
push rcx
mov rcx,currentInventoryItem
mov [rcx],rax
pop rcx
mov r8d,[rax+04]
exit:
jmp return
... |
Add a new memory record to the address list, check the "Pointer" checkbox, base address is currentInventoryItem, only offset is 4
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
anom7 How do I cheat?
Reputation: 0
Joined: 02 Jul 2024 Posts: 5
|
Posted: Fri Jul 25, 2025 5:04 pm Post subject: |
|
|
ParkourPenguin wrote: | The conditional jump instructions above the injection point, `je granblue_fantasy_relink.exe+3356010`, are causing the crash.
The jump to your code (newmem) takes up 5 bytes, but `mov r8d,[rax+04]` only consists of 4 bytes. CE has to pull in the next instruction to have at least 5 bytes. After the jump is assembled, the byte at `granblue_fantasy_relink.exe+3356010` is now in the middle of a `jmp` instruction, and trying to execute code at that address would be nonsense.
Try injecting at `granblue_fantasy_relink.exe+335600A`, and put the code that copies the address after the `je`. I think nothing should jump to `granblue_fantasy_relink.exe+335600C` directly. |
That was the problem, thank you very much!
I did not know that this difference of bytes between old and new code could cause that problem. Now, with your solution the change is from 6 original bytes (2 for JE + 4 for MOV) to 6 bytes (4 for JMP to injection code + 2 for NOP). I see that CE automatically add a NOP to avoid that problem of different sizes of bytes that can cause the problem I had (I suppose).
So, important note for me: check that the injection line has at least the same number of bytes as the jump sentence to the injection code. Right?
Before: from 4 bytes to 5 bytes --> Error
Now: from 6 bytes to 6 bytes --> OK
That is the fixed code with the new 4 bytes var (I will talk later regarding 4 vs 8 bytes):
Code: | [ENABLE]
aobscanmodule(MY_INJECT_ON_JE,granblue_fantasy_relink.exe,74 04 44 8B 40 04 48 89 F1 89 DA) // should be unique
alloc(newmem,$1000,MY_INJECT_ON_JE)
label(code)
label(return)
globalalloc(ITEM_Q,4)
newmem:
code:
je granblue_fantasy_relink.exe+3356010
mov [ITEM_Q],rax
mov r8d,[rax+04]
jmp return
MY_INJECT_ON_JE:
jmp newmem
nop
return:
registersymbol(MY_INJECT_ON_JE)
|
ParkourPenguin wrote: | I'd also change the original `je` instruction to jump to the `jmp return` instruction in the code injection, but it's probably fine.
Also, change INJECT to something else. Registered symbols need to be unique across scripts unless you have a good reason to share them.
|
Yeah, it's fine because I did not need the new code with the `jmp return` you said. But I need more time to process that code that you write, I need to do more testing in order to learn how it really work the recommended script that you write because I did not use the push and pop and I'm not sure why use (although I used you code, works ok and you are the expert ).
I need to learn more and see other examples in scripting in CE to see how and when use some commands.
ParkourPenguin wrote: | Then you can start adding code from that video. Pointers in 64-bit applications are 8 bytes (64 bits), so you need to alloc 8 bytes for the stored address.
In 64-bit code, most instructions can't directly access an address that's far away, so in general, you'd have to refer to that allocated memory indirectly through a register. |
This is the only thing about your code that is not working to me.
The destination address that I'm working with (the item address that look the game's code, [rax]), it a 4 byte address. If I create a 4 - byte pointer I see the number of items correctly, but if I create a 8 bytes pointer it shows a larger and incorrect number (it's reading more bytes that the ones required to read, right?). In both cases the offset is 4.
As a demostration, you can see some of the code where you can see the allocation is 8 bytes and the pointer is also 8 bytes (the current item quantity in game is 999):
i.ibb.co/d0myBcSF/2025-07-26-00-47-24-Auto-Assemble-edit-script-MY-INJECT-ON-JE-NEWVAR-8-bytes.png
I'm not sure if this is the type of pointer you were referring to. Perhaps I said something wrong when I mentioned pointers in my previous messages.
|
|
Back to top |
|
 |
Labyrnth Moderator
Reputation: 10
Joined: 28 Nov 2006 Posts: 6301
|
Posted: Sat Jul 26, 2025 12:14 pm Post subject: |
|
|
Maybe?
[ENABLE]
aobscanmodule(INJECT,granblue_fantasy_relink.exe,44 8B 40 04 48 89 F1 89 DA) // should be unique
alloc(newmem,$1000,INJECT)
label(code)
label(return)
newmem:
; replicate original instructions
mov r8d,[rax+04]
mov rcx,rsi
mov edx,ebx
; then jump back
jmp return
INJECT:
jmp newmem
nop 2
return:
registersymbol(INJECT)
[DISABLE]
INJECT:
db 44 8B 40 04 48 89 F1 89 DA
unregistersymbol(INJECT)
dealloc(newmem)
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4691
|
Posted: Sat Jul 26, 2025 1:26 pm Post subject: |
|
|
The value's type is a 4-byte value. The address of the value (i.e. the thing you want to store) is 8 bytes.
In the memory record you add, the type can be whatever you want- 4-byte is fine. I'm saying that the alloc should have 8 bytes to store the address properly.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
anom7 How do I cheat?
Reputation: 0
Joined: 02 Jul 2024 Posts: 5
|
Posted: Sat Jul 26, 2025 5:08 pm Post subject: |
|
|
@Labyrnth that code has the same problem as my initial code. ParkourPenguin explained it and proposed a fix: forum.cheatengine.org/viewtopic.php?p=5793659&sid=7822864e3d91b7878fff363d1b65b5fc#5793659
In my next post I wrote the fixed code that worked to me (well, the globalalloc must be 8 bytes instead of 4 as ParkourPenguin explained): forum.cheatengine.org/viewtopic.php?p=5793664&sid=7822864e3d91b7878fff363d1b65b5fc#5793664
Thanks for the help anyway!
ParkourPenguin wrote: | The value's type is a 4-byte value. The address of the value (i.e. the thing you want to store) is 8 bytes.
In the memory record you add, the type can be whatever you want- 4-byte is fine. I'm saying that the alloc should have 8 bytes to store the address properly. |
Oh, ok, now I understand it.
Now it's clear to me, thanks for clarifying!
|
|
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
|
|