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 


most elegant method for pointer finding script

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

Joined: 24 Sep 2023
Posts: 6

PostPosted: Sun Jul 13, 2025 4:57 pm    Post subject: most elegant method for pointer finding script Reply with quote

Hi!

I'm trying to improve my skills in CheatEngine scripting, and I'd like to know about some of the "best practices" for scripting, or if I'm not reinventing the wheel.

TLDR: is creating an LUA script that manages autoassembly ones a good idea?

Right now, as I couldn't get pointer scanning to work with my game, I created an autoassembly script to retreive the pointer when it passes on the instruction I found with "Find out what writes at this address"

However thinking about doing a "clean" script, I wondered: "once I find the pointer, I don't need my autoassembly patch, I can disable it!"
But if I disable the autoassembly script, ideally I should deallocate my memory and unregister the symbols... So what do?

My solution was creating an LUA script, that will enable/disable the Autoassembly script when needed. workflow:


    * - LUA script is enabled
    * - registerSymbol of my variable (say "posX")
    - enable the autoassembly script
    I do it via `getAddressList().getMemoryRecordByDescription("scriptName").Active`
    I know I could do it inside the LUA script via `autoassemble`, but I find it cleaner to read this way.
    - on autoassembly Script:
    - register a temporary symbol (say "xTemp")
    - patch my instruction to read the register, and store it to "xTemp" symbol
    of course, I also add offsets, and checks in case of shared instructions
    - back on the LUA:
    - I set a timer every 10th a second to check if "xTemp" is available and not null
    - if available, I copy it's value to my LUA registered symbol "posX"
    - Then I disable the autoassembly script and the timer.
    - The disabling of the autoassembly script unregisters "xTemp" and repatches the game instructions.
    - When I disable the LUA script, I clean all and unregister "posX" / disable the autoassembly script if still running.


The advantages for me are:
- It's more performant, as my autoassembly patch is automatically disabled when not needed anymore.
- It's surely a bit stealthier (not that I aimed specially for it)
- In my LUA script I can know when the pointer is available, and do more stuff/ enable additional LUA scripts accordingly (ex: hotkeys to teleport)


I don't know if my explanation is clear, I can provide a small code example if needed (I didn't included the code because I was afraid it would make it *less* clear ^^')
So, is it an "elegant" solution, is there a better one that was found?

Also small detail, I fail to see the difference between autoassembly scripts in LUA and the "Cheat Table LUA Script".
They work the same way, except that the "Cheat Table LUA Script" is autorunned at load and is the good place to put trainer specific code, am I right, or missing something?

Thanks again for the support, last time I asked a question here i got super fast insightful answers! Very Happy
Also, I did a talk about game hacking, with a focus on CheatEngine, on a pretty big hacking conference in France! But Youtube replays won't be available until a few months :/
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4690

PostPosted: Mon Jul 14, 2025 12:42 am    Post subject: Reply with quote

That seems overly complicated to me. One alternative is to set a breakpoint on the instruction that will copy the address and remove itself when triggered, but I don't think you should be doing that in the first place. Keeping the code injection active is the best and "most elegant" solution IMO. I'm ignoring any games that try to protect themselves against external software since that's outside the scope of these forums.

tuxlu wrote:
However thinking about doing a "clean" script, I wondered: "once I find the pointer, I don't need my autoassembly patch, I can disable it!"
If the address never changes, then sure, that's fine. Certain actions like reloading a save might allocate new memory for relevant values. If the code injection is still active, it will get the new address; otherwise, modifying the old value will either fail in the best case or make arbitrary changes to other parts of the game in the worst case.

tuxlu wrote:
But if I disable the autoassembly script, ideally I should deallocate my memory and unregister the symbols...
`globalalloc` allocates memory once and never deallocates it. You might need to access that memory indirectly through a register:
Code:
globalalloc(myAddress,8)
...
push rdx
mov rdx,myAddress
mov [rdx],rsi
pop rdx
// original code:
mov [rsi+3C],rcx
...


tuxlu wrote:
- enable the autoassembly script
I do it via `getAddressList().getMemoryRecordByDescription("scriptName").Active`
...
- I set a timer every 10th a second to check if "xTemp" is available and not null
I'd organize this better by starting the timer inside the AA script in a {$lua} block. Search the forums for relevant information (particularly "syntaxcheck").

tuxlu wrote:
It's more performant
Negligible in every sense of the word. It's so small it would be practically impossible to measure.
The Lua timer that's calling ReadProcessMemory 10 times per second is several orders of magnitude worse for performance than any theoretical gain from disabling the code injection. Even disabling the script once might use more CPU resources than simply leaving it enabled, but again, that's negligible.

tuxlu wrote:
It's surely a bit stealthier (not that I aimed specially for it)
Not really IMO. Of all the things you could be concerned about, this isn't that important.

tuxlu wrote:
In my LUA script I can know when the pointer is available, and do more stuff/ enable additional LUA scripts accordingly (ex: hotkeys to teleport)
Good idea, but the checks are backwards. It's not safe for the other Lua objects to make assumptions: they should be responsible for checking if the address is valid every time they're invoked.

tuxlu wrote:
Also small detail, I fail to see the difference between autoassembly scripts in LUA and the "Cheat Table LUA Script".
They work the same way, except that the "Cheat Table LUA Script" is autorunned at load and is the good place to put trainer specific code, am I right, or missing something?
AA scripts run AA code, are usually placed in the address list, and can be enabled/disabled by users whenever. The cheat table's Lua script runs Lua code, is unique (i.e. there is one and only one), should be run once when the table is loaded (users can opt out), and can be run by users later (but probably won't be for typical users).
The table's Lua script is generally more complicated to use correctly: many table authors don't account for the possibility that users can run them multiple times. This can lead to memory leaks and duplicated objects.

If you're talking about the `autoAssemble` Lua function, it's a part of CE's Lua API. It doesn't make sense to compare it to the cheat table's Lua script. You use it to run an AA script from Lua.
Comparing that to running an AA script from the cheat table is a more interesting problem. That's usually a matter of how the author wishes to organize and/or present their work to the user- there is no "correct" answer.

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

Joined: 24 Sep 2023
Posts: 6

PostPosted: Mon Jul 14, 2025 11:20 am    Post subject: Reply with quote

thank you again so much for the fast and insightful answer!

Indeed, I may have overcomplicated my script and I overlooked the fact that the address coiuld change when reloading the level.

and indeed stealth was never the point of this approach, just wanted to justify myself on the advantages of doing it my way ^^'

I misunderstood a bit of your advice, I tought for a moment you implied the idea that you could sandwich some LUA code inside an ASM patch, like this:

Code:

mov RAX, 42
mov RCX, [rbx+1337]
{$lua}
print(rcx)
{$asm}
cmp rcx, rax
jne end


but I tried and of course it does not work!

So yeah, maybe I wasn't clear, but I have 2 AA scripts, the "manager" that is in LUA, and the "patch" one that is full ASM, I find it more clear than having 2 languages in the same file.

thanks again!
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 470

Joined: 09 May 2003
Posts: 25762
Location: The netherlands

PostPosted: Mon Jul 14, 2025 11:59 am    Post subject: Reply with quote

replace {$lua} with {$luacode}
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4690

PostPosted: Mon Jul 14, 2025 1:10 pm    Post subject: Reply with quote

If you want the game to run some Lua code in CE synchronously within a code injection, use {$luacode}
https://forum.cheatengine.org/viewtopic.php?t=618134

A {$lua} block is basically a preprocessor macro for AA scripts. They run some Lua code and substitute any returned string into the location where the {$lua} block was located. Returning nothing is also fine.
Again, use a search engine to search the forums. There's plenty of examples.

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

Joined: 24 Sep 2023
Posts: 6

PostPosted: Tue Jul 15, 2025 11:22 am    Post subject: Reply with quote

damn, that's impressive, I had no idea you could do that.
I promise I'll read more of the wiki and check on the forum before asking any more questions.
Thanks again!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking 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