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 


Pausing the process when writing

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
cheat_me
Newbie cheater
Reputation: 0

Joined: 18 Aug 2012
Posts: 10

PostPosted: Wed Jun 17, 2015 11:26 pm    Post subject: Pausing the process when writing Reply with quote

When CE executes a cheat script with [ENABLE] / [DISABLE] sections, it overwrites machine instructions in the process memory. But does CE pauses the process during this overwrite? Because I am having a non persistent crash in a game at the moment the cheat is DISABLED. If the process is not paused, the game may try to execute that part of code which CE has not yet finished writing to. And therefore the code will be in a wrong state.
Back to top
View user's profile Send private message
Profound_Darkness
Newbie cheater
Reputation: 0

Joined: 21 May 2015
Posts: 23

PostPosted: Thu Jun 18, 2015 1:47 am    Post subject: Reply with quote

I was having something similar...

I don't actually know how CE does things, I suspect that it (somehow) keeps an eye on execution and if your memory isn't being executed CE will allow the dealloc (finishes disabling the cheat).

On the other hand it could just be coincidence that crashes aren't more common... The game, ideally, spends most of it's time outside of your code/injection area so if your code is taking longer to run and/or the sequence you overwrite with injection is executed FREQUENTLY the odds go up for a crash.

I had some code execution (call) to another script's memory that if I were in that other script/memory the return could (usually did) crash since the return pointed to null memory.

The first thing I tried, MUCH simpler, was to globalalloc... well most of the memory I was using. Same for memory with variables (symbols) that might need to get passed around. I didn't really like this...

I ended up writing a Lua script that was executed in the disable section. It wrote a 1 into memory (variable) that the asm code had access to and the lua code would sleep (blocking, repeat until) while waiting for that value to go to 0.

In the asm code at the end of any and all call chains or jumps I set the value of that variable to 0 (always).

Works like a charm.

If you end up going this route, error() in Lua will prevent the cheat from disabling. I mention this as it's a good idea to give up waiting after a while (due to bug in code or game is being debugged) otherwise CE will end up stuck (and it sucks if you haven't saved recently Wink ).

There could be some other possibilities for the crash, from my limited experience, but I don't know what was the cause exactly in those cases.

Edit:
Went ahead and posted an example of what I'm doing in Lua, it might have some bugs still...

I've tweaked the code from my original to operate entirely within a single script instead of spread out over multiple scripts... This is tweaked to be for just one script but it doesn't take much to make it work for multiple scripts/variables...

I didn't test the code as it is here...

(I was quite sleepy when I stripped out some elements, one of which was key, if someone else uses the code, this has the aspect added back in, not tested).

Code:

[ENABLE]
{$lua}
shutdownTryCount = 0
function scriptShutdown(leaveVar,jumpVar)
 local waitLimit = 100
 local waitInterval = 10
 -- multiply those together to get total wait time.
 if (readInteger(leaveVar) ~= 0) then
  error("Error with shutdown, another script is waiting?")
 end
 writeInteger(jumpVar,0)
 writeInteger(leaveVar,1)
 repeat
  shutdownTryCount = shutdownTryCount + 1
  if (shutdownTryCount > waitLimit) then
   writeInteger(leaveVar,0)
   shutdownTryCount = 0
   error("Error waiting on asm to clear variable, most oft seen while debugging.")
  end
  sleep(waitInterval)
 until (readInteger(leaveVar) == 0)
 shutdownTryCount = 0
end
{$asm}
// all the usual enable stuff...
alloc(mainMem)
label(dontWork)
label(returnhere)
label(dScriptShutdown)
registersymbol(dScriptShutdown)
label(dDoWork)
registersymbol(dDoWork)

mainMem:
cmp [dDoJump],0
je dontWork
// some code and stuff maybe with calls or jumps...
//end of the code just before going back to the game
dontWork:
mov [dScriptShutdown],0
jmp returnhere

//... inside some memory...
dScriptShutdown:
dd 0
dDoWork
dd 1

// whatever else you've got
[DISABLE]
{$lua}
scriptShutdown("dScriptShutdown","dDoWork")
{$asm}
// all the usual stuff like dealloc and unregistersymbol


Last edited by Profound_Darkness on Thu Jun 18, 2015 11:15 am; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 473

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

PostPosted: Thu Jun 18, 2015 2:48 am    Post subject: Reply with quote

aa scripts are written as blocks in the order they appear(while a block is written the game is locked/paused)

if the jump to newmem is above the newmem block, then first the jmp will be written, and a while later newmem will be filled.
That means that if you don't want to crash, put the implementation of newmem first (just like the code injection example)

_________________
Tools give you results. Knowledge gives you control.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
cheat_me
Newbie cheater
Reputation: 0

Joined: 18 Aug 2012
Posts: 10

PostPosted: Thu Jun 18, 2015 7:54 am    Post subject: Reply with quote

The crash occurs not when I enable but rather when I DISABLE the cheat. The code looks like this


Code:

[ENABLE]
globalalloc(god_mem,2048)
label(returnhere)

god_mem:
  test eax,eax
  //mov [esi+28],eax
  jmp returnhere

"game.exe"+18610C:
  jmp god_mem
returnhere:

[DISABLE]
"game.exe"+18610C:
  test eax,eax
  mov [esi+28],eax


In this script I skip the instruction that writes unit HP to memory. Sometimes when the game script has to kill a unit (by scenario) and cannot do it, it starts to run the Main Loop without the delay, so the CPU is at 100%, the game freezes and waits till the unit dies (which never occurs). When this happens I disable the cheat, and a CRASH occurs.
But when I rewrite my script into this
Code:

[ENABLE]
globalalloc(god_mem,2048)
label(returnhere)

god_mem:
  test eax,eax
  //mov [esi+28],eax
  jmp returnhere

"game.exe"+18610C:
  jmp god_mem
returnhere:

[DISABLE]
globalalloc(god_mem_disabled,2048)
label(returnhere)

god_mem_disabled:
  test eax,eax
  mov [esi+28],eax
  jmp returnhere

"game.exe"+18610C:
  jmp god_mem_disabled
returnhere:



The crash DOES NOT occur. The unit dies, the game unfreezes and runs normally.

So my guess was, that process is paused when writing each single instruction, and is not paused between writing multiple instructions. As you can see, in the first code in the DISABLE part I write 2 instructions. In the latter I write only JMP.
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 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