 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Sun Feb 06, 2022 4:59 am Post subject: Using ReadMem Properly |
|
|
I am trying to make a script more compatible. I think readmem is what I am supposed to be using, but I am not sure because I have never used it. Looking at examples for readmem, I can only seem to understand parts of its usage:
This is the original script:
Code: | aobscanmodule(aob_ped_density,sdhdship.exe,F3??????????????F3??????????????F3??????????????0F54??????????0F2F??????????76)
alloc(newmem_ped_density,1024,sdhdship.exe)
label(return_ped_density)
label(originalcode_ped_density)
label(ped_density_address)
registersymbol(aob_ped_density)
registersymbol(ped_density_address)
newmem_ped_density:
push rdi
lea rdi,[sdhdship.exe+207B21C]
mov [ped_density_address],rdi
pop rdi
originalcode_ped_density:
movss xmm0,[sdhdship.exe+207B21C]
jmp return_ped_density
ped_density_address:
dq 0
aob_ped_density:
jmp newmem_ped_density
nop 3
return_ped_density:
[DISABLE]
dealloc(newmem_ped_density)
aob_ped_density:
db F3 0F 10 05 F8 2B C6 01
unregistersymbol(aob_ped_density)
unregistersymbol(ped_density_address) |
This is my attempt at incorporating newmem:
Code: | aobscanmodule(aob_ped_density,sdhdship.exe,F3??????????????F3??????????????F3??????????????0F54??????????0F2F??????????76)
alloc(newmem_ped_density,1024,sdhdship.exe)
alloc(pdbytes,8)
label(return_ped_density)
label(originalcode_ped_density)
label(ped_density_address)
label(pdbytes)
registersymbol(aob_ped_density)
registersymbol(ped_density_address)
newmem_ped_density:
push rdi
lea rdi,[pdbytes+4] //lea rdi,[sdhdship.exe+207B21C]
mov [ped_density_address],rdi
pop rdi
originalcode_ped_density:
movss xmm0,[pdbytes+4] //movss xmm0,[sdhdship.exe+207B21C]
jmp return_ped_density
ped_density_address:
dq 0
pdbytes:
readmem(aob_ped_density,8)
aob_ped_density:
jmp newmem_ped_density
nop 3
return_ped_density:
[DISABLE]
dealloc(newmem_ped_density)
aob_ped_density:
readmem(aob_ped_density,8) //db F3 0F 10 05 F8 2B C6 01
unregistersymbol(aob_ped_density)
unregistersymbol(ped_density_address) |
Am I even close?
Thanks.
|
|
Back to top |
|
 |
TheyCallMeTim13 Wiki Contributor
Reputation: 51
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Sun Feb 06, 2022 5:59 am Post subject: |
|
|
You want to read the stored bytes when disabling, so you'll need to register the symbol. And I'd deallocate after reading the memory, but I think CE actually handles deallocation the way it needs to be so either one might work.
Code: |
label(pdbytes)
registersymbol(pdbytes)
//...
pdbytes:
readmem(aob_ped_density,8)
//...
[DISABLE]
aob_ped_density:
readmem(pdbytes,8)
dealloc(newmem_ped_density)
//... |
_________________
|
|
Back to top |
|
 |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Sun Feb 06, 2022 6:49 am Post subject: |
|
|
Thank you. I appreciate your help with this.
I have made some changes. Now, the script will activate and will deactivate correctly, with original bytes unaltered upon disable. Which is good. Unfortunately, the correct address is not being stored, and the originalcode is not correct:
Code: | aobscanmodule(aob_ped_density,sdhdship.exe,F3??????????????F3??????????????F3??????????????0F54??????????0F2F??????????76)
alloc(newmem_ped_density,1024,sdhdship.exe)
//alloc(pdbytes,8)
label(return_ped_density)
label(originalcode_ped_density)
label(ped_density_address)
label(pdbytes)
registersymbol(aob_ped_density)
registersymbol(ped_density_address)
registersymbol(pdbytes)
newmem_ped_density:
push rdi
lea rdi,[pdbytes+4] //correct address of [sdhdship.exe+207B21C] is not getting stored
mov [ped_density_address],rdi
pop rdi
originalcode_ped_density:
movss xmm0,[pdbytes+4] //Same as above
jmp return_ped_density
ped_density_address:
dq 0
pdbytes:
readmem(aob_ped_density,8)
aob_ped_density:
jmp newmem_ped_density
nop 3
return_ped_density:
[DISABLE]
aob_ped_density:
readmem(pdbytes,8) //db F3 0F 10 05 F8 2B C6 01
//dealloc(pdbytes)
dealloc(newmem_ped_density)
unregistersymbol(aob_ped_density)
unregistersymbol(ped_density_address)
unregistersymbol(pdbytes) |
Is what I am trying to do even possible? Thanks, again.
|
|
Back to top |
|
 |
TheyCallMeTim13 Wiki Contributor
Reputation: 51
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Sun Feb 06, 2022 7:08 am Post subject: |
|
|
That's because of how x64 bit processes work, the address is actually the 4 bytes as a signed integer + the instruction address at the end of the 4 bytes.
I actually use this Lua function to get an address stored in opcode.
Code: |
----
---- Calculates the address stored in opcode if 64 bit, or reads the address if 32 bit.
----
---- getOpcodeAddress(address)
----
---- Parameters:
---- address : number - string :
---- The address of the opcode the stored address is.
---- Return:
---- number :
---- The address stored at the given opcode address.
function getOpcodeAddress(address)
address = getAddress(address)
if targetIs64Bit() then
local os = readInteger(address, true) or 0
return address + 4 + os
else
return readInteger(address)
end
end
registerLuaFunctionHighlight('getOpcodeAddress') |
Basically it reads the 4 bytes as a signed integer, then adds the value of the 4 bytes + the address passed (were the 4 bytes are) + 4 (to get to the end of where the bytes are stored.
EDIT: to make this work you have to do the AOB scan in lua. Or enable the AA script to get the AOB address and register it's symbol, then enable the Lua script calling this function.
As for the original code that gets executed in the AA script you can use reassemble.
https://wiki.cheatengine.org/index.php?title=Auto_Assembler:reassemble
_________________
|
|
Back to top |
|
 |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Sun Feb 06, 2022 7:28 am Post subject: |
|
|
TheyCallMeTim13, thank you for your help with this. A lot of this is over my head, I'm afraid. I unfortunately do not know lua. I wonder if there is a way to do this all in assembly? I could try using lua, but I would need help with implementation, such as an example to study that is similar.
Regarding reassemble, I wonder how this works if/when the address offset changes to something unknown? Maybe I do not fully understand its usage.
I appreciate your help with this. Maybe I will need to just settle with what I have.
Thanks.
|
|
Back to top |
|
 |
panraven Grandmaster Cheater
Reputation: 62
Joined: 01 Oct 2008 Posts: 958
|
Posted: Sun Feb 06, 2022 8:29 am Post subject: |
|
|
Just a note, the second parameter (num of bytes to read from and write to) is in decimal (no prefix # need), so if more than 9 bytes, remember it is in decimal.
_________________
- Retarded. |
|
Back to top |
|
 |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Sun Feb 06, 2022 8:37 am Post subject: |
|
|
You mean, in the case of readmem(pdbytes,8), the 8 is in decimal format? Or something else?
|
|
Back to top |
|
 |
TheyCallMeTim13 Wiki Contributor
Reputation: 51
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Sun Feb 06, 2022 9:18 am Post subject: |
|
|
You could look for another spot where that static address gets accessed and moved to a registry. Say something like "mov rax,[game.exe+DEADBEEF]". Then you could use reassemble to add that to your script, it would require a second aob scan. But you could then make a script like this.
Code: | aobscanmodule(aob_ped_density,sdhdship.exe,F3??????????????F3??????????????F3??????????????0F54??????????0F2F??????????76)
aobscanmodule(aob_ped_density_2,sdhdship.exe,...)
alloc(newmem_ped_density,1024,sdhdship.exe)
//alloc(pdbytes,8)
label(return_ped_density)
label(originalcode_ped_density)
label(ped_density_address)
label(pdbytes)
registersymbol(aob_ped_density)
registersymbol(ped_density_address)
registersymbol(pdbytes)
newmem_ped_density:
push rax
reassemble(aob_ped_density_2)
mov [ped_density_address],rax
pop rax
originalcode_ped_density:
reassemble(aob_ped_density)
jmp return_ped_density
ped_density_address:
dq 0
pdbytes:
readmem(aob_ped_density,8)
aob_ped_density:
jmp newmem_ped_density
nop 3
return_ped_density:
[DISABLE]
aob_ped_density:
readmem(pdbytes,8) //db F3 0F 10 05 F8 2B C6 01
//dealloc(pdbytes)
dealloc(newmem_ped_density)
unregistersymbol(aob_ped_density)
unregistersymbol(ped_density_address)
unregistersymbol(pdbytes) |
_________________
|
|
Back to top |
|
 |
panraven Grandmaster Cheater
Reputation: 62
Joined: 01 Oct 2008 Posts: 958
|
Posted: Sun Feb 06, 2022 9:54 am Post subject: |
|
|
++METHOS wrote: | You mean, in the case of readmem(pdbytes, , the 8 is in decimal format? Or something else? |
Yes, it is in decimal format, matter only when it is more than 9.
btw, my try on the script, assume the instruction at aob_ped_density is rip-address as movss xmm0,[-some-rip-address-], not test and may be some typo
Code: |
aobscanmodule(aob_ped_density,sdhdship.exe,F3??????????????F3??????????????F3??????????????0F54??????????0F2F??????????76)
alloc(newmem_ped_density,1024,sdhdship.exe)
alloc(pdbytes,8)
label(return_ped_density)
label(originalcode_ped_density)
label(ped_density_address)
label(pdbytes)
registersymbol(aob_ped_density)
registersymbol(ped_density_address)
newmem_ped_density:
push rdi
push rsi
mov rdi,aob_ped_density+8 /// where the 4-bytes rip END
mov rsi,pdbytes+4 /// where the 4-bytes rip START at the COPY of aob_ped_density == pdbytes
movsxd rsi,[rsi]/// rsi get the signed relative offset at rdi-4 of the original instruction, ADDED, same as movsxd rsi,dword ptr[rsi]
add rdi,rsi /// now rdi is the absolute of the rip-address
mov rsi,ped_density_address /// use this format in case, it is outside 2g range
mov [rsi],rdi /// ped_density_address now has its content store above absolute address
pop rsi
pop rdi
originalcode_ped_density:
{
movss xmm0,[pdbytes+4] //movss xmm0,[sdhdship.exe+207B21C]
}
//// -- original code option 1
reassemble(aob_ped_density) /// use reassemble, may fail if there is an rip address outside 2g range of the cave
//// -- original code option 2, manually construct the address and the instruction, use above assume the instruct as movss xmm0,[-some-rip-address-] safe outside 2g range
push rdi
mov rdi,ped_density_address
mov rdi,[rdi] /// get the absolute address
movss xmm0,[rdi]
pop rdi
jmp return_ped_density
ped_density_address:
dq 0
pdbytes:
readmem(aob_ped_density,8)
aob_ped_density:
jmp newmem_ped_density
nop 3
return_ped_density:
[DISABLE]
dealloc(newmem_ped_density)
aob_ped_density:
readmem(aob_ped_density,8) //db F3 0F 10 05 F8 2B C6 01
unregistersymbol(aob_ped_density)
unregistersymbol(ped_density_address)
|
Another note, recent ce's alloc may fail if third parameter (address hint) is provided and if ce cannot alloc a memory near the address hint.
Older behavior is the alloc wont fail just ignore the address hint.
What it means is that, any alloc in recent CE may fail with an address hint. (More likely for mono game, it seems as the game scale larger<ie. use more memory etc>, more likely happend)
For most realizable code, don't use address hint and use 14-byes jump in 64-bit game.
_________________
- Retarded.
Last edited by panraven on Sun Feb 06, 2022 10:04 am; edited 1 time in total |
|
Back to top |
|
 |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Sun Feb 06, 2022 9:55 am Post subject: |
|
|
@TheyCallMeTim13 - Thank you for replying, I really appreciate it.
This brings up a few more questions. Please bear with me.
When using:
Code: |
newmem_ped_density:
push rax
reassemble(aob_ped_density_2)
mov [ped_density_address],rax
pop rax
|
You are not defining which bytes of aob_ped_density_2 are reassembled, is that right?
You are also not moving anything into rax, is that right?
I am curious how CE knows which bytes to move, and how those bytes are getting pushed into rax. Is it such that reassemble only applies to addresses and not the entire instruction? That does not seem likely given that you are using it in lieu of the originalcode_ped_density bytes.
I also do not understand that, if CE can do this:
Code: |
originalcode_ped_density:
reassemble(aob_ped_density)
jmp return_ped_density
|
...and interpret the addressing correctly, then how are we not able to extract a portion of that data for use when loading the static address into rax?
Regarding the other point of a secondary instance of the static address being used throughout the function, this seems like a reasonable concession, but may not be suitable for all cases, so it would be better to have a universal solution.
Also, if the static address was moved into a registry somewhere else, would we still need to use reassemble? Could we just inject after the instruction and pull that data from the registry as-is? Even so, it seems like a solution that would not always be viable.
Thanks.
EDIT: @panraven, your post was not yet visible. I will read it now. Thanks.
EDIT2: @panraven, I think you are very close. I was not able to activate your script as-is. CE will not let me alloc(pdbytes,8) for some reason. However, if I comment out the allocation, and instead use registersymbol, I am able to activate the script and it /appears/ to be working. I will need to examine more closely to be sure. However, upon disabling the script, the target crashes. I am not sure why.
As a side note, your solution makes my brain hurt. I understand parts, but not all of it. I will need to study it more to try to understand.
Code: |
[ENABLE]
aobscanmodule(aob_ped_density,sdhdship.exe,F3??????????????F3??????????????F3??????????????0F54??????????0F2F??????????76)
alloc(newmem_ped_density,1024,sdhdship.exe)
//alloc(pdbytes,8)
label(return_ped_density)
label(originalcode_ped_density)
label(ped_density_address)
label(pdbytes)
registersymbol(aob_ped_density)
registersymbol(ped_density_address)
registersymbol(pdbytes)
newmem_ped_density:
push rdi
push rsi
mov rdi,aob_ped_density+8 /// where the 4-bytes rip END
mov rsi,pdbytes+4 /// where the 4-bytes rip START at the COPY of aob_ped_density == pdbytes
movsxd rsi,[rsi]/// rsi get the signed relative offset at rdi-4 of the original instruction
add rdi,rsi /// now rdi is the absolute of the rip-address
mov rsi,ped_density_address /// use this format in case, it is outside 2g range
mov [rsi],rdi /// ped_density_address now has its content store above absolute address
pop rsi
pop rdi
originalcode_ped_density:
//movss xmm0,[sdhdship.exe+207B21C]
//// -- original code option 1
//reassemble(aob_ped_density) /// use reassemble, may fail if there is an rip address outside 2g range of the cave
//// -- original code option 2, manually construct the address and the instruction, use above assume the instruct as movss xmm0,[-some-rip-address-] safe outside 2g range
push rdi
mov rdi,ped_density_address
mov rdi,[rdi] /// get the absolute address
movss xmm0,[rdi]
pop rdi
jmp return_ped_density
ped_density_address:
dq 0
pdbytes:
readmem(aob_ped_density,8)
aob_ped_density:
jmp newmem_ped_density
nop 3
return_ped_density:
[DISABLE]
dealloc(newmem_ped_density)
aob_ped_density:
readmem(aob_ped_density,8) //db F3 0F 10 05 F8 2B C6 01
unregistersymbol(aob_ped_density)
unregistersymbol(ped_density_address)
unregistersymbol(pdbytes) |
Thank you for your help. I really appreciate it.
|
|
Back to top |
|
 |
panraven Grandmaster Cheater
Reputation: 62
Joined: 01 Oct 2008 Posts: 958
|
Posted: Sun Feb 06, 2022 10:57 am Post subject: |
|
|
@" the target crashes"
When enabled, check if the address store at "ped_density_address" is the right address. If not, may add a trace and break on the cave (or a few instruction above the inject point) to see where go wrong.
_________________
- Retarded. |
|
Back to top |
|
 |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Sun Feb 06, 2022 11:10 am Post subject: |
|
|
The address being stored at ped_density_address is correct.
Thanks.
|
|
Back to top |
|
 |
panraven Grandmaster Cheater
Reputation: 62
Joined: 01 Oct 2008 Posts: 958
|
|
Back to top |
|
 |
++METHOS I post too much
Reputation: 92
Joined: 29 Oct 2010 Posts: 4197
|
Posted: Sun Feb 06, 2022 11:27 am Post subject: |
|
|
That did it. Awesome! Thanks so much.
I actually thought that it needed to be the other way around, but it wasn't working:
Code: | pdbytes:
readmem(aob_ped_density,8) |
Thank you all for your help. I really appreciate it.
Now I need to study this more and try to apply it to other scripts.
I will +rep you guys when I can. I won't forget. Thanks so much.
|
|
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
|
|