[Question] Thread Suspenden

08/04/2011 22:17 Xyooz#1
Hallo ~

Ich wollte mal was probieren und zwar einzelne Threads zu suspenden/resumen via Hotkey.

Finde keinerlei Tutorials zu sowas, nur zum finden der Thread IDs (TID).
Wollte das ganze in AutoIt machen, so viel ist es bisher:

PHP Code:
#include <WinAPi.au3>
#include <array.au3>

Global Const $TH32CS_SNAPTHREAD = 0x00000004
Global Const $THREADENTRY32 = "dword dwSize;dword cntUsage;dword th32ThreadId;dword th32OwnerProcessID;long tpBasePri;long tpDeltaPri;dword dwFlags;"

$pid = ProcessExists("S4Client.exe")
$arr=_GetAllProcessThreads($pid)
_ArrayDisplay($arr)

$arr=_GetAllThreads()
_ArrayDisplay($arr)



Func _GetAllThreads()
    
$call = DllCall("Kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPTHREAD, "dword", 0)
    
$handle = $call[0]
    
Local $RetArr[1][3]
    
ConsoleWrite("Handle: " & $handle & @CRLF)
    
    
$te32=DllStructCreate($THREADENTRY32)
    
DllStructSetData($te32,"dwSize",DllStructGetSize($te32))
    
$call=DllCall("Kernel32.dll","int","Thread32First","ptr",$handle,"ptr",DllStructGetPtr($te32))
    
_GetAllThreads_ArrHelper($RetArr,$te32)
    Do
        
$call=DllCall("Kernel32.dll","int","Thread32Next","ptr",$handle,"ptr",DllStructGetPtr($te32))
        If 
Not $call[0] Then ExitLoop
        _GetAllThreads_ArrHelper
($RetArr,$te32)
    
Until True And False
    _ArrayDelete
($RetArr,0)
    
_WinAPI_CloseHandle($handle)
    Return 
$RetArr
EndFunc   

Func _GetAllProcessThreads
($iPid)
        
$call = DllCall("Kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPTHREAD, "dword", 0)
    
$handle = $call[0]
    
Local $RetArr[1][3]
    
ConsoleWrite("Handle: " & $handle & @CRLF)
    
    
$te32=DllStructCreate($THREADENTRY32)
    
DllStructSetData($te32,"dwSize",DllStructGetSize($te32))
    
$call=DllCall("Kernel32.dll","int","Thread32First","ptr",$handle,"ptr",DllStructGetPtr($te32))
    If 
DllStructGetData($te32,"th32OwnerProcessID")=$iPid Then _GetAllThreads_ArrHelper($RetArr,$te32)
    Do
        
$call=DllCall("Kernel32.dll","int","Thread32Next","ptr",$handle,"ptr",DllStructGetPtr($te32))
        If 
Not $call[0] Then ExitLoop
        
If DllStructGetData($te32,"th32OwnerProcessID")=$iPid Then  _GetAllThreads_ArrHelper($RetArr,$te32)
    
Until True And False
    _ArrayDelete
($RetArr,0)
    
_WinAPI_CloseHandle($handle)
    Return 
$RetArr
EndFunc


Func _GetAllThreads_ArrHelper
(ByRef $Arr,$TE32_Struct)
    
$ub=Ubound($Arr)
    
ReDim $Arr[$ub+1][3]
    
$Arr[$ub][0]=DllStructGetData($TE32_Struct,"th32ThreadId")
    
$Arr[$ub][1]=DllStructGetData($TE32_Struct,"th32OwnerProcessID")
    
$Arr[$ub][2]=DllStructGetData($TE32_Struct,"tpBasePri")
EndFunc 
Was gibt es für Möglichkeiten?
08/04/2011 23:09 xNopex#2
[Only registered and activated users can see links. Click Here To Register...]
[Only registered and activated users can see links. Click Here To Register...]
08/05/2011 04:05 KDeluxe#3
Basierend auf einer [Only registered and activated users can see links. Click Here To Register...] habe ich mal eben das hier erstellt:
PHP Code:
;=================================================================================================
; Function:            
SetThreadStatus($ProcessId, $ThreadId_StartAddress, $Paused = True, $UseThreadStartAddress = False)
; 
Description:        Suspends or resumes a specified thread.
; Return 
Value(s):    On Success - Returns true
;                    On Failure - Returns false
;                    @error:    0  = No error.
;                            
1  = Failed to open 'ntdll.dll'.
;                            
2  = Failed to open 'Kernel32.dll'.
;                            
3  = Failed to create a snapshot.
;                            
4  = Failed to copie the first entry of the thread list.
;                            
5  = Failed to open a thread.
;                            
6  = Failed to get the start address.
;                            
7  = Failed to suspend the thread.
;                            
8  = Failed to resume the thread.
;                            
9  = Failed to close the opened thread.
;                            
10 = Failed to copie the next entry of the thread list.
;                            
11 = Failed to close the created snapshot.
; 
Author(s):        KillerDeluxe
;=================================================================================================

Func SetThreadStatus($ProcessId, $ThreadId_StartAddress, $Paused = True, $UseThreadStartAddress = False)
    
$StartAddress = DllStructCreate("DWORD")

    
$TE32 = DllStructCreate("DWORD;DWORD;DWORD;DWORD;LONG;LONG;DWORD")
    
DllStructSetData($TE32, 1, DllStructGetSize($TE32))

    
$ntdll = DllOpen("ntdll.dll")
    If @
error Then Return SetError(1, "", False)

    
$Kernel32 = DllOpen("Kernel32.dll")
    If @
error Then Return SetError(2, "", False)

    
$hSnapshot = DllCall($Kernel32, "HANDLE", "CreateToolhelp32Snapshot", "int", 4, "DWORD", $ProcessId)
    If @
error Then Return SetError(3, "", False)

    
DllCall($Kernel32, "int", "Thread32First", "HANDLE", $hSnapshot[0], "ptr", DllStructGetPtr($TE32))
    If @
error Then Return SetError(4, "", False)

    While 
True
        
If DllStructGetData($TE32, 4) == $ProcessId Then
            $hThread 
= DllCall($Kernel32, "HANDLE", "OpenThread", "int", 0x62, "bool", False, "DWORD", DllStructGetData($TE32, 3))
            If @
error Then Return SetError(5, "", False)

            
DllCall($ntdll, "none", "NtQueryInformationThread", "HANDLE", $hThread[0], "int", 9, "ptr", DllStructGetPtr($StartAddress), "int", 4, "int", 0)
            If @
error Then Return SetError(6, "", False)

            
$bSuspendResume = False

            
If $UseThreadStartAddress Then
                
If DllStructGetData($StartAddress, 1) == $ThreadId_StartAddress Then $bSuspendResume = True
            
Else
                If 
DllStructGetData($TE32, 3) == $ThreadId_StartAddress Then $bSuspendResume = True
            
EndIf

            If 
$bSuspendResume Then
                
If $Paused Then
                    DllCall
($Kernel32, "DWORD", "SuspendThread", "HANDLE", $hThread[0])
                    If @
error Then Return SetError(7, "", False)
                Else
                    
DllCall($Kernel32, "DWORD", "ResumeThread", "HANDLE", $hThread[0])
                    If @
error Then Return SetError(8, "", False)
                EndIf
            EndIf

            
DllCall($Kernel32, "int", "CloseHandle", "HANDLE", $hThread[0])
            If @
error Then Return SetError(9, "", False)
        EndIf

        
$ret = DllCall($Kernel32, "int", "Thread32Next", "HANDLE", $hSnapshot[0], "ptr", DllStructGetPtr($TE32))
        If @
error Then Return SetError(10, "", False)
        If 
Not $ret[0] Then ExitLoop
    WEnd

    DllCall
($Kernel32, "int", "CloseHandle", "HANDLE", $hSnapshot[0])
    If @
error Then Return SetError(11, "", False)

    
DllClose($ntdll)
    
DllClose($Kernel32)
    Return 
SetError(0, "", True)
EndFunc 
Auch hier muss wieder beachtet werden, dass das Script als 32 Bit Anwendung kompiliert werden muss ("#AutoIt3Wrapper_UseX64=n").