Inject multiple places

Want Cheat Engine to do something specific and no idea how to do that, ask here. (From simple scripts to full trainers and extensions)
ShyTwig16
Expert Cheater
Expert Cheater
Posts: 335
Joined: Thu Apr 06, 2017 7:14 pm
Reputation: 19

Re: Inject multiple places

Post by ShyTwig16 »

Fruitpunch wrote:
Tue Jan 25, 2022 5:48 pm
...
Perfect! Too bad I didn't think of that myself. All I needed was to change the asm to a function. Now it works exactly like it's supposed to. Before I made the change the script was working but for some weird reason I got an Access violation. I wish there was a deallocSharedMemory though.
You still just use "deAlloc" and pass it the allocated memory address.

miraikolus
Expert Cheater
Expert Cheater
Posts: 59
Joined: Fri Jan 04, 2019 12:09 am
Reputation: 19

Re: Inject multiple places

Post by miraikolus »

Fruitpunch wrote:
Tue Jan 25, 2022 5:48 pm
Yeah dude, you just basically wrote the same thing I had in my first post and it was specifically stated that the aim is to allocate only once, but thanks anyway.
Just there is no second allocation included!? And there is the thing that will not work when you do jumps across (virtual) terabytes, and try mov [faraddr],reg, but instead recommending to use a value in the script. Also there is the hint to not use an extra value to register (but newmem+8).

Btw. I guess it can work without jmp far return as the last script's return will be near the allocated space, but that depends on which codes you hook into and when they are being loaded.
Also: do note that far jumps won't help if the module is using compatibility mode, check out: [Link] (calling would also be the best option for returning to same instruction - you could save that too but that's just additional ops, though depending what you hook into you need to modify the stack value)
Last edited by miraikolus on Thu Jan 27, 2022 9:29 am, edited 1 time in total.

Fruitpunch
Cheater
Cheater
Posts: 34
Joined: Sat Sep 09, 2017 1:07 pm
Reputation: 1

Re: Inject multiple places

Post by Fruitpunch »

miraikolus wrote:
Tue Jan 25, 2022 8:29 pm
Just there is no second allocation included!? And there is the thing that will not work when you do jumps across (virtual) terabytes, and try mov [faraddr],reg, but instead recommending to use a value in the script. Also there is the hint to not use an extra value to register (but newmem+8).

Btw. I guess it can work without jmp far return as the last script's return will be near the allocated space, but that depends on which codes you hook into and when they are being loaded.
Also: do note that far jumps won't help if the module is using compatibility mode, check out: [Link] (calling would also be the best option for returning to same instruction - you could save that too but that's just additional ops, though depending what you hook into you need to modify the stack value)
Sorry you are correct (only one allocation), I only glanced at it briefly. I suggest that in the future you e.g. show what you changed compared to the original posted code.

So what you're saying is that it's possible to in your example not use [faraddr] and just use [newmem+8]. I didn't know that. I guess that depends if all the allocated memory was used or not. Since my background is in C++, all this allocation stuff is quite unfamiliar to me.
ShyTwig16 wrote:
Tue Jan 25, 2022 6:17 pm
You still just use "deAlloc" and pass it the allocated memory address.
Okay, cool. Just saw some confusing remarks about that function around the web so I thought that wouldn't work.

miraikolus
Expert Cheater
Expert Cheater
Posts: 59
Joined: Fri Jan 04, 2019 12:09 am
Reputation: 19

Re: Inject multiple places

Post by miraikolus »

Okay, will try to write a bit clearer. And yes, exactly. You can reference [newmem+8] if in this case newmem is either a symbol or a local label.

You did the CE tutorial, right? So you'll know of addr. like "Tutorial-x86_64.exe"+2265CE. Always think of it as address+offset (if you handle a pointer or s.t. else). newmem+8 is the same. Though newmem is the default label name used. Perfecly safe as label but when using as register, you can only do use that for 1 script, which is ok as you want to do only one allocation but, you seem to want to save a register value as some base to use in a table entry. "baseptr" f.e. makes more sense then newmem
simple addr+offset

Code: Select all

local aascript0=[[alloc(baseptr,$1000]]..''--[[you could allocate near s.t. here that you f.e. find using aobscan in lua]]..[[)
registersymbol(baseptr)]]

local result,aainfo = {},{} --define as table
result[0],aainfo[0] = autoAssemble(aascript0)
print(tostring(result[0]),tostring(aainfo[0])) --always print debugging infos
if not result[0] then error("Couldn't alloc?") end --error handling

local aascript1=[[baseptr+8: //we skip first 8 bytes
mov qword ptr [baseptr],rdi //we save rdi at the start of allocated mem
//all the other code
jmp far baseptr+8 //you don't want to execute the first bytes, read as opcode it would prob crash the game]]

for i=1,1 do
  local result[i],aainfo[i] = autoAssemble(aascript1)
  if not result[i] then error(print("Error at script:",i,"Msg:",aainfo[i])--[[,2]]) end --only infos if needed. aainfo would be a string in this case
end
other ways that are not the best solution but good as examples
Well, static offset. Quite bad if you decide to change the script and forget to change offset too.

Code: Select all

{$lua}
aascript=[[newmem:
mov qword ptr [somelabel],rdi
//your code
somelabel:
...
jmp far newmem]]
registersymbol("symbolforlabel",new+22) --Hope you know addr. are typically as int in lua except some cases (mostly when handling records/Foundlist & such)
Another bad basic example. Avoid globals. And if you get an addr you want to register in lua also do that in lua, no need to pass it using globals. Just to show it could work that way.

Code: Select all

{$lua}
myglobalallocation = allocateMemory(0x1000)
{$asm}
aobscanregion(aobscanforluaval,$myglobalallocation,$myglobalallocation+1,*)
registersymbol(aobscanforluaval) //That would need to be outside any loop if pre CE 7.3
Also rather bad for an address, but maybe useful for s.t. else ...

Code: Select all

newmem:
mov rax,qword ptr [somelabel]
mov qword ptr [rax],rdi //... except this part but rather do s.t. with rax
//code
somelabel: //note: this doesn't have to be a symbol if you only use it in this script
{$lua}
local addr = 78187493520  --holds an addr you want to write to, probably not static like this but read/calc
return string.format("dq %08X", addr)
{$asm}
Last edited by miraikolus on Thu Jan 27, 2022 4:55 pm, edited 1 time in total.

Fruitpunch
Cheater
Cheater
Posts: 34
Joined: Sat Sep 09, 2017 1:07 pm
Reputation: 1

Re: Inject multiple places

Post by Fruitpunch »

miraikolus wrote:
Thu Jan 27, 2022 11:02 am
Okay, will try to write a bit clearer. And yes, exactly. You can reference [newmem+8] if in this case newmem is either a symbol or a local label.

You did the CE tutorial, right? So you'll know of addr. like "Tutorial-x86_64.exe"+2265CE. Always think of it as address+offset (if you handle a pointer or s.t. else). newmem+8 is the same. Though newmem is the default label name used. Perfecly safe as label but when using as register, you can only do use that for 1 script, which is ok as you want to do only one allocation but, you seem to want to save a register value as some base to use in a table entry. "baseptr" f.e. makes more sense then newmem
Cheers m8.

I did the tutorial well over 10 years ago, so it has probably changed since then. :D

Post Reply

Who is online

Users browsing this forum: No registered users