|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Sat Jun 12, 2021 2:31 am Post subject: Automatic Script? |
|
|
I'm trying to make a script that can run on its own once enabled, which detects the current game's version by checking for a valid pointer (different per version, per executable, as there's two platforms for the game).
I guess I'm just having an issue getting it to run by itself? I can allocate memory to the same code cave in every version/platform, so writing the script isn't necessarily my problem, but can I just make it run code when enabled instead of being an inert jmp that will never get reached?
Seeing how I can't be certain where even the static addresses lie between all variants of the game, I can't just plop this at the end of a constant function (like fps counter) to run once.
|
|
Back to top |
|
|
DaSpamer Grandmaster Cheater Supreme Reputation: 52
Joined: 13 Sep 2011 Posts: 1578
|
Posted: Sat Jun 12, 2021 5:20 am Post subject: |
|
|
If using autoassembler you can use {$LUA} block to read the pointer and instruction string according to that.
An example
Code: | {$LUA}
gameVersion = readInteger("address") --readInteger(readInteger(getAddress("baseAddress.exe"+offset)+offset)+offset) ...
[ENABLE]
{$ASM}
alloc(newmem,128)
label(myValue)
label(return)
newmem:
{$LUA}
if (gameVersion == 1) then -- 1 version
return "mov rcx,[rax+E48]"
else -- elseif(gameVersion == 2) then
return "mov rcx,[rax+E60]"
end
{$ASM}
push rax
mov rax,[myValue]
mov [rcx+20],rax
pop rax
jmp return
myValue:
dq #100
"process.exe"+404B:
jmp newmem
nop 2
return:
[DISABLE]
"process.exe"+404B:
{$LUA}
if (gameVersion == 1) then -- 1 version
return "mov rcx,[rax+E48]"
else -- elseif(gameVersion == 2) then
return "mov rcx,[rax+E60]"
end |
_________________
|
|
Back to top |
|
|
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Sat Jun 12, 2021 1:49 pm Post subject: |
|
|
I appreciate the response but it seems I wasn't clear enough.
I'm checking a different pointer entirely for each version of the game. Internally the game only tracks its version in a parsed string {Var}_{Num} (UE4) so I can't point to that with CE. I'm trying to access pointers that point to the game's "seed" on the main menu, which is always the same value, but vastly different pointers between all game variants.
Activating the script on the main menu should fetch the version based on if the pointer is found and valid or not and is excepted; so if it doesn't find v1.0 Platform 1, it'll check v1.0 Platform 2, etc. iteratively increasing versions/platforms, until it finds the one that works.
From that I just had it setting an internal symbol to track both the version and platform, so related scripts can update their aobscans to automatically work based on what is currently attached.
As is, I just have no way of making it run my pointer-check sequence when the script is enabled, since I can't attach this to the end of a background function (all versions/platforms use different static addresses for different things).
|
|
Back to top |
|
|
DaSpamer Grandmaster Cheater Supreme Reputation: 52
Joined: 13 Sep 2011 Posts: 1578
|
Posted: Sun Jun 13, 2021 5:49 am Post subject: |
|
|
Well a code snippet of your script would allow us to see what kind of solutions or alternative approaches are possible.
Referring to the original post,
You may use createThread to execute your script (auto assembler), and keep it in a loop until a certain condition.
You could hook it to a fps counter code, using aobscan&code injection preferably.
Accessing base addresses locations wouldn't be a much of an issue.
_________________
|
|
Back to top |
|
|
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Wed Jun 16, 2021 4:11 am Post subject: |
|
|
Well, trying a newer approach to this by measuring the .exe's size/md5, as they're all distinct enough... but now I've reached the point where I can't seem to allocate space properly.
Code: |
globalalloc(game_platform,4,$process)
globalalloc(game_version,4,$process)
FULLACCESS(game_platform,4)
FULLACCESS(game_version,4)
label(game_version)
label(game_platform)
game_platform:
db byte
game_version:
db byte
[ENABLE]
{$lua}
if syntaxcheck then return end
local myGame = process
local MD5Value=md5memory(myGame,4096)
local ModSize=getModuleSize(myGame)
-- Need to check against results to determine version and set related bytes...
autoAssemble([[
mov [game_platform],01
]]) -- Doesn't hang on "couldn't be injected" but also literally does nothing
{$asm}
[DISABLE]
mov [game_platform],01 //Not all Instructions could be Injected.. likely needs more memory for the instruction but I'm dumb
|
Whether I try to define these in or outside [ENABLE], it always provides the error: "Not all Instructions could be Injected".. unless there's no bytes (db 00) defined at all.
I've looked through a few tutorials and tried searching for why this may be, but I'm totally lost. As I understand it, globalalloc should be providing the designated free space (started with 4kb but no luck, so lowered it to what I presume I need for just definition) at its earliest convenience from the start of the $process, and register the named symbol for me there, and following that given FullAccess should allow me to define those bytes?
Also, whether it's in the [ENABLE] block or not, it automatically assigns a place in memory for the symbols, but can't define the associated label's bytes for presumably the same reason... without enabling the script? Just attaching the table to a process does so; is that something globalalloc does by itself (not in documentation)?
Original method was going to be checking against a bunch of pointers until one was found valid and at correct value in the main menu, but
A) This should be easier to process
B) Same issue, couldn't define these symbols so I tried rewriting it as basic as possible, and I'm just too ignorant to figure out why this doesn't work for either attempt
|
|
Back to top |
|
|
TheyCallMeTim13 Wiki Contributor Reputation: 50
Joined: 24 Feb 2017 Posts: 976 Location: Pluto
|
Posted: Wed Jun 16, 2021 6:06 am Post subject: |
|
|
In my experience "gobalAlloc" is good to use in the table lua script so it's only used once when then table is first loaded. For allocating in AA scripts (scripts that are enable and disable) use "alloc" and "registerSymbol" instead. But you are also using labels that are the same as the symbols/labels that get created by "globalAlloc" so I'd remove the label declaration and just use the symbols you create when allocating the memory. And I would move the allocation to the enable section, otherwise it will try to allocate when enabling and disabling which is unnecessary.
In the script you aren't injecting to anywhere, so the assembled bytes have nowhere to be assembled, and thus won't ever write the value you are trying to set. For what you are doing just use lua functions like "writeInteger" or "writeBytres".
Code: | writeInteger('game_platform', 1) |
EDIT:
For version checking I use the first nodule (usually the EXE) and check the file version. But keep in mind not all games will update the file version. But most seem to, so you'll just have to test it out to see if it changes with the updates for the game.
Code: | getFileVersion(enumModules()[1].PathToFile) |
_________________
|
|
Back to top |
|
|
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Wed Jun 16, 2021 4:29 pm Post subject: |
|
|
Alright, got this working to a degree (thanks for the help!)
As an aside, the file's version detail is always the same, regardless of what patch it's on lol. Thanks for the suggestion though Tim.
My final problem lies in another script's related aobscan based on the version. Seems that using Lua to Autoassemble doesn't let the regular ASM respect symbols defined this way?
Code: |
[ENABLE]
{$lua}
if syntaxcheck then return end
local checkVer = readBytes('game_version',1)
if checkVer == 14 then
autoAssemble([[
aobscanmodule(INJECT_ItemEdit,$process,97 06 00 4C 8B 03 48 8D 54 24 30)
registersymbol(INJECT_ItemEdit) //also doesn't work
]])
elseif checkVer == 13 then
autoAssemble([[
aobscanmodule(INJECT_ItemEdit,$process,40 06 00 4C 8B 03 48 8D 54 24 30)
]])
...
...
end
{$asm}
alloc(newmem,$1000,INJECT_ItemEdit)
|
"Failure determining what INJECT_ItemEdit means" error, even though it should be defined by the aobscanmodule? I thought Lua would resolve first so it shouldn't be an issue, but maybe I read that wrong.
The AOBs are impossible to make distinctly unique and work between all versions (3 bits are shared out of the entire sequence for all), so I need this method of checking version to have it all be in a single script.
Code: |
Compiled list of AOBs
97 06 00 4C 8B 03 48 8D 54 24 30
40 06 00 4C 8B 03 48 8D 54 24 30
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 72
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 72
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 92
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 92
EE 12 00 4C 8B 03 48 8D 54 24 30
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 02
9F 0D 00 4C 8B 03 48 8D 54 24 30
9E 0D 00 4C 8B 03 48 8D 54 24 30
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 C2
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 72
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 B2 EC
4C 8B 03 48 8D 54 24 30 48 8B C8 48 8B F8 E8 A2
"Unique" AOB
** ** 0* 4* 8* ** ** ** ** ** ** ** ** ** ** ** **
|
|
|
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
|
|