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 


Why is "call sleep" never ending

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 2:13 am    Post subject: Why is "call sleep" never ending Reply with quote

Upon activation, the code runs flawlessly, but the sleep never ends

Please assist me in figuring out why the sleep lasts forever (sleep is one of the last lines of code, approximately 10 lines from bottom)

if I remove the push and sleep, the code loops correctly

Code:
[enable]
alloc(UpgradeShip,4096)
label(notToday)
label(Loop1)
label(Loop2)
CREATETHREAD(UpgradeShip);

UpgradeShip:
mov eax, [myShip]
cmp eax, [lastShip]
je notToday //Has the ship identifier changed
mov [lastShip], eax //Set myShip into last ship to prevent running code too frequently

mov eax, [myShip]//[[[[["myShip"+40]+40]+68]+10]+18] for counter value
add eax, 40
mov eax, [eax]
mov eax, [eax+40]
mov eax, [eax+68]
mov [aItem], eax //Store the current Item List pointer
mov eax, [eax+18] //Number of parts, save this value
mov [CountToValue], eax
mov [CounterValue], 20
Loop1: //We need to loop until CountToValue is 0
dec [CountToValue]
mov eax, [aItem]
add eax, [CounterValue]
mov eax, [eax]
mov eax, [eax+28]
mov eax, [eax+20] //access mysubsystems (aka base values)
or eax,eax
je notToday //Test pointer before writing
mov [eax+20], 1 //Set weight to 1
mov [eax+24], 0 //Set health to 0
mov [eax+28], 0 //Set armor to 0
mov [eax+2c], 0 //Set shield to 0
mov [eax+30], 0 //Set rotate to 0
mov [eax+34], 0 //Set speed to 0
mov [eax+38], 0 //Set reactor to 0
mov [eax+3c], 0 //Set capacitor to 0
mov eax, [aItem]
add eax, [CounterValue]
mov eax, [eax]
mov eax, [eax+28]
mov eax, [eax+28] //access myBoosts (aka bonus values)
or eax,eax
je notToday //Test pointer before writing
mov [eax+20], 0 //Set Bonus weight to 0
mov [eax+24], (int)1000 //Set Bonus health to 1000*perkbonus
mov [eax+28], (int)1000 //Set Bonus armor to 1000*perkbonus
mov [eax+2c], (int)1000 //Set Bonus shield to 1000*perkbonus
mov [eax+30], (int)10 //Set Bonus rotate to 10
mov [eax+34], (int)20 //Set Bonus speed to 20
mov [eax+38], (int)1000 //Set Bonus reactor to 1000*perkbonus
mov [eax+3c], (int)1000 //Set Bonus capacitor to 1000*perkbonus
add [CounterValue], 8
cmp [CountToValue], 0 //While Items are still in the list, increment the item pointer value and decrement the counter
jg Loop1
//At this point, every attachment should be upgraded
//Now to do weapons
mov eax, [myShip]//[[[[["myShip"+40]+40]+68]+10]+18] for counter value
add eax, 40
mov eax, [eax]
mov eax, [eax+B8]
mov eax, [eax+10]
mov [aItem], eax //Store the current Item List pointer
mov eax, [eax+18] //Number of parts, save this value
mov [CountToValue], eax
mov [CounterValue], 20
Loop2: //We need to loop until CountToValue is 0
dec [CountToValue]
mov eax, [aItem]
add eax, [CounterValue]
mov eax, [eax]
mov eax, [eax+20]
mov eax, [eax+20] //access Item[2] (Emitter, Missile, or Projectile Weapons) (aka base values)
or eax,eax
je notToday //Test pointer before writing
mov [eax+7c], 10 //Set Burst to 10
mov [eax+78], (float)0.1 //Set Reload Time to .1s
mov [eax+90], (float)9999999 //Set Damage per shot to 10 million -1
mov [eax+bc], (float)20 //Set damage multiplier to 20
add [CounterValue], 8
cmp [CountToValue], 0 //While Items are still in the list, increment the item pointer value and decrement the counter
jg Loop2

notToday:
push #3000
call sleep
cmp [EndToggle],1
jne UpgradeShip
ret

EndToggle:
dd 0

[disable]
EndToggle:
dd 1
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Mon Jun 06, 2016 3:54 am    Post subject: Reply with quote

try call kernel32.sleep

perhaps there is an other dll loaded that implements sleep as well but then on a second based implementation

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 9:35 am    Post subject: Reply with quote

I tried calling kernel32.sleep, I also tried changing the #3000 to #500 and #3, nothing worked. The sleep still never ends.

Any other advise?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Mon Jun 06, 2016 10:11 am    Post subject: Reply with quote

Set a breakpoint at call kernel32.Sleep, wait for it to break, and post the values of all the registers and what the first few values on the top of the stack are (right click bottom-right window -> full stack). Step over the call (debug -> Step Over) and see what happens. If it breaks at the next instruction, post anything that changed.
_________________
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
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 11:07 am    Post subject: Reply with quote

Here is the pre, at, post breakpoint:

PreSleep


At Sleep


PostSleep
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Mon Jun 06, 2016 11:21 am    Post subject: This post has 1 review(s) Reply with quote

That's a 64-bit process. First of all, you should be using the 64-bit registers when referring to a memory location, but CE should correct that automatically for you.

More importantly, the reason why it's not working the way you want is that x64 has different calling conventions than x86.
Quote:
  • RAX = return value register
  • RCX = first integer argument
  • RDX = second integer argument
  • R8 = third integer argument
  • R9 = fourth integer argument
  • ...
reference

Also, you will need to give it 32 bytes of scratch space on the stack before you call it. If you don't do this, that call will overwrite the return address of this thread.
Quote:
The caller is responsible for allocating space for parameters to the callee, and must always allocate sufficient space for the 4 register parameters, even if the callee doesn’t have that many parameters.
reference

So, have sub rsp,20 at the beginning of your code, have add rsp,20 at the end (just before the ret), and call kernel32.Sleep by moving BB8 into ecx (upper 32 bits of rcx aren't used by kernel32.Sleep) just before the call.

_________________
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
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Mon Jun 06, 2016 11:27 am    Post subject: Reply with quote

ParkourPenguin wrote:
call kernel32.Sleep by moving BB8 into ecx
-RCX can be used...but I haven't checked to see if CE corrects this upon activation.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Mon Jun 06, 2016 11:33 am    Post subject: Reply with quote

It really shouldn't make any difference functionally. I only use the 32-bit variant because that takes up less memory.
Code:
48 B9 B80B000000000000 - mov rcx,0000000000000BB8 { 3000 }
// compared to:
B9 B80B0000            - mov ecx,00000BB8 { 3000 }

_________________
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
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Mon Jun 06, 2016 11:35 am    Post subject: Reply with quote

That's true. Very Happy
Back to top
View user's profile Send private message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 11:39 am    Post subject: Reply with quote

Great!

I didn't realize that sleep had different conventions between x86 and x64.
When I googled sleep on cheatengine, all of the examples were in x86 but never mentioned an alternative.

Adding the stack reservation and moving to ecx did the trick!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Mon Jun 06, 2016 11:46 am    Post subject: Reply with quote

That's not just for sleep. Any call you make should be done this way (by convention).

For example, here's how you'd call VirtualFree to free that memory:
Code:
mov rcx,UpgradeShip
xor rdx,rdx
mov r8d,8000
call kernel32.VirtualFree

_________________
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
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 1:08 pm    Post subject: Reply with quote

would that be added into the disable section?

Every example of createthread, indicated that you couldnt dealloc the memory, so I just left it in the game's memory.

For completeness, I would love to 'dealloc' the memory, and if that is how to do so, I'll add it into the disable section.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Mon Jun 06, 2016 1:19 pm    Post subject: Reply with quote

The reason why you shouldn't deallocate the memory if the thread is still running is that it'll cause the thread to try to execute freed memory, resulting in the process crashing. To solve this, make the thread deallocate its own memory and have it return to where it'll be properly destroyed.

Here's a short example which freezes a value (address is mythreadKill-4) to 5000 when it's enabled and deallocates itself when disabled.
Code:
[ENABLE]
alloc(mythread,2048,kernel32.dll)
label(value)
label(mythreadKill)
registersymbol(mythreadKill)

createthread(mythread)

mythread:
  sub rsp,20
@@:
  mov dword ptr[value],#5000
  mov ecx,#500
  call kernel32.Sleep
  mov al,[mythreadKill]
  test al,al
  jz short @b
// dealloc and kill thread
  add rsp,20
  mov rcx,mythread
  xor rdx,rdx
  mov r8d,8000
  jmp kernel32.VirtualFree   // return address of this thread is on the top of the stack, so kernel32.VirtualFree will actually return to that (not this memory)
  db CC CC CC CC
value:
  dd 0
mythreadKill:
  db 0

[DISABLE]
mythreadKill:
  db 1
unregistersymbol(mythreadKill)

_________________
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
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