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 


destroying a thread created using createthread()

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> Auto Assembler tutorials
View previous topic :: View next topic  
Author Message
giniyat202
How do I cheat?
Reputation: 0

Joined: 17 Aug 2014
Posts: 1

PostPosted: Sun Aug 17, 2014 10:41 am    Post subject: destroying a thread created using createthread() Reply with quote

i had a problem while using createthread in a cheat table,
the thread was supposed to increase a specific value by 1 every second
and it was supposed to keep running until killed under [DISABLE]
but cheat engine has no destroythread so it was a problem,
until i came up with this solution and decided to post it here

Code:
[ENABLE]
    alloc(mythread,$1000)
    label(mythread_loop)
    label(mythread_req_end)
    createthread(mythread)
    registersymbol(mythread_req_end)

    mythread:
    //some initialization

    mythread_loop:
    //whatever

    cmp byte ptr [mythread_req_end], 0
    je mythread_loop

    //the thread is going to exit
    //do any cleanup here

    //free the memory and exit thread

    push 0                      //dwExitCode = 0
    call GetCurrentThread
    push eax                    //hThread = GetCurrentThread()
    push 0                      //return address = NULL

    push 8000                   //dwFreeType = MEM_RELEASE
    push 0                      //dwSize = 0
    push mythread               //dwAddress = mythread
    push TerminateThread        //return address = TerminateThread
    jmp VirtualFree

    mythread_req_end:
    db 0

[DISABLE]
    mythread_req_end:
    dd 1

    unregistersymbol(mythread_req_end)


note that you must not free the memory used by the thread under disable, and the thread free its own memory itself

i have tested only on 32 bit, if anyone can port it to 64 bit
please tell me since i have no knowledge of x64 assembly.
Back to top
View user's profile Send private message
Nemexia55
Expert Cheater
Reputation: 0

Joined: 28 Jan 2014
Posts: 159

PostPosted: Sat Dec 20, 2014 1:51 pm    Post subject: Reply with quote

excuse me, i couldn't find my answer anywhere,
what is a thread?

_________________
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 344

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

PostPosted: Sat Dec 20, 2014 2:29 pm    Post subject: Reply with quote

You can see a thread as something the cpu is currently executing, separate from the main code

As for the original poster, if you leave the stack intact (restore it) when you call ret it will automatically call the TerminateThread function, as that function is stored at the top of the stack when the thread starts

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Back to top
View user's profile Send private message MSN Messenger
ZxPwds
Newbie cheater
Reputation: 0

Joined: 27 Oct 2015
Posts: 20

PostPosted: Thu Oct 29, 2015 8:45 pm    Post subject: Reply with quote

Thank you Dark Byte I was looking for this!
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 148

Joined: 07 Nov 2008
Posts: 4190
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sun Nov 29, 2015 10:48 am    Post subject: Reply with quote

My 64bit implementation (kind of alpha version):


Code:
[ENABLE]
createThread(selfFreeingThread)
alloc(selfFreeingThread,2048)
label(mainLoop)
label(exitMyThread)
label(freeTheThread)

label(havetoquit)
registersymbol(havetoquit)
label(counter)
registersymbol(counter)


selfFreeingThread:
  mov rax,selfFreeingThread
  push rax //push base address of the region of pages to be freed
  mov rax,VirtualFree
  push rax //push VirtualFree address

  sub rsp,28

mainLoop:
  mov rcx,#500
  call Sleep

  and byte ptr [havetoquit],01
  jnz exitMyThread

  inc [counter]
  jmp mainLoop


exitMyThread:
  add rsp,28
  jmp freeTheThread

havetoquit:
db 00

counter:
dd 0



selfFreeingThread+800:
freeTheThread:
mov rbp,rsp
sub rsp,40 // room for code and calls (remember pushes at the very beginning)

lea rcx,[rsp+20]
mov rdx,00000020
mov r8d,40
lea r9,[rsp+18]
mov rax,VirtualProtect     // make stack executable
call rax

// place the rest on stack
mov [rsp+20],084D8B48                   // mov rcx,[rbp+08]    // address
mov [rsp+24],41D23148                   // xor rdx,rdx         // size
mov [rsp+28],008000B8                   // mov r8d,00008000    // MEM_RELEASE
mov [rsp+2c],0055FF00                   // call [rbp+00]       // VirtualFree
mov [rsp+30],50C48348                   // add rsp,50          //
mov [rsp+34],000000C3                   // ret
lea rcx,[rsp+20]
jmp rcx

[DISABLE]
havetoquit:
db 01

unregistersymbol(havetoquit)
unregistersymbol(counter)














My 32bit implementation (also alpha version):
Code:
[ENABLE]
createThread(selfFreeingThread)
alloc(selfFreeingThread,2048)
label(mainLoop)
label(exitMyThread)
label(freeTheThread)

label(havetoquit)
registersymbol(havetoquit)
label(counter)
registersymbol(counter)


selfFreeingThread:
  push selfFreeingThread  // base address of the region of pages to be freed

mainLoop:
  push #500
  call Sleep

  and byte ptr [havetoquit],01
  jnz exitMyThread

  inc [counter]
  jmp mainLoop

exitMyThread:
  jmp freeTheThread

havetoquit:
db 00

counter:
dd 0

freeTheThread:
mov ebp,esp
sub esp,04

push esp
push 40
push 8
push esp
call VirtualProtect     // make stack executable

// place "add esp,08 ; ret" code in stack
mov [esp],C308C483

push 00008000     //MEM_RELEASE
push 0            //size
push [ebp+00]     //address
lea eax,[ebp-04]
push eax
jmp VirtualFree


[DISABLE]
havetoquit:
db 01

unregistersymbol(havetoquit)
unregistersymbol(counter)



selfFreeingThread.CT
 Description:
demo,
attach 64bit CE to any 64bit process, then enable/disable the script.

counter should increase every 0.5s

Download
 Filename:  selfFreeingThread.CT
 Filesize:  2.22 KB
 Downloaded:  765 Time(s)


_________________
Back to top
View user's profile Send private message MSN Messenger
ParkourPenguin
Grandmaster Cheater Supreme
Reputation: 55

Joined: 06 Jul 2014
Posts: 1824
Location: Arcadian Suburbia

PostPosted: Thu Dec 24, 2015 6:35 pm    Post subject: Reply with quote

I'm guessing using ret is the correct way of terminating the thread, but what's the difference between calling TerminateThread yourself and letting the script ret on its own?
_________________
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
Dark Byte
Site Admin
Reputation: 344

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

PostPosted: Thu Dec 24, 2015 7:18 pm    Post subject: Reply with quote

a thread's ret will bring it's instruction pointer to a "call RtlExitUserThread" (with eax being it's parameter)

TerminateThread is a bit more forceful but has basically the same effect

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Back to top
View user's profile Send private message MSN Messenger
mgr.inz.Player
I post too much
Reputation: 148

Joined: 07 Nov 2008
Posts: 4190
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Thu Dec 24, 2015 7:36 pm    Post subject: Reply with quote

I'm guessing that there's no big difference.

giniyat202 called TerminateThread (and GetCurrentThread ) and probably he didn't want to go back to the original caller.

Lets analyse his code:
Code:
    push 0                      //dwExitCode = 0
    call GetCurrentThread
    push eax                    //hThread = GetCurrentThread()
    push 0                      //return address = NULL

    push 8000                   //dwFreeType = MEM_RELEASE
    push 0                      //dwSize = 0
    push mythread               //dwAddress = mythread
    push TerminateThread        //return address = TerminateThread
    jmp VirtualFree



When we stop at jmp, the stack will be:
Code:
retA |  TerminateThreadAddress
     |  ourThreadAddress
     |  0
     |  MEM_RELEASE
     |  0
     |  hOurThread
     |  0




Then we jump to the VirtualFree function. Jump instead of call. (CPU stack not changed)

So, VirtualFree function will take arguments (ourThreadAddress,0,MEM_RELEASE) and free memory at address ourThreadAddress.

Because it was a jump, it will RET to TerminateThread. Note, RET is also a jump, it just pops one value (ret address) from the stack. Callee also removes arguments from the stack.

At the very beginning of TerminateThread, the stack will be

Code:
retA |  0
     |  hOurThread
     |  0



TerminateThread will take (hOurThread, 0), handle and ExitCode. And from what I see it doesn't ret to the original caller. Ret address is zero, but, it doesn't crash. So, TerminateThread doesn't have RET at the end. It will call other function and pass ExitCode value.






My approach is slightly different. Some tricks won't work in 64bit application. So, I move code execution to the stack, free the memory, and ret to the original caller. I made it for 64bit first, and I converted that code to 32bit version too.

_________________
Back to top
View user's profile Send private message MSN Messenger
ParkourPenguin
Grandmaster Cheater Supreme
Reputation: 55

Joined: 06 Jul 2014
Posts: 1824
Location: Arcadian Suburbia

PostPosted: Thu Dec 24, 2015 8:46 pm    Post subject: Reply with quote

Thank you both very much.
I tried to do a bit of research on RtlExitUserThread and found the parameter is an NTSTATUS. Should I make sure eax is 0 just before the ret, or does it really matter what parameter I pass it?

_________________
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
mgr.inz.Player
I post too much
Reputation: 148

Joined: 07 Nov 2008
Posts: 4190
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Thu Dec 24, 2015 9:53 pm    Post subject: Reply with quote

part of CE code:
Code:
            try
              threadhandle:=createremotethread(processhandle,nil,0,pointer(testptr),nil,0,bw);
              ok2:=threadhandle>0;

              if ok2 then
                closehandle(threadhandle);
            finally
            end;


I don't see getexitcodethread there. Looks like it doesn't matter.

_________________
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials -> Auto Assembler tutorials 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