 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Iniar How do I cheat?
Reputation: 0
Joined: 05 Dec 2023 Posts: 5
|
Posted: Tue Dec 05, 2023 5:18 am Post subject: Multi-level pointer in Cheat Engine autoassembler script |
|
|
Good afternoon. Please tell me how to fix or more correctly register a multi-level pointer in an autoassembler script? My version of the script crashes the game, I don’t understand why. The crash occurs after adding another pointer level. Here's my script:
| Code: |
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
aobscanmodule(patron2,lithtech.exe,8B 56 3C 57 83 C2 40) // should be unique
alloc(newmem,$4000)
label(code)
label(patr2)
registersymbol(patr2)
label(return)
newmem:
push edx
xor edx,edx
lea edx,["lithtech.exe"+00014238]
mov edx,[edx]
lea edx,[edx+2C]
mov edx,[edx]
lea edx,[edx+D0]
lea edx,[edx+6C]
mov edx,[edx]
lea edx,[edx+4]
mov edx,[edx]
lea edx,[edx+C]
//mov edx,[edx] // -------- If you uncomment this, then the game crashes and patr2 is zero.
//lea edx,[edx+8]
mov dword ptr [patr2],edx
pop edx
mov edx,[esi+3C]
push edi
add edx,40
jmp return
code:
//mov edx,[esi+3C]
//push edi
//add edx,40
//jmp return
patr2:
dd 0
patron2:
jmp newmem
nop 2
return:
registersymbol(patron2)
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
patron2:
db 8B 56 3C 57 83 C2 40
unregistersymbol(patron2)
unregistersymbol(patr2)
dealloc(newmem)
|
My index has 7 levels.
|
|
| Back to top |
|
 |
Csimbi I post too much
Reputation: 97
Joined: 14 Jul 2007 Posts: 3326
|
Posted: Tue Dec 05, 2023 8:27 am Post subject: |
|
|
Try this (provided the offsets are correct).
| Code: | push edx
mov edx,["lithtech.exe"+00014238]
mov edx,[edx+2C]
mov edx,[edx+D0]
mov edx,[edx+6C] // ? You had two LEA instructions here, not sure why, please double-check it
mov edx,[edx+04]
mov edx,[edx+0C]
mov edx,[edx+08]
mov dword ptr [patr2],edx
pop edx |
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4707
|
Posted: Tue Dec 05, 2023 1:02 pm Post subject: |
|
|
There's no need to interleave `mov` and `lea` instructions. The only exception might be the last offset (use `lea` instead of `mov`) since you typically want the final address and not the final value, but you could also delay that last offset until you actually need the value.
With that said, why are you doing this in an AA script? If this isn't just a pedagogical example, use Lua instead.
| Code: | -- use a more unique name than `t`
if t then t.destroy(); t = nil end
t = createTimer()
t.Interval = 100
t.OnTimer = function()
registerSymbol('patr2', getAddressSafe'[[[[[["game.exe"+00014238]+2C]+D0]+6C]+4]+C]+8', true)
end | Note that you need one less layer of indirection when using the symbol "patr2" with this script. It's registering the address itself and not a pointer to the address.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| Back to top |
|
 |
Iniar How do I cheat?
Reputation: 0
Joined: 05 Dec 2023 Posts: 5
|
Posted: Tue Dec 05, 2023 11:01 pm Post subject: |
|
|
| Csimbi wrote: | Try this (provided the offsets are correct).
| Code: | push edx
mov edx,["lithtech.exe"+00014238]
mov edx,[edx+2C]
mov edx,[edx+D0]
mov edx,[edx+6C] // ? You had two LEA instructions here, not sure why, please double-check it
mov edx,[edx+04]
mov edx,[edx+0C]
mov edx,[edx+08]
mov dword ptr [patr2],edx
pop edx |
|
Thanks for the option. But in my case, unfortunately, it didn’t work. Apparently there is some problem with the offsets. The situation is this: Offsets 2C and D0 go without problems, then after them comes offset 0 and if I leave only mov edx,[edx+2C] and mov edx,[edx+D0] in the script, and place the pointer address in the cheat table [patr2] and I add further offset levels in it manually, then the address simply loops no matter how many levels and what offsets I add.
| ParkourPenguin wrote: | There's no need to interleave `mov` and `lea` instructions. The only exception might be the last offset (use `lea` instead of `mov`) since you typically want the final address and not the final value, but you could also delay that last offset until you actually need the value.
With that said, why are you doing this in an AA script? If this isn't just a pedagogical example, use Lua instead.
| Code: | -- use a more unique name than `t`
if t then t.destroy(); t = nil end
t = createTimer()
t.Interval = 100
t.OnTimer = function()
registerSymbol('patr2', getAddressSafe'[[[[[["game.exe"+00014238]+2C]+D0]+6C]+4]+C]+8', true)
end | Note that you need one less layer of indirection when using the symbol "patr2" with this script. It's registering the address itself and not a pointer to the address. |
Your option works well. In [patr2] I got an address one offset less than the address I needed by removing one level in getAddressSafe and adding readInteger at the end. But the question is, how can I now transfer this address from [patr2] to the edx register so that I can continue to work with it in the AA script? By the way, I integrated your Lua code into my AA script. I want to further use a loop to sequentially change values at successive address offsets. And since I don’t speak Lua well, I use AA scripts for my training. Here's an example loop I want to use after passing the address of the value from [patr2] to edx :
| Code: |
cikl:
cmp ax,0
je exitcikl
mov [edx],0a
add edx,4
dec ax
jmp cikl
|
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4707
|
Posted: Wed Dec 06, 2023 12:03 am Post subject: |
|
|
| Iniar wrote: | | Offsets 2C and D0 go without problems, then after them comes offset 0 | You didn't include that in the AA script. What is the correct pointer path?
| Iniar wrote: | | By the way, I integrated your Lua code into my AA script. | Unless you used {$luacode} it's wrong. {$lua} blocks get executed only once when the script is assembled.
This really isn't a usecase for {$luacode} anyway.
| Iniar wrote: | | I don’t speak Lua well | Lua is a lot easier to learn than assembly.
| Code: | if arrayFreezeTimer then arrayFreezeTimer.destroy(); arrayFreezeTimer = nil end
arrayFreezeTimer = createTimer()
arrayFreezeTimer.Interval = 100
arrayFreezeTimer.OnTimer = function(t)
local addr = getAddressSafe'[[[[[[["game.exe"+00014238]+2C]+D0]+0]+6C]+4]+C]+8'
if not addr then
t.Enabled = false
error'Invalid pointer path'
end
for i = 0, 9 do
writeInteger(addr, 10)
addr = addr + 4
end
end |
Roughly equivalent AA code:
| Code: | ...
newmem:
// no need to push/pop edx- the original code overwrites it
push ecx
{$try}
mov edx,[game.exe+00014238]
mov edx,[edx+2C]
mov edx,[edx+D0]
mov edx,[edx]
mov edx,[edx+6C]
mov edx,[edx+4]
mov edx,[edx+C]
lea edx,[edx+8]
mov ecx,#10
jmp enterLoop
{$except}
jmp originalcode
myloop:
mov dword ptr[edx],#10
add edx,4
dec ecx
enterLoop:
test ecx,ecx
jnz myloop
originalcode:
pop ecx
mov edx,[esi+3C]
push edi
add edx,40
jmp return
...
|
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| Back to top |
|
 |
Iniar How do I cheat?
Reputation: 0
Joined: 05 Dec 2023 Posts: 5
|
Posted: Wed Dec 06, 2023 12:44 am Post subject: |
|
|
| ParkourPenguin wrote: | | Iniar wrote: | | Offsets 2C and D0 go without problems, then after them comes offset 0 | You didn't include that in the AA script. What is the correct pointer path? |
The thing is that this game constantly hides the process when you restart the game. The instruction I'm interested in and all the offsets in it change after each restart. If I make a script according to the instructions I found, then when I restart the game the script does not work, even though I use AOBScan in the AA script. Just in addition to the shift, the game process itself also changes. For example, I wrote a script and in it: | Code: | | aobscanmodule(patron4,cshD98E.tmp,89 08 8B 44 24 3C) | . After restarting the game, the instructions will be located here, for example - | Code: | | aobscanmodule(patroni4,tmpA23C.tmp,89 08 8B 44 24 3C) | . Because of this, you need to manually search for the byte array again, change the module in the script, etc.
But I found a solution, through several stages of pointer search I reached the address of the initial stage of the pointer to which, during certain actions in the game (for example, a shot), an instruction is triggered from a static game module like - aobscanmodule(patron2,lithtech.exe,8B 56 3C 57 83 C2 40). And from this the script begins to work. I take the address of the beginning of the pointer stage, the one that does not change under any conditions, BUT NO INSTRUCTION WORKS WITH IT IN THE GAME, I put this pointer in the instruction that works in the game and already perform actions on this pointer. So far I have several versions of these pointers and I'm still trying to figure out which one is more stable under all game conditions and restarts. And these several pointers have completely different sets of offsets. That's why I wrote it like that. But still, the option of the person who gave me the first example did not work with those offsets that, when manually creating a pointer in a table, show the result. The game works in a very cunning way, but I was able to partially overcome it.
| ParkourPenguin wrote: |
| Iniar wrote: | | By the way, I integrated your Lua code into my AA script. | Unless you used {$luacode} it's wrong. {$lua} blocks get executed only once when the script is assembled.
This really isn't a usecase for {$luacode} anyway.
| Iniar wrote: | | I don’t speak Lua well | Lua is a lot easier to learn than assembly. |
Thanks for your examples. They made me a little smarter.)
Yes, perhaps Lua is much easier to learn, but from the very beginning of working with CE I worked and improved my AA scripting knowledge. For example, if I take your piece of Lua script, it will take the address I need, it will execute the piece of script 9 times in a loop... But then I need it to execute the original part of the game code after exiting the loop and finish before the next shot, for example . So far, it’s difficult for me to understand exactly when your lua script is triggered and how to tie it to the conditions I need in the game (for example, a shot), how to execute the lua script, then the original game code and complete the script before the next shot in the game. I can send my full script to give you an idea of the big picture if you are interested.
By the way, if you are interested in researching what I am doing, you can download the game No One Live Forever 2. I am researching the possibility of giving me 10 rounds of ammunition for all weapons when I fire a shot from any weapon. Do 10 even on weapons that I don’t have open. It’s just that in the game all weapon addresses are in a sequential array one after another with an offset of +4. You can take my full script with your additions and test it.
For me, this is a sporting interest in the quality of my training and improving my game hacking skills. Beating the game is not my goal. I've already passed it a long time ago several times. Back when I didn’t know how to hack games.)
|
|
| 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
|
|