How do i get thread handle from thread id?

Just starting out? Need help? Post your questions and find answers here.
goldbaby
User
User
Posts: 32
Joined: Sat May 22, 2010 11:08 am

How do i get thread handle from thread id?

Post by goldbaby »

openthread win32api funciion doesnt seem to be supported either in purebasic or maybe its because i am running win7 64 bit....... unless i can access openthread function in win 7 64 bit somehow or if anyone has source code that doesnt use openthread api function to get the thread handle of a thread from a thread id that would be great if someone could help me out......
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: How do i get thread handle from thread id?

Post by doctorized »

goldbaby wrote:openthread win32api funciion doesnt seem to be supported either in purebasic or maybe its because i am running win7 64 bit....... unless i can access openthread function in win 7 64 bit somehow or if anyone has source code that doesnt use openthread api function to get the thread handle of a thread from a thread id that would be great if someone could help me out......
Help me a little to understand what exactly you want to do. You want to get the thread handle for a running thread by using the thread id?
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: How do i get thread handle from thread id?

Post by Thorium »

Your right OpenThread isnt available in PureBasic. However you can use it anyway. One way would be to open the kernel32.dll with OpenLibrary and call OpenThread with CallFunction.

Example:

Code: Select all

LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
hThread = CallFunction(LibKernel32,"OpenThread",#THREAD_ALL_ACCESS,0,idThread)
Additional you could request OpenThread_ in the "Feature Requests and Wishlists" subforum.

And i think that could be interessting for you: http://www.purebasic.fr/english/viewtop ... =7&t=39881
It isnt a debugger but the injector shows how to retrieve and change EIP register and some stuff.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: How do i get thread handle from thread id?

Post by SFSxOI »

Don't know if this will help but I had it laying around, gets thread or process handle (your choice) from a running process. Don't know if it would work on 64 bit as i haven't tried it on 64 bit:

Code: Select all

#Get_Thread_Handle = 1
#Get_Process_Handle = 2
#PROCESS_ALL_ACCESS_VISTA_WIN7 = $1FFFFF

Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;

Procedure GetPidByName(p_name$) 
    Protected hDLL.i, process_name$ 
    Protected PEntry.PROCESSENTRY32, hTool32.i 
    Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot 
    Protected pProcess32First.PFNProcess32First 
    Protected pProcess32Next.PFNProcess32Next 
    Protected pid.i 
    
    hDLL = OpenLibrary(#PB_Any,"kernel32.dll") 
    
    If hDLL 
        pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot") 
        pProcess32First = GetFunction(hDLL,"Process32First") 
        pProcess32Next = GetFunction(hDLL,"Process32Next") 
    Else 
        ProcedureReturn 0 
    EndIf 
    
    PEntry\dwSize = SizeOf(PROCESSENTRY32) 
    hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0) 
    pProcess32First(hTool32, @PEntry) 
    process_name$ = Space(#MAX_PATH) 
    CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH) 
    
    If  UCase(process_name$) = UCase(p_name$) 
        ProcedureReturn PEntry\th32ProcessID 
    EndIf 
    
    While pProcess32Next(hTool32, @PEntry) > 0 
        process_name$ = Space(#MAX_PATH) 
        CopyMemory(@PEntry\szExeFile,@process_name$,#MAX_PATH) 
        
        If  UCase(process_name$) = UCase(p_name$) 
            ProcedureReturn PEntry\th32ProcessID 
        EndIf 
    
    Wend 
    
    CloseLibrary(hDLL) 
    
    ProcedureReturn 0 
EndProcedure


; gets thread or process handle
; #Get_Thread_Handle = 1
; #Get_Process_Handle = 2
; uasge:
; hThread.i = Get_Thread_Process_Handle("notepad.exe", #Get_Thread_Handle)
; hThread.i = Get_Thread_Process_Handle("notepad.exe", #Get_Process_Handle)

Procedure Get_Thread_Process_Handle(Proc_file_mame$, Thread_Proc_Handle.i)

Define te.THREADENTRY32
PID = GetPidByName(Proc_file_mame$)

h=CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD,0);

Lib_OpenThread = LoadLibrary_("kernel32.dll")

If Lib_OpenThread
  *h_Thread = GetProcAddress_(Lib_OpenThread, "OpenThread")
  FreeLibrary_(Lib_OpenThread)
EndIf

If (h<>#INVALID_HANDLE_VALUE) 
  te\dwSize=SizeOf(te) 
    If (Thread32First_(h,@te)) 
      Repeat 
      If (te\dwSize>=OffsetOf(THREADENTRY32\th32OwnerProcessID)+SizeOf(te\th32OwnerProcessID)) 
          If PID = te\th32OwnerProcessID
            hProcess.i = OpenProcess_(#PROCESS_ALL_ACCESS_VISTA_WIN7,#False,te\th32OwnerProcessID)
            hThread.i = CallFunctionFast(*h_Thread, #PROCESS_ALL_ACCESS_VISTA_WIN7,#False,te\th32ThreadID)
          EndIf
        EndIf 
        te\dwSize=SizeOf(te)
      Until Not (Thread32Next_(h,@te)); 
    EndIf
  CloseHandle_(h)
EndIf

If Thread_Proc_Handle = #Get_Thread_Handle ; = 1
ProcedureReturn hThread
EndIf

If Thread_Proc_Handle = #Get_Process_Handle ; =2
ProcedureReturn hProcess
EndIf 

EndProcedure

Debug Get_Thread_Process_Handle("explorer.exe", #Get_Thread_Handle)
But if you already have the thread ID and just want the open handle then Thorium's post above is it. When you are done with it be sure to use the CloseHandle function.
Last edited by SFSxOI on Mon May 31, 2010 12:49 pm, edited 3 times in total.
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
goldbaby
User
User
Posts: 32
Joined: Sat May 22, 2010 11:08 am

Re: How do i get thread handle from thread id?

Post by goldbaby »

this code retrieves the context data but in part.... most of the time it doesnt update the exceptionaddress properly..... I really appreciate ur help...

Code: Select all

LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")

hprocess=RunProgram("c:\int3.exe", "", "", #PB_Program_Open);|#PB_Program_Read)
pid=ProgramID(hProcess)



result=DebugActiveProcess_(pid)

#PROCESS_ALL_ACCESS_VISTA_WIN7 = $1FFFFF


restart:
While WaitForDebugEvent_(@lpep.Debug_event,900)
   res=ContinueDebugEvent_(lpep.debug_event\dwProcessId,lpep.debug_event\dwThreadId,#DBG_CONTINUE);
   If res>0 
   hThreadh = CallFunction(libkernel32,"OpenThread", #PROCESS_ALL_ACCESS_VISTA_WIN7, 0,lpep.debug_event\dwThreadId)





Global con.context
;pcon\
;res=GetThreadContext_(lpEP.debug_event\dwThreadId,con.context)
con\ContextFlags = #CONTEXT_FULL
res=GetThreadContext_(hthreadh,@con.context)
CloseHandle_(hthreadh)
 tt$=""
 If lpep.debug_event\u\exception\exceptionrecord\exceptioncode=#EXCEPTION_SINGLE_STEP
 tt$="Single step"
 EndIf
MessageRequester("it works","address="+Str(lpEP.debug_event\u\exception\exceptionrecord\exceptionaddress)+" : Exception name="+tt$)
   EndIf
       
      Wend
    JMP l_restart                  

	
 exitdone:


I hope this code is all together before i posted it :)
goldbaby
User
User
Posts: 32
Joined: Sat May 22, 2010 11:08 am

Re: How do i get thread handle from thread id?

Post by goldbaby »

doctorized wrote:
goldbaby wrote:openthread win32api funciion doesnt seem to be supported either in purebasic or maybe its because i am running win7 64 bit....... unless i can access openthread function in win 7 64 bit somehow or if anyone has source code that doesnt use openthread api function to get the thread handle of a thread from a thread id that would be great if someone could help me out......
Help me a little to understand what exactly you want to do. You want to get the thread handle for a running thread by using the thread id?
sorry doctorized, im onto other things now after i figured out how to use openhandle api function...... I'm trying to get the exceptionaddress all the time throughout my little debugger running..... i was up all night finding information on openhandle functinn and then i figured it out....... then the other person replied and explained basically the same way to do it was callfunction...... anyways, I posted code hopefully u could help me with concerning getting the exceptionaddress properly I copied a basic debugger exception handler and converted it to purebasic but i can't get the data to display properly...... it shows the first address it will at all after an exception then it doesnt display the addresses at all....... I'm trying to get it to single step debug and display each address the exception_single_step exception happens on....... are the regflags in the context structure called "eflags"? because that is what i have to set to single step is the eighth bit in something called the regflags in the context structure then set the context of the thread i am currently debugging.....
User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: How do i get thread handle from thread id?

Post by doctorized »

I did some tests and the only value that is returned once is #EXCEPTION_BREAKPOINT.
#EXCEPTION_SINGLE_STEP appears never. Something else should be needed.

Advice: you do not have to use the var's type all the time. For example you do not have to write
lpEP.debug_event all the time, just the first time and all the others type lpEP!
goldbaby
User
User
Posts: 32
Joined: Sat May 22, 2010 11:08 am

Re: How do i get thread handle from thread id?

Post by goldbaby »

{I did some tests and the only value that is returned once is #EXCEPTION_BREAKPOINT.
#EXCEPTION_SINGLE_STEP appears never. Something else should be needed.

Advice: you do not have to use the var's type all the time. For example you do not have to write
lpEP.debug_event all the time, just the first time and all the others type lpEP!}


I need to do something to a flags or eflags or as it is known regflags and change the eighth bit to turn on single step....... thanks for the var type information I'm gonna try to get the singel step flag turned on in the process context....
goldbaby
User
User
Posts: 32
Joined: Sat May 22, 2010 11:08 am

Re: How do i get thread handle from thread id?

Post by goldbaby »

Here is code that works except instead of running the program smoothly while the single step flag is set it endlessly loops showing and endless loop of exectution addresses or to say exceptionaddresses in a loop endlessly.... if i take out the code the induces single step the program runs fine...
don't mind the mess..... :)

Code: Select all

Global con.context
LibKernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
;'------------------------------------------------------------------------ 
;              BEISPIEL 
;'------------------------------------------------------------------------ 


;result=WaitProgram("c:\int3.exe", 3000)

;MessageRequester("","In der folgenden Zeile wird eine Division durch 0 ausgeführt!",0) 

hprocess=RunProgram("c:\int3.exe", "", "", #PB_Program_Open);|#PB_Program_Read)
pid=ProgramID(hProcess)



;result=OpenProcess_(#PROCESS_ALL_ACCESS,#True,pid)

;MessageRequester("pid="+Str(pid),Str(result))
   ; BOOL bInheritHandle,	// handle inheritance flag 
   ; DWORD dwProcessId 	// process identifier 
;SetWindowsHookEx_(#WH_DEBUG,@mydebugger(), result, 0)

;    INT idHook,	// type of hook To install
;    HOOKPROC lpfn,	// address of hook Procedure
;    HINSTANCE hMod,	// handle of application instance
;    DWORD dwThreadId 	
;MessageRequester("pid",Str(pid))




result=DebugActiveProcess_(pid)
;InitDebugger() 
;MessageRequester("",Str(result))
; If (!WaitForDebugEvent(&debug_event, INFINITE))
 ;       Return;
  ;  ProcessDebugEvent(&debug_event);  // User-defined function, not API
   ; ContinueDebugEvent(debug_event.dwProcessId,
    ;                  debug_event.dwThreadId,
     ;                 DBG_CONTINUE);

;InitKeyboard()
#PROCESS_ALL_ACCESS_VISTA_WIN7 = $1FFFFF
;debug_vent.debug_event=debug_event

Global d_e.debug_event
start=0
restart:
If WaitForDebugEvent_(@lp.debug_event,#INFINITE)
  hThreadh = CallFunction(libkernel32,"OpenThread", #PROCESS_ALL_ACCESS_VISTA_WIN7, 0,lp.debug_event\dwThreadId)
If start=1 
  rst= SuspendThread_(hthreadh)
con\ContextFlags = #CONTEXT_FULL
res=GetThreadContext_(hthreadh,@con.context)
con\eflags=$100 ; THIS IS THE FLAG PART OF CONTEXT TO SET SINGLE STEP





;bill=1
;EndIf


res=SetThreadContext_(hthreadh,@con.context)
rst= ResumeThread_(hthreadh)
EndIf
If start=0
start=1

    
     rst= SuspendThread_(hthreadh)
   ;  MessageRequester("suspend",Str(rst))
      
   ; ProcessDebugEvent_(lpEP.debug_event);  // User-defined function, not API
  

 ;  If res>0 
;  If billy=0 

 ;  billy=1
  ; EndIf
;MessageRequester("hthreadh",Str(hthreadh))
 ;  MYDEBUGGER()
 ;  EndIf
  ; POINT=@LPep.EXCEPTION_POINTERSGetExceptionInformation_()
  ; EndIf

 ;  *cont.context = *lpEP\ContextRecord        ;Lese die 1. Beschreibung in eine Struktur 
;*rec.EXCEPTION_RECORD = *lpEP\pExceptionRecord  ;Lese die 2. Beschreibung in eine Struktur 

;If DebuggerVal=0                 ;The user don't klick on ignore?

;  DisplayDebuggerMessage: 
;*cont.context = *lpEP\ContextRecord        ;Lese die 1. Beschreibung in eine Struktur 
;*rec.EXCEPTION_RECORD = *lpEP\pExceptionRecord  ;Lese die 2. Beschreibung in eine Stru
  ;Show a Dialog with the Registers.
;lpointer=getexceptioninformation()
;tHANDLE= OpenThread_(#TOKEN_ALL_ACCESS,0,lpEP.debug_event\dwthreadid)
;Define te.THREADENTRY32

;h=CreateToolhelp32Snapshot_(#TH32CS_SNAPTHREAD,0);

;If (h<>#INVALID_HANDLE_VALUE)
;;   te\dwSize=SizeOf(te)
 ;  If (Thread32First_(h,@te))
;;         Repeat
;         If (te\dwSize>=OffsetOf(THREADENTRY32\th32OwnerProcessID)+SizeOf(te\th32OwnerProcessID))
 ;      ;  If 
  ;          Debug "Process "+RSet(Hex(te\th32OwnerProcessID),4,"0")+" Thread "+RSet(Hex(te\th32ThreadID),4,"0")
  ;       EndIf
  ;       te\dwSize=SizeOf(te);
;  ;;    Until Not (Thread32Next_(h,@te));
 ;  EndIf
;   CloseHandle_(h);
;EndIf

;  __in  DWORD dwDesiredAccess,
;  __in  BOOL bInheritHandle,
;  __in  DWORD dwThreadId
;);

;OpenThread_(#PROCESS_ALL_ACCESS_VISTA_WIN7, 0,lpEP.debug_event\dwThreadId)


;pcon\
;res=GetThreadContext_(lpEP.debug_event\dwThreadId,con.context)




;con\ContextFlags = #CONTEXT_FULL
;res=GetThreadContext_(hthreadh,@con.context)




;If billy=0 
;If flgs=0 then
;flgs=con\eflags
;EndIf







con\eflags=$100 ; THIS AGAIN SETS THE SINGLE STEP EXCEPTION





;bill=1
;EndIf


res=SetThreadContext_(hthreadh,@con.context)







;MessageRequester(Str(eflgs),"")
rst=0
rst= ResumeThread_(hthreadh)
  ;   MessageRequester("resume",Str(rst))

;ResumeThread(hthreadh)
EndIf







;openthread (



 ;   LPCONTEXT lpContext 	// address of context Structure 
 ;  );
  Title.s = "MyDebugger" 

  Message.s = "Program crashed!" + CrLf 
 ; Message.s + "" + CrLf 
 ; Message.s + "Register-values:" + CrLf 
 Message.s + "EDI="+Str(con.context\edi) + CrLf 
 ; Message.s + "ESI="+Str(*cont\esi) + CrLf 
 ; Message.s + "EBX="+Str(*cont\ebx) + CrLf 
 ; Message.s + "EDX="+Str(*cont\edx) + CrLf 
 ; Message.s + "ECX="+Str(*cont\ecx) + CrLf 
 ; Message.s + "EAX="+Str(*cont\eax) + CrLf 
 ; Message.s + "EBP="+Str(*cont\ebp) + CrLf 
 ; Message.s + "EIP="+Str(*cont\eip) + CrLf 
 ; Message.s + "ESP="+Str(*cont\esp) + CrLf 
 ; Message.s + "" + CrLf 
 ; Message.s + "Click on ignore to ignore it and do the next command in the programm," + CrLf 
 ; Message.s + "Retry to try it again," + CrLf 
 ; Message.s + "or Abort to exit the programm" 
 tt$=""
 If lp.debug_event\u\exception\exceptionrecord\exceptioncode=#EXCEPTION_SINGLE_STEP
 tt$="Single step"
 EndIf
MessageRequester("it works","address="+Str(lp.debug_event\u\exception\exceptionrecord\exceptionaddress)+" : Exception name="+tt$)

;MessageRequester("eip","eip:"+Str(con\eip))



 ;  MessageRequester(Title.s,message.s)
  ; EndIf
       
      ;
;                      EndIf
   ;                If KeyboardPushed(#PB_Key_Escape) 
    ;               Goto exitdone
     ;              EndIf
      ;
      ;             Goto restart
  ;    Wend
  EndIf
  ;MessageRequester("",Str(lp.debug_event\dwthreadid))
       res=ContinueDebugEvent_(lp.debug_event\dwProcessId,lp.debug_event\dwThreadId,#DBG_CONTINUE);
    JMP l_restart                  
;MessageRequester("result",Str(result))

;    LPDEBUG_EVENT lpDebugEvent,	// address of Structure For event information  
;    DWORD dwMilliseconds 	// number of milliseconds To WAIT For event 
;   );	
 exitdone:
 CloseHandle_(hthreadh)
;InitDebugger() 
;INT 3
;Y=0 
;X=999/Y 
;INT 3
;RunProgram("C:\int3.exe","","",#PB_Program_Open|#PB_Program_Read)
;MessageRequester("","Diese Zeile wird ausgeführt, obwohl ein Fehler aufgetreten war!",0) 

;UnloadDebugger()


User avatar
doctorized
Addict
Addict
Posts: 882
Joined: Fri Mar 27, 2009 9:41 am
Location: Athens, Greece

Re: How do i get thread handle from thread id?

Post by doctorized »

The last code is a real mess! If I understood well, you have taken this code from C++ and translated it.
Can you post the original code? It could be a little helpful to see what exactly has been translated.
goldbaby
User
User
Posts: 32
Joined: Sat May 22, 2010 11:08 am

Re: How do i get thread handle from thread id?

Post by goldbaby »

http://www.codeproject.com/KB/system/wr ... ger_1.aspx

is where i got the c++ source code........

for example:

Code: Select all


DEBUG_EVENT debug_event = {0};
for(;;)
{
    if (!WaitForDebugEvent(&debug_event, INFINITE))
        return;
    ProcessDebugEvent(&debug_event);  // User-defined function, not API
    ContinueDebugEvent(debug_event.dwProcessId,
                      debug_event.dwThreadId,
                      DBG_CONTINUE);
}
goldbaby
User
User
Posts: 32
Joined: Sat May 22, 2010 11:08 am

Re: How do i get thread handle from thread id?

Post by goldbaby »

the code i wrote from the c++ source executes the program that is being debugged fine except when i try to use single step exception flag set in the thread's context of the process being debugged.
Post Reply