 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Fred.000 How do I cheat?
Reputation: 0
Joined: 30 Nov 2023 Posts: 2
|
Posted: Thu Nov 30, 2023 4:25 pm Post subject: Trying to make working a CE script for Metro Exodus |
|
|
Hi!
I'am trying to use a CE script "M3 Engine 1.0.0.7 for CE 7.1" made by SunBeam.
I'am playing with the original Metro Exodus game version (on Steam).
I'am using CE 7.5, because CE 7.1 do not work on my computer (installation crashes).
With CE 7.5, after attaching the process and "initializing", adding vars and Dev Console (F1) are working well, but when checking NoClip, the game freezes and crashes as soon as I try to move in game.
After crashing the game, when editing the scripts in CE, I can validate the 2 first scripts, but when trying to validate the NoClip one, I got the message : "this address specifier is not valid" at
====> [ZLock]+34:
dd 08080000
Maybe because the game just crashed and the address is not available anymore?
| Code: | [ENABLE]
Trampolines+00:
jmp [jumptrampolineaddress]
jumptrampolineaddress:
dq MovementHook
align 10 CC
NoClip:
jmp Trampolines+00
[DISABLE]
[ZLock]+34:
dd 08080000
[ZLock]+30:
db 0
NoClip:
readmem( NoClip_o, 5 ) |
I'am trying to tshoot the issue, but without success. What is the best way to understand the issue? Using a debugger? Installing CE Extensions? Other tips?
Am I missing something obvious?
Regards,
Fred
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4717
|
Posted: Thu Nov 30, 2023 4:40 pm Post subject: |
|
|
That script by itself doesn't provide much information. Where is NoClip, Trampolines, MovementHook, ZLock, and NoClip_o?
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| Back to top |
|
 |
Fred.000 How do I cheat?
Reputation: 0
Joined: 30 Nov 2023 Posts: 2
|
Posted: Fri Dec 01, 2023 2:54 pm Post subject: |
|
|
These are defined in the "Initiaze" script.
| Code: | {$STRICT}
{$lua}
if syntaxcheck then return end
function stopExec( s )
error( print( string.format( "\r\n>> %s <<", s ) ) )
end
function aobScanEx( aob )
-- thanks panraven for this function!
-- https://forum.cheatengine.org/viewtopic.php?t=577536
-- simplified for my needs
local p, a, n, s, e = nil or '*X*W', nil or fsmNotAligned, nil or '0', getAddress( process ) or 0x0, ( getAddress( process ) + getModuleSize( process ) ) or 0xffffffffffffffff
local ms = pb and createMemScan( pb ) or createMemScan()
local fl = createFoundList( ms )
ms.firstScan( soExactValue, vtByteArray, nil, aob, nil, s, e, p, a, n, true, false, false, false )
ms.waitTillDone()
fl.initialize()
local result = nil
if fl ~= nil and fl.getCount() > 0 then
result = createStringlist()
for i = 1, fl.getCount() do result.add( fl.getAddress( i - 1 ) ) end
end
fl.destroy()
ms.destroy()
return result
end
local _script = [[[ENABLE]
label( NoClip_o )
registersymbol( NoClip_o )
alloc( MovementHook, 0x1000, MetroExodus.exe )
registersymbol( MovementHook )
label( skip )
label( subGetAsyncKeyState )
label( fraction )
label( ZLock )
registersymbol( ZLock )
MovementHook:
push rdx
mov rdx,g_PhysX
mov rdx,[rdx]
mov rdx,[rdx+28] // leads to Player
mov rdx,[rdx+758]
mov rdx,[rdx+10]
cmp rbx,rdx
pop rdx
jnz NoClip_o
mov [ZLock],rbx
mov byte ptr [rbx+30],4
mov rax,g_PhysX
mov rax,[rax]
mov rax,[rax+28] // leads to Player
test rax,rax
jz NoClip_o
cmp [rax+938],0 // check if camera vector is initialized
jz NoClip_o
push rax
push rbx
push rdx
push rsi
push rdi
push rbp
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push rcx
xor r10,r10
mov r11,1 // FORWARD
mov ecx,'W'
call short subGetAsyncKeyState
mov r11,2 // BACKWARD
mov ecx,'S'
call short subGetAsyncKeyState
mov r11,4 // STRAFE LEFT
mov ecx,'A'
call short subGetAsyncKeyState
mov r11,8 // STRAFE RIGHT
mov ecx,'D'
call short subGetAsyncKeyState
mov r11,10 // FASTER
mov ecx,10 // Shift
call short subGetAsyncKeyState
mov r11,20 // Z UP
mov ecx,20 // Space
call short subGetAsyncKeyState
mov r11,40 // Z DOWN
mov ecx,11 // Ctrl
call short subGetAsyncKeyState
pop rcx
test r10,r10
jz skip
mov rdi,g_PhysX
mov rdi,[rdi]
mov rdi,[rdi+28]
mov rbx,rdi
mov rdi,[rdi+928] // camera vector (already normalized)
test rdi,rdi
jz skip
movups xmm1,[rdi+C0]
xorps xmm15,xmm15 // this register will temporary keep sum of four vectors (forward, backward, strafe left, strafe right)
test r10,1 // forward
jz +4
addps xmm15,xmm1
test r10,2 // backward
jz +4
subps xmm15,xmm1
// calc rotatedLeftBy90 vector
shufps xmm1,xmm1,6 // camera struct (X,Z,Y), Z is up-down axis
// now xmm1 contains (Y,Z,X)
xorps xmm2,xmm2
subss xmm2,xmm1
movss xmm1,xmm2 // now xmm1 contains (-Y,Z,X); rotatedLeftBy90deg in Z-axis
movaps xmm14,xmm1 // save for later
// for strafing we have to set Z to zero
mov eax,-1
movd xmm2,eax
shufps xmm2,xmm2,8
andps xmm1,xmm2 // now xmm1 contains (-Y,0,X)
test r10,4 // strafe left
jz +4
addps xmm15,xmm1
test r10,8 // strafe right
jz +4
subps xmm15,xmm1
// move in Z axis
mov eax,(float)1.0
movd xmm1,eax
shufps xmm1,xmm1,51 // now xmm1 contains (0,1,0)
test r10,20 // Z axis UP
jz +4
addps xmm15,xmm1
test r10,40 // Z axis DOWN
jz +4
subps xmm15,xmm1
movups xmm1,[rdi+C0] // camVect
movaps xmm2,xmm14 // rotLeft90camVect
movaps xmm14,xmm1
shufps xmm1,xmm1,9
shufps xmm2,xmm2,12
shufps xmm14,xmm14,12
mulps xmm1,xmm2
shufps xmm2,xmm2,12
mulps xmm14,xmm2
subps xmm1,xmm14
// xmm1 now has cross product of camVect and rotLeft90camVect, lets call it V1
movaps xmm14,xmm1
subss xmm14,xmm1
subss xmm14,xmm1
shufps xmm14,xmm14,6 // xmm14 now has rotRight90V1, lets call it V2
addps xmm1,xmm14 // sum of V1 and V2
// normalize
movaps xmm2,xmm1
mulps xmm2,xmm2
movss xmm14,xmm2
shufps xmm2,xmm2,21
addss xmm14,xmm2
movhlps xmm2,xmm2
addss xmm14,xmm2
sqrtss xmm14,xmm14
shufps xmm14,xmm14,00
divps xmm1,xmm14
movaps xmm1,xmm15 // xmm1 constains vector for No_Clip (sum of many vectors)
xorps xmm2,xmm2
mulps xmm15,xmm15
addss xmm2,xmm15
shufps xmm15,xmm15,E1
addss xmm2,xmm15
movhlps xmm15,xmm15
addss xmm2,xmm15
sqrtss xmm2,xmm2 // xmm2 contains No_Clip vector length
xorps xmm15,xmm15
comiss xmm2,xmm15 // deal with division by zero
je short skip
shufps xmm2,xmm2,00
divps xmm1,xmm2 // No_Clip vector is now normalized
// before we add this vector to playerPos, we have to reduce it a bit
movss xmm2,[fraction]
shufps xmm2,xmm2,00
// faster
test r10,10
jz +6
addps xmm2,xmm2
addps xmm2,xmm2
mulps xmm1,xmm2
// update player pos
mov rbx,[rbx+758]
test rbx,rbx
jz short skip
mov rbx,[rbx+10]
movups xmm2,[rbx+BC]
addps xmm2,xmm1
movq [rbx+BC],xmm2
movhlps xmm2,xmm2
movss [rbx+C4],xmm2
skip:
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rbp
pop rdi
pop rsi
pop rdx
pop rbx
pop rax
xor edi,edi
NoClip_o:
readmem( NoClip, 5 )
jmp NoClip+5
align 10 CC
subGetAsyncKeyState:
push r10
push r11
sub rsp,8
call GetAsyncKeyState
add rsp,8
pop r11
pop r10
test ax,8000
jz short @f
or r10,r11
@@:
ret
align 10 CC
fraction:
dd (float)0.025
align 10 CC
ZLock:
dq 0
align 10 CC
]]..[[[DISABLE]
unregistersymbol( NoClip_o )
dealloc( MovementHook )
unregistersymbol( MovementHook )
unregistersymbol( ZLock )
]]
[ENABLE]
local sl, u, t = 0, 0, 0
-- read the version from the game
local aob_to_VersionString = "49????4C8D0D????????4C8D05????????48????E8????????E9????????41"
sl = aobScanEx( aob_to_VersionString )
if not sl or sl.Count < 1 then stopExec( "'aob_to_VersionString' not found." ) end
t = tonumber( sl[0], 16 ) + 0x3
t = t + readInteger( t + 0x3, true ) + 0x7
local GameVersion = readString( t, 8 )
GameVersion = GameVersion:gsub( "^%s*(.-)%s*$", "%1" )
-- read the version from the table
local TableVersion = addresslist_getMemoryRecord( getAddressList(), 1 )
TableVersion = memoryrecord_getDescription( TableVersion )
TableVersion = string.match( TableVersion, 'Version: Epic Games Store | (.*)' )
-- check the two and warn the user
if TableVersion ~= GameVersion then
showMessage( "This table is designed for Version: \r\n>> " .. TableVersion .. "\r\n\r\nYours is: \r\n>> " .. GameVersion .. "\r\n\r\nThe script will now enable, though I can't guarantee everything will work properly." )
end
-- continue and find the requisites
local aob_g_Console = "488B0D????????4885C975??E8????????488BC8488905????????E8"
sl = aobScanEx( aob_g_Console )
if not sl or sl.Count < 1 then stopExec( "'aob_g_Console' not found." ) end
t = tonumber( sl[0], 16 )
t = t + readInteger( t + 0x3, true ) + 0x7
unregisterSymbol( "g_Console" )
registerSymbol( "g_Console", t, true )
local aob_NoClip = "48837B??0074??807B??000F94??84C075??85??74??F3"
sl = aobScanEx( aob_NoClip )
if not sl or sl.Count < 1 then stopExec( "'aob_NoClip' not found." ) end
t = tonumber( sl[0], 16 )
unregisterSymbol( "NoClip" )
registerSymbol( "NoClip", t, true )
local aob_g_PhysX = "488B05????????48895C24??48897C24??488B48??4885C974"
sl = aobScanEx( aob_g_PhysX )
if not sl or sl.Count < 1 then stopExec( "'aob_g_PhysX' not found." ) end
t = tonumber( sl[0], 16 )
t = t + readInteger( t + 0x3, true ) + 0x7
unregisterSymbol( "g_PhysX" )
registerSymbol( "g_PhysX", t, true )
local aob_infFlashlight = "80B9????????00F30F114C24??75"
sl = aobScanEx( aob_infFlashlight )
if not sl or sl.Count < 1 then stopExec( "'aob_infFlashlight' not found." ) end
t = tonumber( sl[0], 16 )
unregisterSymbol( "InfiniteFlashlight" )
registerSymbol( "InfiniteFlashlight", t, true )
local aob_infFlamethrower = "48895C24??574883EC??48????E8????????33DB85C074??48????E8"
sl = aobScanEx( aob_infFlamethrower )
if not sl or sl.Count < 1 then stopExec( "'aob_infFlamethrower' not found." ) end
t = tonumber( sl[0], 16 )
t = t + 0x1B
if readBytes( t, 1 ) ~= 0xE8 then stopExec( "incorrect alignment, wrong byte found." ) end
t = t + readInteger( t + 0x1, true ) + 0x5
unregisterSymbol( "InfiniteFlamethrower" )
registerSymbol( "InfiniteFlamethrower", t, true )
local gameModule = getAddress( process )
local offset = 0x550
t = gameModule + offset
fullAccess( t, 0x1000 - offset )
executeCodeEx( 0, nil, getAddressSafe( "RtlZeroMemory" ), t, 0x1000 - offset )
unregisterSymbol( "Trampolines" )
registerSymbol( "Trampolines", t, true )
result, disableinfo = autoAssemble( _script )
[DISABLE]
autoAssemble( _script, disableinfo )
local t = getAddressSafe( "Trampolines" )
local offset = 0x550
executeCodeEx( 0, nil, getAddressSafe( "RtlZeroMemory" ), t, 0x1000 - offset )
unregisterSymbol( "Trampolines" )
autoAssemble([[
unregistersymbol( InfiniteFlamethrower )
unregistersymbol( InfiniteFlashlight )
unregistersymbol( g_PhysX )
unregistersymbol( NoClip )
unregistersymbol( g_Console )
]]) |
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4717
|
Posted: Fri Dec 01, 2023 4:11 pm Post subject: |
|
|
There's probably something wrong in that script, but I really don't want to read through all of it. There's some small things like executing memory initialized by `readmem` (should use `reassemble` for that). I don't know what the author intended with `jz +6` but they're wrong. CE interprets that as a conditional jump to the address 6- this will certainly crash the game if the branch is taken.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| 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
|
|