News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

thread TerminateThread and SECURITY_DESCRIPTOR

Started by TouEnMasm, September 02, 2014, 05:38:17 PM

Previous topic - Next topic

TouEnMasm


Msdn say that TerminateThread need THREAD_TERMINATE as flag in a SECURITY_DESCRIPTOR structure to work.
The function is usefull to interrupt a thread.
I had tried to use the structure like that


.data
securdesc SECURITY_DESCRIPTOR<>
securththread SECURITY_ATTRIBUTES  <sizeof SECURITY_ATTRIBUTES,securdesc,NULL>
pSecurityDescriptor dd securdesc

.code

invoke InitializeSecurityDescriptor,pSecurityDescriptor,SECURITY_DESCRIPTOR_REVISION   ; SECURITY_DESCRIPTOR
; SECURITY_DESCRIPTOR all access pDacl = NULL
invoke SetSecurityDescriptorDacl,pSecurityDescriptor,NULL,NULL,TRUE
;------------
;addr securththread
;creation of thread failed
invoke CreateThread,addr securththread,NULL,Thread_BoucleTraduction,HwndProc,NULL,addr thread.threadid
mov thread.Htread,eax
;------------------
;The thread is in an infinite loop
invoke TerminateThread,thread.Htread,NULL ;need THREAD_TERMINATE flag

The functions works but CreateThread failed ( addr securththread is n good)
Is there any sample on how to use it.





Fa is a musical note to play with CL

fearless

If you call it without the security info:
invoke CreateThread,NULL,NULL,Thread_BoucleTraduction,HwndProc,NULL,addr thread.threadid
it should have THREAD_ALL_ACCESS by default which includes THREAD_TERMINATE, the documentation on TerminateThread also indicates this i think:

QuoteThe thread handle returned by the CreateThread and CreateProcess functions has THREAD_TERMINATE access, so any caller holding one of these handles can terminate your thread.

Also if your going to use the TerminateThread function, and most documention ive read on it says really dont:

QuoteIf the thread is created in a runnable state (that is, if the CREATE_SUSPENDED flag is not used), the thread can start running before CreateThread returns and, in particular, before the caller receives the handle and identifier of the created thread.

so maybe:

invoke CreateThread,NULL,NULL,Thread_BoucleTraduction,HwndProc,CREATE_SUSPENDED,addr thread.threadid
mov thread.Htread,eax
Invoke ResumeThread, thread.Htread
invoke TerminateThread,thread.Htread,NULL


Even then, most blogs and other comments suggest that you set some flag somewhere, so that in your thread you bow out gracefully as it could cause problems just terminating it. Could put a variable like in your thread structure (thread.AbortThreadFlag maybe?) and if its set you stop processing somewhere, giving you a chance to cleanup stuff.

MtheK

FYI,

  I do something similar for CreateProcess:

SECATTR            EQU   THIS BYTE
SECATTRL           DWORD ?
SECATTRA           DWORD ?
SECATTRI           DWORD 0

         INVOKE InitializeSecurityDescriptor,
               OFFSET SECDESC,               ; 4K-aligned
               SECURITY_DESCRIPTOR_REVISION
.if eax == 0
         JMP   BADINITSECDESC
.else
         INVOKE SetSecurityDescriptorDacl,
               OFFSET SECDESC,
               TRUE,
               NULL,               ; null DACL allows everyone full access
               0
  .if eax == 0
         JMP   BADSETSECDESC
  .endif   
.endif
         MOV   SECATTRL,12
         MOV   SECATTRA,OFFSET SECDESC

...

         INVOKE CreateProcess,
                       OFFSET PATHEXTO,
                       OFFSET PROGRAMPID,
                       OFFSET SECATTR,       
                       OFFSET SECATTR,
                       FALSE,
                       CREATEFLG,
                       NULL,
                       NULL,
                       OFFSET STARTINFO,
                       OFFSET RETINFO

I am able to TerminateProcess it successfully.

  Also, in the OS-created thread for SetConsoleCtrlHandler,
I "spinlock" a flag that the main thread constantly checks in
loops, after SLEEPs (min 15ms allowed to help defeat the
force-killer @ PowerOff), etc to decide whether to exit or not.
That seems to work well, such as during Ctrl-C, shutdown, etc.


TouEnMasm

Here a real case who don't work.
I don't see what is wrong
He must display a counter
Fa is a musical note to play with CL

qWord

It does count somehow on my machine, but there are several problems:
- using global variables will only work for one thread
- the created threads receives a pointer to a local variable, which might no longer exist when the thread is executed
- not surprisingly, terminating the threads cause a handle leak

I strongly suggest you to omit TerminateThread().
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

i try not to use TerminateThread

rather, set up a semaphore and use ExitThread, as fearless suggested
i usually make my own semaphore using XCHG AL,byte (LOCK is implied)
but, there are API functions, as well

http://msdn.microsoft.com/en-us/library/windows/desktop/ms685129%28v=vs.85%29.aspx

TouEnMasm

Here the end test,I can start and stop the thread without put Windbg on the trouble.
The stack adress passed in parameter was just a test.
Try this one on your system,There is no reason to have a problem.
I have not solved the problem on how change the Dacl.
Semaphore ?,perhaps a sample.
The advantage of TerminateThread is that he allow to interrupt a thread.
Fa is a musical note to play with CL

qWord

Quote from: ToutEnMasm on September 03, 2014, 03:29:56 AMThe advantage of TerminateThread is that he allow to interrupt a thread.
There is no advantage in using this function. It does destroy the thread regardless in which state the thread is. If there are resources allocated by the thread-code, they are not freed.
IMO using this function is an indication for a bad software design.
MREAL macros - when you need floating point arithmetic while assembling!

Zen

TOUTENMASM,
This information is from: Windows Via C/C++, 2008, by Jeffrey Richter and Christophe Nasarre.

Terminating a Thread: A thread can be terminated in four ways:

  • The thread function returns. (This is highly recommended.)
  • The thread kills itself by calling the ExitThread function. (Avoid this method.)
  • A thread in the same process or in another one calls the TerminateThread function. (Avoid this method.)
  • The process containing the thread terminates. (Avoid this method.)
The TerminateThread Function: A call to TerminateThread kills a thread:

BOOL TerminateThread(
HANDLE hThread,
DWORD dwExitCode);


"Unlike ExitThread, which always kills the calling thread, TerminateThread can kill any thread. The hThread parameter identifies the handle of the thread to be terminated. When the thread terminates, its exit code becomes the value you passed as the dwExitCode parameter. Also, the thread's kernel object has its usage count decremented.
Note The TerminateThread function is asynchronous. That is, it tells the system that you want the thread to terminate but the thread is not guaranteed to be killed by the time the function returns. If you need to know for sure that the thread has terminated, you might want to call WaitForSingleObject or a similar function, passing the handle of the thread.
A well-designed application never uses this function because the thread being terminated receives no notification that it is dying. The thread cannot clean up properly, and it cannot prevent itself from being killed.
Note When a thread dies by returning (the Thread Function) or calling ExitThread, the stack for the thread is destroyed. However, if TerminateThread is used, the system does not destroy the thread's stack until the process that owned the thread terminates. Microsoft purposely implemented
TerminateThread in this way. If other still-executing threads were to reference values on the forcibly killed thread's stack, these other threads would raise access violations. By leaving the killed thread's stack in memory, other threads can continue to execute just fine.
In addition, dynamic-link libraries (DLLs) usually receive notifications when a thread is terminating. If a thread is forcibly killed with TerminateThread, however, the DLLs do not receive this notification, which can prevent proper cleanup."

The authors then have a long section on Thread Internals (which is pretty interesting). They then conclude that section with this statement:
"To create a new thread, you must not call the operating system's CreateThread function—you must call the C/C++ run-time library function _beginthreadex."  There is a long section that describes what exactly is happening when you initialize a thread with  _beginthreadex, but, essentially, it creates a number of data structures that CreateThread does not.

qWord

Zen,
calling ExitThread is the same as returning from the thread function and thus also "highly recommended".
MREAL macros - when you need floating point arithmetic while assembling!

Zen

I think so. I'm just quoting the authors. And, the book is written for C/C++ programmers. They have their reasons for making that recommendation,...and, it involves the thread clean-up (of C++ class objects).
"The ExitThread function is the Windows function that kills a thread."

TouEnMasm

I agree that it is not a normal way to quit a thread.
The case is what did you do when your thread is in an unpredictable infinite loop  ?.
answer,you use it,no other choice.
Fa is a musical note to play with CL

qWord

Quote from: Zen on September 03, 2014, 05:54:39 AMThey have their reasons for making that recommendation,...and, it involves the thread clean-up (of C++ class objects).
that is true when using a multithreading library in c++, but not when doing plain WinAPI programming.

Quote from: ToutEnMasm on September 03, 2014, 05:59:48 AMThe case is what did you do when your thread is in an unpredictable infinite loop  ?
wouldn't this be a programming error?
MREAL macros - when you need floating point arithmetic while assembling!

Zen

Dang, QWORD, I wish I had your brain,...mine is deprecated,...:dazzled:

This is the address for the PDF version of "Windows Via C/C++",...it might help (lots of information on thread internals):
Windows Via C/C++, 2008, by Jeffrey Richter and Christophe Nasarre

TouEnMasm

#14
Quote
wouldn't this be a programming error?
As everyone know there is never problem in a program and the window sdk is perfect  :bgrin:.
Here is two errors find in the windows sdk 8.1 ,found with  the very useful function  TerminateThread who allow to quit and read the data to get the line.
Quote
   ;D:\Include_8.1\um\IContentPrefetcherTaskTrigger.h
    _On_failure_(_Post_satisfies_(*isRegistered == false)) interface  ;mis //
   ;271 #define MD_INSERT_PATH_STRINGW      L##"<%INSERT_PATH%>"                     
   ;D:\Include_8.1\um\Mddefw.h
There is an another file where a , is missing in an enum
If you can't interrupt the thread in those cases,you can search a certain time in all the lines.

Fa is a musical note to play with CL