Jump to content

Thread Enumeration with CreateToolhelp32Snapshot


monoceres
 Share

Recommended Posts

Simple UDF for enumerating threads. Fast 'n easy :)

Not much to say really, check source for more info

Thread_Enum.au3

:)

Merry xmas monoceres o:)

Thanks for your help but is it also possible to resolve the TID with names (see screenshot -> SHLWAPI.dll, autoit3.exe, msvcrt.dll and gdiplus.dll)?

post-29844-1228847941_thumb.png

Here an example where the screenshot comes from.

#include <WinAPi.au3>
#include <Array.au3> 
Opt('MustDeclareVars', 1)
HotKeySet("{ESC}", "_Exit")
Global Const $TH32CS_SNAPTHREAD = 0x00000004
Global Const $THREADENTRY32 = "dword dwSize;dword cntUsage;dword th32ThreadId;dword th32OwnerProcessID;long tpBasePri;long tpDeltaPri;dword dwFlags;"

Global $zip_file = "c:\Test.zip"
Global $source_folder = "c:\Windows\Inf\"
Add_Folder_2_ZIP($source_folder, $zip_file)

Func Add_Folder_2_ZIP($folder, $zip_filename, $flag = 4)
    Local $hZIP, $ZIP_fileheader, $obj_ZIP, $obj_Folder, $obj_ZIP_Folder, $obj_Copy, $arr
    $hZIP = FileOpen($zip_filename, 26)
    $ZIP_fileheader = Chr(80) & Chr(75) & Chr(5) & Chr(6) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0)
    FileWrite($hZIP, $ZIP_fileheader)
    FileClose($hZIP)
    $obj_ZIP = ObjCreate("Shell.Application")
    $obj_Folder = $obj_ZIP.NameSpace($folder)
    $obj_ZIP_Folder = $obj_ZIP.NameSpace($zip_filename)
    $obj_Copy = $obj_ZIP.NameSpace($zip_filename).CopyHere($obj_Folder.Items, $flag) ;add files to ZIP archive
    While 1
        Sleep(1000)
        $arr = _GetAllProcessThreads(@AutoItPID)
        _ArrayDisplay($arr)
    WEnd
EndFunc   ;==>Add_Folder_2_ZIP

Func _GetAllThreads()
    Local $call = DllCall("Kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPTHREAD, "dword", 0)
    Local $handle = $call[0]
    Local $RetArr[1][3]
    ConsoleWrite("Handle: " & $handle & @CRLF)
    
    Local $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   ;==>_GetAllThreads

; Same as _GetAllThreads, but with a simple pid filter
Func _GetAllProcessThreads($iPid)
    Local $call = DllCall("Kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPTHREAD, "dword", 0)
    Local $handle = $call[0]
    Local $RetArr[1][3]
    ConsoleWrite("Handle: " & $handle & @CRLF)
    
    Local $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   ;==>_GetAllProcessThreads

Func _GetAllThreads_ArrHelper(ByRef $arr, $TE32_Struct)
    Local $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   ;==>_GetAllThreads_ArrHelper

Func _Exit()
    Exit
EndFunc

Thanks,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Merry xmas monoceres o:)

Merry xmas you too ;)

Thanks for your help but is it also possible to resolve the TID with names (see screenshot -> SHLWAPI.dll, autoit3.exe, msvcrt.dll and gdiplus.dll)?

That is not the names of the threads but rather the modules in which they run. So what's needed is the thread address+base address of all modules+size of all modules.

I can check for a solution tomorrow.

:)

@Andreik, thanks for the comment, I always appreciate it :)

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

Merry xmas you too o:)

That is not the names of the threads but rather the modules in which they run. So what's needed is the thread address+base address of all modules+size of all modules.

I can check for a solution tomorrow.

:)

@Andreik, thanks for the comment, I always appreciate it :)

Just curious, which is the highest priority that you have at your threads?

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

Win32 :)

I rarely modify the standard priority which is automatically set when creating a thread. The values you use when specifying the priority in C/C++ is not the same as returned by this function though.

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

  • 3 years later...

Merry xmas monoceres ;)

Thanks for your help but is it also possible to resolve the TID with names (see screenshot -> SHLWAPI.dll, autoit3.exe, msvcrt.dll and gdiplus.dll)?

post-29844-1228847941_thumb.png

Here an example where the screenshot comes from.

#include <WinAPi.au3>
#include <Array.au3>
Opt('MustDeclareVars', 1)
HotKeySet("{ESC}", "_Exit")
Global Const $TH32CS_SNAPTHREAD = 0x00000004
Global Const $THREADENTRY32 = "dword dwSize;dword cntUsage;dword th32ThreadId;dword th32OwnerProcessID;long tpBasePri;long tpDeltaPri;dword dwFlags;"

Global $zip_file = "c:Test.zip"
Global $source_folder = "c:WindowsInf"
Add_Folder_2_ZIP($source_folder, $zip_file)

Func Add_Folder_2_ZIP($folder, $zip_filename, $flag = 4)
Local $hZIP, $ZIP_fileheader, $obj_ZIP, $obj_Folder, $obj_ZIP_Folder, $obj_Copy, $arr
$hZIP = FileOpen($zip_filename, 26)
$ZIP_fileheader = Chr(80) & Chr(75) & Chr(5) & Chr(6) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0)
FileWrite($hZIP, $ZIP_fileheader)
FileClose($hZIP)
$obj_ZIP = ObjCreate("Shell.Application")
$obj_Folder = $obj_ZIP.NameSpace($folder)
$obj_ZIP_Folder = $obj_ZIP.NameSpace($zip_filename)
$obj_Copy = $obj_ZIP.NameSpace($zip_filename).CopyHere($obj_Folder.Items, $flag) ;add files to ZIP archive
While 1
Sleep(1000)
$arr = _GetAllProcessThreads(@AutoItPID)
_ArrayDisplay($arr)
WEnd
EndFunc ;==>Add_Folder_2_ZIP

Func _GetAllThreads()
Local $call = DllCall("Kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPTHREAD, "dword", 0)
Local $handle = $call[0]
Local $RetArr[1][3]
ConsoleWrite("Handle: " & $handle & @CRLF)

Local $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 ;==>_GetAllThreads

; Same as _GetAllThreads, but with a simple pid filter
Func _GetAllProcessThreads($iPid)
Local $call = DllCall("Kernel32.dll", "ptr", "CreateToolhelp32Snapshot", "dword", $TH32CS_SNAPTHREAD, "dword", 0)
Local $handle = $call[0]
Local $RetArr[1][3]
ConsoleWrite("Handle: " & $handle & @CRLF)

Local $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 ;==>_GetAllProcessThreads

Func _GetAllThreads_ArrHelper(ByRef $arr, $TE32_Struct)
Local $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 ;==>_GetAllThreads_ArrHelper

Func _Exit()
Exit
EndFunc

Thanks,

UEZ

Hey UEZ,

What is that application in that screenshot called?

It looks like an alternative task manager that allows people to kill/suspend threads.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...