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 


How to pass parameters to CELUA_ExecuteFunctionByReference

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

Joined: 22 Nov 2023
Posts: 5

PostPosted: Thu Nov 23, 2023 1:35 am    Post subject: How to pass parameters to CELUA_ExecuteFunctionByReference Reply with quote

I'm in a bit over my head, but I'm very close to accomplishing what I'm trying to do. I'm very new to assembly, so please keep that in mind if you are so kind as to respond.

I followed Dark Byte's tutorial on CELUA_ExecuteFunctionByReference. I'm testing out some scripts on Do Not Feed the Monkeys 2099. I've copied the code in the tutorial and made minor changes and it runs and I can get it to do some stuff, but I can't get it to do what I want it to do. If I leave everything alone, I can access and display the values of the parameters that are passed to it, but I'm not sure how to set the parameters I want.

The tutorial script passes some address to the function. I want to pass 1 address and read what's inside, then alter it. I also want to pass an integer telling the function how much to change the value.

I have a simple lua function like this:

function changeValue(address,value)
if condition then
oldvalue = readInteger(address)
newvalue = oldvalue + value
writeInteger(address,newvalue)
end
end

Next, we initialize everything:
...
alloc(luafunctionid,4)
alloc(luafunctionname,256)
...

Next, there's a bunch of memory allocation stuff I don't understand and moving some values around:

...
newmem:
//save the state
sub rsp,20+a*8
...
//store parameters you might be interested in
mov [rsp+20],rax
...
//store these registers as they may get changed:
mov [rsp+40],rcx

Next, I modified the script to try and pass the pointer I'm interested in. I have no idea if this is the right way to do it, but it seems to work:
...
//setup parameter space:
//--- ORIGINAL ---//
//lea rax,[rsp+20]
//---- My Attempt to load the pointer I want----//
mov rax,[[[[[[[[UnityPlayer.dll+01994540]+08]+58]+48]+10]+58]+28]+E0]

When I print the value of the address that gets passed in the function (rax/[UnityPlayer.dll+01994540...]) I get something like this: 4793993838110703763. I don't know what this number represents and it seems to change every time I run it.

Then some other stuff happens I don't really understand:
...
//need to keep the stack aligned
lea rax,[rbx+7f0]
...
//store these registers as they may get changed:
mov [rsp+48],rdx
...

Then we set up the function
...
mov rcx,luafunctionname
call CELUA_GetFunctionReferenceFromName
...


Then we run the function:
...
hasrefid: //there is a functionID to use
mov edx,2 //only the addresses of RAX and RBX are to be passed. So 2
lea r8,[rsp+30] //the addresses to RAX and RBX are at RSP+30
mov r9,0 //0=no async, 1=async. Use async if you do not wish to update
call CELUA_ExecuteFunctionByReference
...

I don't really understand what's going on here, but here's what I think is going on:

mov edx,2 <- Tells CELUA_ExecuteFunctionByReference the number of parameters
lea r8,[rsp+30] <- The parameters, in this case 2 addresses. In my modifications, the first one should be that pointer [UnityPlayer.dll+01994540...]. I'd like the second one to be an integer which I will add to the value of that pointer, but as it stands it's some memory address (RBX I guess).

It's not clear to me how this even works, RAX is pretty straight forward:
mov [rsp+30],rax

RBX on the other hand does not appear to ever be set to anything or set to RSP+30, and also I don't understand how we're passing two values with one register:
//need to keep the stack aligned, and might as well use it to store the address being accessed
lea rax,[rbx+7f0]
mov [rsp+38],rax

...
lea r8,[rsp+30] //the addresses to RAX and RBX are at RSP+30

In another example by gibberishh, they pass the parameters in a more straightforward way, but I was not able to adapt the example to my case at all:
push 0 // Synchronous = 0, Async = 1.
push parameter // The parameter we want to pass to our function
push 1 // The number of parameters we are passing
push eax // The Id of the Lua function.
call CELUA_ExecuteFunctionByReference

When I tried running their code, I just kept getting crashes. Also when I tried just setting the parameters like this with just pushing them.

I can post the full code if it helps, but it's 90% the same as what Dark Byte posted here:

I can't post URLs yet, so you'll have to Google it for reference.

In summary, I need help with a few things:
1a) Am I passing the address of that pointer properly? If not, what is the best way to do it?
1b) Whatever I'm getting causes the game to crash when I try to read the value using readInteger(pointerAddress) in the lua function, so either I'm not passing it right or I'm not reading it right.
2a) How do I pass an address and an integer to the lua function using Dark Byte's template?
2b) Is there a more straight forward way to do it? It seems like there's a bunch of memory management issues that are currently over my head.

Bonus Question:

I tried to brute force it like this just to see if it would work:

//param1 and param2 don't do anything here, I just added them because the template sends two parameters and I wanted to catch them in case it causes problems when you don't.
function addMoney(param1,param2)
old_money = readInteger('[[[[[[["UnityPlayer.dll"+01994540]+08]+58]+48]+10]+58]+28]+E0')
new_money = old_money + 1000
writeInteger('[[[[[[["UnityPlayer.dll"+01994540]+08]+58]+48]+10]+58]+28]+E0',new_money)
end

This works fine in a pure lua script. However here, I can read and print the value correctly, but I can't change the value. It doesn't crash, but nothing changes. I'm guessing there's something in the way CELUA_ExecuteFunctionByReference works that requires an address to be explicitly passed in before you can change it?

Thanks for reading, I would appreciate any help.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4307

PostPosted: Thu Nov 23, 2023 2:00 am    Post subject: Reply with quote

Use code tags for writing blocks of code.

You should study x64 calling conventions before trying to call a function in assembly.

`mov rax,[[[[[[[[UnityPlayer.dll+01994540]+08]+58]+48]+10]+58]+28]+E0]` only traverses that path once when the script is assembled. You'd have to dereference each node individually in order to traverse it at runtime.

I didn't read the rest in detail. Post the full script not broken up into parts in code tags if you want help.

Do you know about {$luacode}?
https://forum.cheatengine.org/viewtopic.php?t=618134

Example using step 2 of the tutorial:
Code:
loadlibrary(luaclient-x86_64.dll)

[ENABLE]
aobscanmodule(Step2Write,Tutorial-x86_64.exe,29 83 F8 07 00 00)
alloc(newmem,$1000,Step2Write)

label(return)

newmem:
{$luacode ptr=rbx val=rax}
if readInteger(ptr+0x7F8) < 50 then
  val = -50
else
  val = val * 10
end
print(val, 'damage')
{$asm}
  sub [rbx+000007F8],eax
  jmp return

Step2Write:
  jmp newmem
  nop
return:
registersymbol(Step2Write)

[DISABLE]

Step2Write:
  db 29 83 F8 07 00 00

unregistersymbol(Step2Write)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: Tutorial-x86_64.exe+2B4BC

Tutorial-x86_64.exe+2B4AF: B9 05 00 00 00           - mov ecx,00000005
Tutorial-x86_64.exe+2B4B4: E8 57 47 FE FF           - call Tutorial-x86_64.exe+FC10
Tutorial-x86_64.exe+2B4B9: 83 C0 01                 - add eax,01
// ---------- INJECTING HERE ----------
Tutorial-x86_64.exe+2B4BC: 29 83 F8 07 00 00        - sub [rbx+000007F8],eax
// ---------- DONE INJECTING  ----------
Tutorial-x86_64.exe+2B4C2: 48 8D 4D F8              - lea rcx,[rbp-08]
Tutorial-x86_64.exe+2B4C6: E8 45 DA FD FF           - call Tutorial-x86_64.exe+8F10
Tutorial-x86_64.exe+2B4CB: 8B 8B F8 07 00 00        - mov ecx,[rbx+000007F8]
}

{$luacode} should only be used if you have something to do in CE. If it's something trivial like writing a value to an address, just do that in assembly. Something more complicated that doesn't need to do anything with CE can be done in C w/ {$ccode} (see previous link).

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

Joined: 22 Nov 2023
Posts: 5

PostPosted: Tue Nov 28, 2023 4:07 pm    Post subject: Reply with quote

Thanks for the reply. I ended going another way with what I was doing and more or less figured it out.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting 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