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 can this script disable itself after 1 usage?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
Autem
Expert Cheater
Reputation: 1

Joined: 30 Jan 2023
Posts: 119

PostPosted: Tue May 23, 2023 7:09 pm    Post subject: How can this script disable itself after 1 usage? Reply with quote

I'd like the below script to disable itself and revert everything back to normal as soon as ONE instance runs through the modified/enabled newmem section. Whether it takes 1 hour of being activated or just 3 seconds, I only want the script to basically wait until it's used 1 time and then disable itself immediately to avoid any possible follow up data being influenced.

I've tried a few variations on how I think it's possible to call lua inline with asm but it's not working. How should I write the part that force disables everything after 1 usage?

Code:
[ENABLE]
aobscanmodule(INJECT,WWE2K23_x64.exe,C5 F8 2F 73 34) // should be unique
alloc(newmem,$1000,INJECT)
label(code)
label(return)

newmem:
mov [rbx+34],(float)0.0
vcomiss xmm6,[rbx+34]

code:
db C5 F8 2F 73 34   //My attempt to return the bytes to normal myself before auto disable
Luacall(memrec.Active=false)  //My attempt to auto self disable and then unregister/dealloc below
unregistersymbol(INJECT) 
dealloc(newmem)
jmp return

INJECT:
  jmp newmem
return:
registersymbol(INJECT)

[DISABLE]
INJECT:
  db C5 F8 2F 73 34

unregistersymbol(INJECT)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: WWE2K23_x64.exe+C9404C

WWE2K23_x64.exe+C9401C: C5 FA 5E 43 30           - vdivss xmm0,xmm0,[rbx+30]
WWE2K23_x64.exe+C94021: C5 FA 11 4B 34           - vmovss [rbx+34],xmm1
WWE2K23_x64.exe+C94026: E8 B5 82 60 FF           - call WWE2K23_x64.AK::SoundEngine::StartProfilerCapture+3340
WWE2K23_x64.exe+C9402B: C5 F8 28 D0              - vmovaps xmm2,xmm0
WWE2K23_x64.exe+C9402F: C5 F8 57 C0              - vxorps xmm0,xmm0,xmm0
WWE2K23_x64.exe+C94033: C5 FA 10 CA              - vmovss xmm1,xmm0,xmm2
WWE2K23_x64.exe+C94037: C5 E0 57 DB              - vxorps xmm3,xmm3,xmm3
WWE2K23_x64.exe+C9403B: C5 F2 5F CB              - vmaxss xmm1,xmm1,xmm3
WWE2K23_x64.exe+C9403F: C5 F2 5D 0D 8D 22 59 02  - vminss xmm1,xmm1,[WWE2K23_x64.exe+32262D4]
WWE2K23_x64.exe+C94047: C5 FA 11 4B 60           - vmovss [rbx+60],xmm1
// ---------- INJECTING HERE ----------
WWE2K23_x64.exe+C9404C: C5 F8 2F 73 34           - vcomiss xmm6,[rbx+34]
// ---------- DONE INJECTING  ----------
WWE2K23_x64.exe+C94051: C5 F8 28 74 24 20        - vmovaps xmm6,[rsp+20]
WWE2K23_x64.exe+C94057: 48 8B 7C 24 40           - mov rdi,[rsp+40]
WWE2K23_x64.exe+C9405C: 72 12                    - jb WWE2K23_x64.exe+C94070
WWE2K23_x64.exe+C9405E: 48 8B 03                 - mov rax,[rbx]
WWE2K23_x64.exe+C94061: 48 8B CB                 - mov rcx,rbx
WWE2K23_x64.exe+C94064: 48 83 C4 30              - add rsp,30
WWE2K23_x64.exe+C94068: 5B                       - pop rbx
WWE2K23_x64.exe+C94069: 48 FF A0 98 00 00 00     - jmp qword ptr [rax+00000098]
WWE2K23_x64.exe+C94070: 48 83 C4 30              - add rsp,30
WWE2K23_x64.exe+C94074: 5B                       - pop rbx
}
Back to top
View user's profile Send private message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Tue May 23, 2023 7:36 pm    Post subject: Reply with quote

You can use lua, or you can simply create a boolean that resets to 0 after you enable it.

Code:

//stuff

label(trigger)
registersymbol(trigger)

newmem:
cmp byte ptr [trigger],1
je code
jmp originalcode

code:
mov byte ptr [trigger],0
//manipulation code

//stuff

trigger:
db 0

//stuff


Then set up the cheat so that when it activates, it sets the trigger value to 1.

You can manually add an address inside of your cheat table, with trigger as the address, then change data type to byte. Assign a hotkey to set value to 1.
Back to top
View user's profile Send private message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Tue May 23, 2023 8:07 pm    Post subject: Reply with quote

I'd just use LUA, condition the jump from executing the newcode on whether a flag is set, set the flag within the newcode, and have the script erase everything once the flag is set, too.

newcode:
cmp [flag], 1
je skip
//Code you want to execute once
mov [flag], 1
skip:
//Originalcode


Then have the timer the LUA code set up check the flag as well and write over the jump, clean out the code cave, reset the flag, and turn off the timer that is checking on the flag.

If it has to be in AA, it would be interesting to try:
push eax
mov eax, 0xC5F82F7334 //Note: bytes may be out of order
mov [INJECT], eax //Note: making this up
pop eax
return

I have never attempted this so I would be surprised if it did work. It won't clean up the code cave and you may not have to register any symbols since you only are using them once and you may be able to overwrite all the preceding instructions of the code cave with the last write. So there would be evidence left, but not evidence of what was done or where it was done, just some stray lines of code seeming to reference itself. You will introduce a memory leak if this runs multiple times.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4291

PostPosted: Tue May 23, 2023 8:11 pm    Post subject: Reply with quote

You're looking for {$luacode}, but that's a terrible idea. The disable section deallocates newmem. What do you think happens if the {$luacode} block returns to memory that's been deallocated?

Everything between the `code:` label and `jmp newmem` shouldn't be there. I think I see what you're trying to do, and the AutoAssembler doesn't work that way.

I'd use a breakpoint.
Code:
{$lua}
if syntaxcheck then return end

local injectAddr = getAddress'WWE2K23_x64.exe+C9404C'

[ENABLE]

debug_setBreakpoint(injectAddr, function()
  writeFloat(RBX+0x34, 0)
  createTimer(100, function() memrec.Active = false end)
  debug_removeBreakpoint(injectAddr)
  debug_continueFromBreakpoint(co_run)
end)

[DISABLE]

debug_removeBreakpoint(injectAddr)

If you really want to use a code injection, look into the various existing solutions for running code only once. Simply using a flag should suffice. (use cmpxchg if you want to be technically correct in a multithreaded context)

_________________
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
Autem
Expert Cheater
Reputation: 1

Joined: 30 Jan 2023
Posts: 119

PostPosted: Tue May 23, 2023 9:13 pm    Post subject: Reply with quote

The boolean trigger idea from Methos seems to be working in my early trials. Thanks for the idea.

I wonder tho if a breakpoint like Penguin suggests would actually be better as far as eliminating any slim chance of more than 1 execution sneaking thru at the same time? Or would the result be identical either way?

ParkourPenguin wrote:
The disable section deallocates newmem.


The reason I put them there is I thought when using memrec.Active=false it would mean the 'disable' part of a script doesn't get executed, meaning I should include those db restoration and dealloc steps if I were going to be using memrec.Active=false?
Back to top
View user's profile Send private message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Tue May 23, 2023 9:54 pm    Post subject: Reply with quote

Autem wrote:
as far as eliminating any slim chance of more than 1 execution sneaking thru at the same time?
-As far as I understand, that shouldn't happen unless you erroneously initiate the trigger more than once via hotkey or similar. Hopefully, someone can correct me if I am wrong.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4291

PostPosted: Wed May 24, 2023 12:26 am    Post subject: This post has 1 review(s) Reply with quote

Technically speaking, there would be a race condition between the `cmp` and the `mov`. If thread1 executes the `cmp`, gets preempted before the `mov`, and thread2 executes the `cmp`, then both thread1 and thread2 will run the code that was only suppose to be run once.

This is a common problem in concurrent systems. If you want to know more about concurrency, I'd recommend "C++ Concurrency in Action" by Anthony Williams. It's a little dated for C++, but there's still a lot to be learned from it.

The odds of this happening in practice are negligible. It's probably single-threaded, and even if it isn't, it might happen once in several billion times.

_________________
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
wayden
Cheater
Reputation: 0

Joined: 09 Dec 2020
Posts: 27

PostPosted: Fri Jul 14, 2023 5:30 am    Post subject: Reply with quote

I use a way following your first idea, reseting bytes before disabling
and a bit of lua to auto disable, im not sure if it's a good way to do it but it seems to work
for that i got 2 scripts

-one main containing my reset function and allocating memory for itself and any other script that i would want to inject at the same InjectionPoint
and for the "variable" used to store the ResetBytes + regestering symbols

-And the other one containing the actual scipts i want to run only once



The main one looks something like this
Code:


[ENABLE]
alloc(DevMods,$1000) //i removed third parameter because i don't really get what it is used for and it sometimes causes warning

define(FT_ResetFunc,DevMods+08) //manually choose where you register your code you have to take care to not overwrite your own code
define(RB_ResetFunc,DevMods+2D)
define(FT_GiveItem,DevMods+3C)

registersymbol(DevMods)
registersymbol(FT_ResetFunc)
registersymbol(RB_ResetFunc)

registersymbol(InjectionPoint)
define(InjectionPoint,GameHandler:UpdateFrame+50c)

registersymbol(FT_GiveItem)

RB_ResetFunc:
  db 66 0F 1F 84 00 00 00 00 00

FT_ResetFunc:
  push rax //save rax
  mov rax, qword ptr[RB_ResetFunc] //moves the reset bytes into rax
  mov qword [InjectionPoint], rax  //moves reset bytes at the injection point (equivalent to being at injection point and doing db 66 0F 1F 84 00 00 00 00 00)
  pop rax //restore rax
  jmp InjectionPoint

[DISABLE]
  unregistersymbol(InjectionPoint)
  unregistersymbol(FT_ResetFunc)
  unregistersymbol(RB_ResetFunc)
  unregistersymbol(FT_GiveItem)
  dealloc(DevMods)



The Actual Script that i want to run only once :


Code:

{$lua}
  if not syntaxcheck then
   synchronize(createTimer,50,memrec.setActive,false) //waits 50ms before disabling script
  end
{$asm}


[ENABLE]

FT_GiveItem:
  mov rcx,rsi
  lea rbp,[rbp]
  mov r11,GameHandler:GiveItems    //do your thing
  call r11
  jmp FT_ResetFunc     //call the reset Function

InjectionPoint: //it's the injection point declared in the main script
  jmp FT_GiveItem

[DISABLE]

//nothing happens on disable because everything it's managed from main script and bytes are already reseted



i like this way because i don't have to alloc memory for each one of my scripts just got a main one where i can manage manually where they are stored in the main scripts memory
and it doesn't use any flags so the entry in cheat table list is really disabled and there is no cmp to do and if you have mutiple script that you want to run only once you can inject them at the exact same point and just jmp to the resetfunction
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