如何枚举一个进程中所有的线程

时间:2022-08-28 21:48:42
已知一个进程,即已有进程的HANDLE或进程的PID(同时具有足够的权限). 如保才能枚举出此进程中所有的线程? (至少获得所有线程的HANDLE或ID).

18 个解决方案

#1


CreateToolhelp32Snapshot
Takes a snapshot of the processes and the heaps, modules, and threads used by the processes.

HANDLE WINAPI CreateToolhelp32Snapshot(
  DWORD dwFlags,       
  DWORD th32ProcessID  
);

Parameters
dwFlags 
Specifies portions of the system to include in the snapshot. This parameter can be one of the following: Value Meaning 
TH32CS_INHERIT Indicates that the snapshot handle is to be inheritable. 
TH32CS_SNAPALL Equivalent to specifying TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPPROCESS, and TH32CS_SNAPTHREAD. 
TH32CS_SNAPHEAPLIST Includes the heap list of the specified process in the snapshot. 
TH32CS_SNAPMODULE Includes the module list of the specified process in the snapshot. 
TH32CS_SNAPPROCESS Includes the process list in the snapshot. 
TH32CS_SNAPTHREAD Includes the thread list in the snapshot. 


th32ProcessID 
Specifies the process identifier. This parameter can be zero to indicate the current process. This parameter is used when the TH32CS_SNAPHEAPLIST or TH32CS_SNAPMODULE value is specified. Otherwise, it is ignored.


使用TH32CS_SNAPTHREAD作为参数

#2


/*********************
   EnumProc.h
   *********************/
   #include <windows.h>

   typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR,
      LPARAM ) ;

   BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam ) ;

   /*********************
   EnumProc.c (or .cpp)
   *********************/
   #include "EnumProc.h"
   #include <tlhelp32.h>
   #include <vdmdbg.h>

   typedef struct
   {
      DWORD          dwPID ;
      PROCENUMPROC   lpProc ;
      DWORD          lParam ;
      BOOL           bEnd ;
   } EnumInfoStruct ;

   BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
      PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;

   // The EnumProcs function takes a pointer to a callback function
   // that will be called once per process in the system providing
   // process EXE filename and process ID.
   // Callback function definition:
   // BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
   //
   // lpProc -- Address of callback routine.
   //
   // lParam -- A user-defined LPARAM value to be passed to
   //           the callback routine.
   BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
   {
      OSVERSIONINFO  osver ;
      HINSTANCE      hInstLib ;
      HINSTANCE      hInstLib2 ;
      HANDLE         hSnapShot ;
      PROCESSENTRY32 procentry ;
      BOOL           bFlag ;
      LPDWORD        lpdwPIDs ;
      DWORD          dwSize, dwSize2, dwIndex ;
      HMODULE        hMod ;
      HANDLE         hProcess ;
      char           szFileName[ MAX_PATH ] ;
      EnumInfoStruct sInfo ;

      // ToolHelp Function Pointers.
      HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
      BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
      BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;

      // PSAPI Function Pointers.
      BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
      BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
         DWORD, LPDWORD );
      DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE,
         LPTSTR, DWORD );

      // VDMDBG Function Pointers.
      INT (WINAPI *lpfVDMEnumTaskWOWEx)( DWORD,
         TASKENUMPROCEX  fp, LPARAM );


      // Check to see if were running under Windows95 or
      // Windows NT.
      osver.dwOSVersionInfoSize = sizeof( osver ) ;
      if( !GetVersionEx( &osver ) )
      {
         return FALSE ;
      }

#3


// If Windows NT:
      if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
      {

         // Load library and get the procedures explicitly. We do
         // this so that we don't have to worry about modules using
         // this code failing to load under Windows 95, because
         // it can't resolve references to the PSAPI.DLL.
         hInstLib = LoadLibraryA( "PSAPI.DLL" ) ;
         if( hInstLib == NULL )
            return FALSE ;

         hInstLib2 = LoadLibraryA( "VDMDBG.DLL" ) ;
         if( hInstLib2 == NULL )
            return FALSE ;

         // Get procedure addresses.
         lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
            GetProcAddress( hInstLib, "EnumProcesses" ) ;
         lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
            DWORD, LPDWORD)) GetProcAddress( hInstLib,
            "EnumProcessModules" ) ;
         lpfGetModuleFileNameEx =(DWORD (WINAPI *)(HANDLE, HMODULE,
            LPTSTR, DWORD )) GetProcAddress( hInstLib,
            "GetModuleFileNameExA" ) ;
         lpfVDMEnumTaskWOWEx =(INT(WINAPI *)( DWORD, TASKENUMPROCEX,
            LPARAM))GetProcAddress( hInstLib2, "VDMEnumTaskWOWEx" );
         if( lpfEnumProcesses == NULL ||
            lpfEnumProcessModules == NULL ||
            lpfGetModuleFileNameEx == NULL ||
            lpfVDMEnumTaskWOWEx == NULL)
            {
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }

         // Call the PSAPI function EnumProcesses to get all of the
         // ProcID's currently in the system.
         // NOTE: In the documentation, the third parameter of
         // EnumProcesses is named cbNeeded, which implies that you
         // can call the function once to find out how much space to
         // allocate for a buffer and again to fill the buffer.
         // This is not the case. The cbNeeded parameter returns
         // the number of PIDs returned, so if your buffer size is
         // zero cbNeeded returns zero.
         // NOTE: The "HeapAlloc" loop here ensures that we
         // actually allocate a buffer large enough for all the
         // PIDs in the system.
         dwSize2 = 256 * sizeof( DWORD ) ;
         lpdwPIDs = NULL ;
         do
         {
            if( lpdwPIDs )
            {
               HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
               dwSize2 *= 2 ;
            }
            lpdwPIDs = HeapAlloc( GetProcessHeap(), 0, dwSize2 );
            if( lpdwPIDs == NULL )
            {
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }
            if( !lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) )
            {
               HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }
         }while( dwSize == dwSize2 ) ;

         // How many ProcID's did we get?
         dwSize /= sizeof( DWORD ) ;

         // Loop through each ProcID.
         for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ )
         {
            szFileName[0] = 0 ;
            // Open the process (if we can... security does not
            // permit every process in the system).
            hProcess = OpenProcess(
               PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
               FALSE, lpdwPIDs[ dwIndex ] ) ;
            if( hProcess != NULL )
            {
               // Here we call EnumProcessModules to get only the
               // first module in the process this is important,
               // because this will be the .EXE module for which we
               // will retrieve the full path name in a second.
               if( lpfEnumProcessModules( hProcess, &hMod,
                  sizeof( hMod ), &dwSize2 ) )
               {
                  // Get Full pathname:
                  if( !lpfGetModuleFileNameEx( hProcess, hMod,
                     szFileName, sizeof( szFileName ) ) )
                  {
                     szFileName[0] = 0 ;
                    }
               }
               CloseHandle( hProcess ) ;
            }
            // Regardless of OpenProcess success or failure, we
            // still call the enum func with the ProcID.
            if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam))
               break ;

            // Did we just bump into an NTVDM?
            if( _stricmp( szFileName+(strlen(szFileName)-9),
               "NTVDM.EXE")==0)
            {
               // Fill in some info for the 16-bit enum proc.
               sInfo.dwPID = lpdwPIDs[dwIndex] ;
               sInfo.lpProc = lpProc ;
               sInfo.lParam = lParam ;
               sInfo.bEnd = FALSE ;
               // Enum the 16-bit stuff.
               lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex],
                  (TASKENUMPROCEX) Enum16,
                  (LPARAM) &sInfo);

               // Did our main enum func say quit?
               if(sInfo.bEnd)
                  break ;
            }
         }

         HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
         FreeLibrary( hInstLib2 ) ;

      // If Windows 95:
      }else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
      {


         hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
         if( hInstLib == NULL )
            return FALSE ;

         // Get procedure addresses.
         // We are linking to these functions of Kernel32
         // explicitly, because otherwise a module using
         // this code would fail to load under Windows NT,
         // which does not have the Toolhelp32
         // functions in the Kernel 32.
         lpfCreateToolhelp32Snapshot=
            (HANDLE(WINAPI *)(DWORD,DWORD))
            GetProcAddress( hInstLib,
            "CreateToolhelp32Snapshot" ) ;
         lpfProcess32First=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32First" ) ;
         lpfProcess32Next=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32Next" ) ;
         if( lpfProcess32Next == NULL ||
            lpfProcess32First == NULL ||
            lpfCreateToolhelp32Snapshot == NULL )
         {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
         }

         // Get a handle to a Toolhelp snapshot of the systems
         // processes.
         hSnapShot = lpfCreateToolhelp32Snapshot(
            TH32CS_SNAPPROCESS, 0 ) ;
         if( hSnapShot == INVALID_HANDLE_VALUE )
         {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
         }

         // Get the first process' information.
         procentry.dwSize = sizeof(PROCESSENTRY32) ;
         bFlag = lpfProcess32First( hSnapShot, &procentry ) ;

         // While there are processes, keep looping.
         while( bFlag )
         {
            // Call the enum func with the filename and ProcID.
            if(lpProc( procentry.th32ProcessID, 0,
               procentry.szExeFile, lParam ))
            {
               procentry.dwSize = sizeof(PROCESSENTRY32) ;
               bFlag = lpfProcess32Next( hSnapShot, &procentry );
            }else
               bFlag = FALSE ;
         }


      }else
         return FALSE ;

      // Free the library.
      FreeLibrary( hInstLib ) ;

      return TRUE ;
   }

#4


#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL GetProcessList () 

    HANDLE         hProcessSnap = NULL; 
    BOOL           bRet      = FALSE; 
    PROCESSENTRY32 pe32      = {0}; 
 
    //  Take a snapshot of all processes in the system. 

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 

    if (hProcessSnap == (HANDLE)-1) 
        return (FALSE); 
 
    //  Fill in the size of the structure before using it. 

    pe32.dwSize = sizeof(PROCESSENTRY32); 
 
    //  Walk the snapshot of the processes, and for each process, 
    //  display information. 

    if (Process32First(hProcessSnap, &pe32)) 
    { 
        DWORD         dwPriorityClass; 
        BOOL          bGotModule = FALSE; 
        MODULEENTRY32 me32       = {0}; 
 
        do 
        { 
            bGotModule = GetProcessModule(pe32.th32ProcessID, 
                pe32.th32ModuleID, &me32, sizeof(MODULEENTRY32)); 

            if (bGotModule) 
            { 
                HANDLE hProcess; 
 
                // Get the actual priority class. 
                hProcess = OpenProcess (PROCESS_ALL_ACCESS, 
                    FALSE, pe32.th32ProcessID); 
                dwPriorityClass = GetPriorityClass (hProcess); 
                CloseHandle (hProcess); 

                // Print the process's information. 
                printf( "\nPriority Class Base\t%d\n", 
                    pe32.pcPriClassBase); 
                printf( "PID\t\t\t%d\n", pe32.th32ProcessID);
                printf( "Thread Count\t\t%d\n", pe32.cntThreads);
                printf( "Module Name\t\t%s\n", me32.szModule);
                printf( "Full Path\t\t%s\n\n", me32.szExePath);
            } 
        } 
        while (Process32Next(hProcessSnap, &pe32)); 
        bRet = TRUE; 
    } 
    else 
        bRet = FALSE;    // could not walk the list of processes 
 
    // Do not forget to clean up the snapshot object. 

    CloseHandle (hProcessSnap); 
    return (bRet); 

#5


建议楼阅读<Windows核心编程>

#6


The following example obtains a list of running threads for the specified process. First, the RefreshThreadList function takes a snapshot of the currently executing threads in the system using the CreateToolhelp32Snapshot function, then it walks through the list recorded in the snapshot, using the Thread32First and Thread32Next functions. The parameter for RefreshThreadList is the identifier of the process whose threads will be listed. 

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL RefreshThreadList (DWORD dwOwnerPID) 

    HANDLE        hThreadSnap = NULL; 
    BOOL          bRet        = FALSE; 
    THREADENTRY32 te32        = {0}; 
 
    // Take a snapshot of all threads currently in the system. 

    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 
    if (hThreadSnap == INVALID_HANDLE_VALUE) 
        return (FALSE); 
 
    // Fill in the size of the structure before using it. 

    te32.dwSize = sizeof(THREADENTRY32); 
 
    // Walk the thread snapshot to find all threads of the process. 
    // If the thread belongs to the process, add its information 
    // to the display list.
 
    if (Thread32First(hThreadSnap, &te32)) 
    { 
        do 
        { 
            if (te32.th32OwnerProcessID == dwOwnerPID) 
            { 
                printf( "\nTID\t\t%d\n", te32.th32ThreadID); 
                printf( "Owner PID\t%d\n", te32.th32OwnerProcessID); 
                printf( "Delta Priority\t%d\n", te32.tpDeltaPri); 
                printf( "Base Priority\t%d\n", te32.tpBasePri); 
            } 
        } 
        while (Thread32Next(hThreadSnap, &te32)); 
        bRet = TRUE; 
    } 
    else 
        bRet = FALSE;          // could not walk the list of threads 
 
    // Do not forget to clean up the snapshot object. 

    CloseHandle (hThreadSnap); 
 
    return (bRet); 

#7


windows程序设计!

#8


收藏

#9


努力学习一下

#10


十分感谢诸位的帮助.

再追问一句,得到了线程的HANDLE或ID后,如何判断此线程是由CreateRemoteThread()建立的,还是由CreateThread()建立的?

#11


这个就不会了。     汗~    :(

#12


不太好判断.
windows系统创建一个线程的唯一方法是调用API CreatThread函数(__beginthreadex之类的都要在内部调用他创建新线程)。windows核心编程说,在win2000下,系统用CreateRemoteThread函数来创建线程,CreateThread在内部调用CreateRemoteThread。

#13


得到了线程的HANDLE或ID后,如何判断此线程是由CreateRemoteThread()建立的,还是由CreateThread()建立的?
应该无法判断吧。

#14


应该在创建的时候拦截。

#15


后一个问题有点奇怪?这样的区别感觉没有意义。

一、如果想保护自己的机器,那么首先自己的程序要抢先运行,从而拦截 CreateRemoteThread,才可能知道。

二、至于说,是 CreateRemoteThread 还是 CreateThread 地判断来保证不被注入,个人觉得完全没有意思。
因为,我可以在 CreateRemoteThread 中在 CreateThread,这样,你是无法达到你的目的的。因为,我用
CreateThread 创建的还在,我却可以退出 CreateRemoteThread 的。

#16


mark

#17


好,我也需要这个

Mark

#18


想要不让别人用CreateRemoteThread入侵进程,只有你用另一个账号运行进程,而这个帐号权限不够才行吧,我也不明白为什么windows要留这样一个后门,许多木马可以这样藏身。

#1


CreateToolhelp32Snapshot
Takes a snapshot of the processes and the heaps, modules, and threads used by the processes.

HANDLE WINAPI CreateToolhelp32Snapshot(
  DWORD dwFlags,       
  DWORD th32ProcessID  
);

Parameters
dwFlags 
Specifies portions of the system to include in the snapshot. This parameter can be one of the following: Value Meaning 
TH32CS_INHERIT Indicates that the snapshot handle is to be inheritable. 
TH32CS_SNAPALL Equivalent to specifying TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPPROCESS, and TH32CS_SNAPTHREAD. 
TH32CS_SNAPHEAPLIST Includes the heap list of the specified process in the snapshot. 
TH32CS_SNAPMODULE Includes the module list of the specified process in the snapshot. 
TH32CS_SNAPPROCESS Includes the process list in the snapshot. 
TH32CS_SNAPTHREAD Includes the thread list in the snapshot. 


th32ProcessID 
Specifies the process identifier. This parameter can be zero to indicate the current process. This parameter is used when the TH32CS_SNAPHEAPLIST or TH32CS_SNAPMODULE value is specified. Otherwise, it is ignored.


使用TH32CS_SNAPTHREAD作为参数

#2


/*********************
   EnumProc.h
   *********************/
   #include <windows.h>

   typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR,
      LPARAM ) ;

   BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam ) ;

   /*********************
   EnumProc.c (or .cpp)
   *********************/
   #include "EnumProc.h"
   #include <tlhelp32.h>
   #include <vdmdbg.h>

   typedef struct
   {
      DWORD          dwPID ;
      PROCENUMPROC   lpProc ;
      DWORD          lParam ;
      BOOL           bEnd ;
   } EnumInfoStruct ;

   BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
      PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;

   // The EnumProcs function takes a pointer to a callback function
   // that will be called once per process in the system providing
   // process EXE filename and process ID.
   // Callback function definition:
   // BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
   //
   // lpProc -- Address of callback routine.
   //
   // lParam -- A user-defined LPARAM value to be passed to
   //           the callback routine.
   BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
   {
      OSVERSIONINFO  osver ;
      HINSTANCE      hInstLib ;
      HINSTANCE      hInstLib2 ;
      HANDLE         hSnapShot ;
      PROCESSENTRY32 procentry ;
      BOOL           bFlag ;
      LPDWORD        lpdwPIDs ;
      DWORD          dwSize, dwSize2, dwIndex ;
      HMODULE        hMod ;
      HANDLE         hProcess ;
      char           szFileName[ MAX_PATH ] ;
      EnumInfoStruct sInfo ;

      // ToolHelp Function Pointers.
      HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
      BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
      BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;

      // PSAPI Function Pointers.
      BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
      BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
         DWORD, LPDWORD );
      DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE,
         LPTSTR, DWORD );

      // VDMDBG Function Pointers.
      INT (WINAPI *lpfVDMEnumTaskWOWEx)( DWORD,
         TASKENUMPROCEX  fp, LPARAM );


      // Check to see if were running under Windows95 or
      // Windows NT.
      osver.dwOSVersionInfoSize = sizeof( osver ) ;
      if( !GetVersionEx( &osver ) )
      {
         return FALSE ;
      }

#3


// If Windows NT:
      if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
      {

         // Load library and get the procedures explicitly. We do
         // this so that we don't have to worry about modules using
         // this code failing to load under Windows 95, because
         // it can't resolve references to the PSAPI.DLL.
         hInstLib = LoadLibraryA( "PSAPI.DLL" ) ;
         if( hInstLib == NULL )
            return FALSE ;

         hInstLib2 = LoadLibraryA( "VDMDBG.DLL" ) ;
         if( hInstLib2 == NULL )
            return FALSE ;

         // Get procedure addresses.
         lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
            GetProcAddress( hInstLib, "EnumProcesses" ) ;
         lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
            DWORD, LPDWORD)) GetProcAddress( hInstLib,
            "EnumProcessModules" ) ;
         lpfGetModuleFileNameEx =(DWORD (WINAPI *)(HANDLE, HMODULE,
            LPTSTR, DWORD )) GetProcAddress( hInstLib,
            "GetModuleFileNameExA" ) ;
         lpfVDMEnumTaskWOWEx =(INT(WINAPI *)( DWORD, TASKENUMPROCEX,
            LPARAM))GetProcAddress( hInstLib2, "VDMEnumTaskWOWEx" );
         if( lpfEnumProcesses == NULL ||
            lpfEnumProcessModules == NULL ||
            lpfGetModuleFileNameEx == NULL ||
            lpfVDMEnumTaskWOWEx == NULL)
            {
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }

         // Call the PSAPI function EnumProcesses to get all of the
         // ProcID's currently in the system.
         // NOTE: In the documentation, the third parameter of
         // EnumProcesses is named cbNeeded, which implies that you
         // can call the function once to find out how much space to
         // allocate for a buffer and again to fill the buffer.
         // This is not the case. The cbNeeded parameter returns
         // the number of PIDs returned, so if your buffer size is
         // zero cbNeeded returns zero.
         // NOTE: The "HeapAlloc" loop here ensures that we
         // actually allocate a buffer large enough for all the
         // PIDs in the system.
         dwSize2 = 256 * sizeof( DWORD ) ;
         lpdwPIDs = NULL ;
         do
         {
            if( lpdwPIDs )
            {
               HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
               dwSize2 *= 2 ;
            }
            lpdwPIDs = HeapAlloc( GetProcessHeap(), 0, dwSize2 );
            if( lpdwPIDs == NULL )
            {
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }
            if( !lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) )
            {
               HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
               FreeLibrary( hInstLib ) ;
               FreeLibrary( hInstLib2 ) ;
               return FALSE ;
            }
         }while( dwSize == dwSize2 ) ;

         // How many ProcID's did we get?
         dwSize /= sizeof( DWORD ) ;

         // Loop through each ProcID.
         for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ )
         {
            szFileName[0] = 0 ;
            // Open the process (if we can... security does not
            // permit every process in the system).
            hProcess = OpenProcess(
               PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
               FALSE, lpdwPIDs[ dwIndex ] ) ;
            if( hProcess != NULL )
            {
               // Here we call EnumProcessModules to get only the
               // first module in the process this is important,
               // because this will be the .EXE module for which we
               // will retrieve the full path name in a second.
               if( lpfEnumProcessModules( hProcess, &hMod,
                  sizeof( hMod ), &dwSize2 ) )
               {
                  // Get Full pathname:
                  if( !lpfGetModuleFileNameEx( hProcess, hMod,
                     szFileName, sizeof( szFileName ) ) )
                  {
                     szFileName[0] = 0 ;
                    }
               }
               CloseHandle( hProcess ) ;
            }
            // Regardless of OpenProcess success or failure, we
            // still call the enum func with the ProcID.
            if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam))
               break ;

            // Did we just bump into an NTVDM?
            if( _stricmp( szFileName+(strlen(szFileName)-9),
               "NTVDM.EXE")==0)
            {
               // Fill in some info for the 16-bit enum proc.
               sInfo.dwPID = lpdwPIDs[dwIndex] ;
               sInfo.lpProc = lpProc ;
               sInfo.lParam = lParam ;
               sInfo.bEnd = FALSE ;
               // Enum the 16-bit stuff.
               lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex],
                  (TASKENUMPROCEX) Enum16,
                  (LPARAM) &sInfo);

               // Did our main enum func say quit?
               if(sInfo.bEnd)
                  break ;
            }
         }

         HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
         FreeLibrary( hInstLib2 ) ;

      // If Windows 95:
      }else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
      {


         hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
         if( hInstLib == NULL )
            return FALSE ;

         // Get procedure addresses.
         // We are linking to these functions of Kernel32
         // explicitly, because otherwise a module using
         // this code would fail to load under Windows NT,
         // which does not have the Toolhelp32
         // functions in the Kernel 32.
         lpfCreateToolhelp32Snapshot=
            (HANDLE(WINAPI *)(DWORD,DWORD))
            GetProcAddress( hInstLib,
            "CreateToolhelp32Snapshot" ) ;
         lpfProcess32First=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32First" ) ;
         lpfProcess32Next=
            (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
            GetProcAddress( hInstLib, "Process32Next" ) ;
         if( lpfProcess32Next == NULL ||
            lpfProcess32First == NULL ||
            lpfCreateToolhelp32Snapshot == NULL )
         {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
         }

         // Get a handle to a Toolhelp snapshot of the systems
         // processes.
         hSnapShot = lpfCreateToolhelp32Snapshot(
            TH32CS_SNAPPROCESS, 0 ) ;
         if( hSnapShot == INVALID_HANDLE_VALUE )
         {
            FreeLibrary( hInstLib ) ;
            return FALSE ;
         }

         // Get the first process' information.
         procentry.dwSize = sizeof(PROCESSENTRY32) ;
         bFlag = lpfProcess32First( hSnapShot, &procentry ) ;

         // While there are processes, keep looping.
         while( bFlag )
         {
            // Call the enum func with the filename and ProcID.
            if(lpProc( procentry.th32ProcessID, 0,
               procentry.szExeFile, lParam ))
            {
               procentry.dwSize = sizeof(PROCESSENTRY32) ;
               bFlag = lpfProcess32Next( hSnapShot, &procentry );
            }else
               bFlag = FALSE ;
         }


      }else
         return FALSE ;

      // Free the library.
      FreeLibrary( hInstLib ) ;

      return TRUE ;
   }

#4


#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL GetProcessList () 

    HANDLE         hProcessSnap = NULL; 
    BOOL           bRet      = FALSE; 
    PROCESSENTRY32 pe32      = {0}; 
 
    //  Take a snapshot of all processes in the system. 

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 

    if (hProcessSnap == (HANDLE)-1) 
        return (FALSE); 
 
    //  Fill in the size of the structure before using it. 

    pe32.dwSize = sizeof(PROCESSENTRY32); 
 
    //  Walk the snapshot of the processes, and for each process, 
    //  display information. 

    if (Process32First(hProcessSnap, &pe32)) 
    { 
        DWORD         dwPriorityClass; 
        BOOL          bGotModule = FALSE; 
        MODULEENTRY32 me32       = {0}; 
 
        do 
        { 
            bGotModule = GetProcessModule(pe32.th32ProcessID, 
                pe32.th32ModuleID, &me32, sizeof(MODULEENTRY32)); 

            if (bGotModule) 
            { 
                HANDLE hProcess; 
 
                // Get the actual priority class. 
                hProcess = OpenProcess (PROCESS_ALL_ACCESS, 
                    FALSE, pe32.th32ProcessID); 
                dwPriorityClass = GetPriorityClass (hProcess); 
                CloseHandle (hProcess); 

                // Print the process's information. 
                printf( "\nPriority Class Base\t%d\n", 
                    pe32.pcPriClassBase); 
                printf( "PID\t\t\t%d\n", pe32.th32ProcessID);
                printf( "Thread Count\t\t%d\n", pe32.cntThreads);
                printf( "Module Name\t\t%s\n", me32.szModule);
                printf( "Full Path\t\t%s\n\n", me32.szExePath);
            } 
        } 
        while (Process32Next(hProcessSnap, &pe32)); 
        bRet = TRUE; 
    } 
    else 
        bRet = FALSE;    // could not walk the list of processes 
 
    // Do not forget to clean up the snapshot object. 

    CloseHandle (hProcessSnap); 
    return (bRet); 

#5


建议楼阅读<Windows核心编程>

#6


The following example obtains a list of running threads for the specified process. First, the RefreshThreadList function takes a snapshot of the currently executing threads in the system using the CreateToolhelp32Snapshot function, then it walks through the list recorded in the snapshot, using the Thread32First and Thread32Next functions. The parameter for RefreshThreadList is the identifier of the process whose threads will be listed. 

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

BOOL RefreshThreadList (DWORD dwOwnerPID) 

    HANDLE        hThreadSnap = NULL; 
    BOOL          bRet        = FALSE; 
    THREADENTRY32 te32        = {0}; 
 
    // Take a snapshot of all threads currently in the system. 

    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 
    if (hThreadSnap == INVALID_HANDLE_VALUE) 
        return (FALSE); 
 
    // Fill in the size of the structure before using it. 

    te32.dwSize = sizeof(THREADENTRY32); 
 
    // Walk the thread snapshot to find all threads of the process. 
    // If the thread belongs to the process, add its information 
    // to the display list.
 
    if (Thread32First(hThreadSnap, &te32)) 
    { 
        do 
        { 
            if (te32.th32OwnerProcessID == dwOwnerPID) 
            { 
                printf( "\nTID\t\t%d\n", te32.th32ThreadID); 
                printf( "Owner PID\t%d\n", te32.th32OwnerProcessID); 
                printf( "Delta Priority\t%d\n", te32.tpDeltaPri); 
                printf( "Base Priority\t%d\n", te32.tpBasePri); 
            } 
        } 
        while (Thread32Next(hThreadSnap, &te32)); 
        bRet = TRUE; 
    } 
    else 
        bRet = FALSE;          // could not walk the list of threads 
 
    // Do not forget to clean up the snapshot object. 

    CloseHandle (hThreadSnap); 
 
    return (bRet); 

#7


windows程序设计!

#8


收藏

#9


努力学习一下

#10


十分感谢诸位的帮助.

再追问一句,得到了线程的HANDLE或ID后,如何判断此线程是由CreateRemoteThread()建立的,还是由CreateThread()建立的?

#11


这个就不会了。     汗~    :(

#12


不太好判断.
windows系统创建一个线程的唯一方法是调用API CreatThread函数(__beginthreadex之类的都要在内部调用他创建新线程)。windows核心编程说,在win2000下,系统用CreateRemoteThread函数来创建线程,CreateThread在内部调用CreateRemoteThread。

#13


得到了线程的HANDLE或ID后,如何判断此线程是由CreateRemoteThread()建立的,还是由CreateThread()建立的?
应该无法判断吧。

#14


应该在创建的时候拦截。

#15


后一个问题有点奇怪?这样的区别感觉没有意义。

一、如果想保护自己的机器,那么首先自己的程序要抢先运行,从而拦截 CreateRemoteThread,才可能知道。

二、至于说,是 CreateRemoteThread 还是 CreateThread 地判断来保证不被注入,个人觉得完全没有意思。
因为,我可以在 CreateRemoteThread 中在 CreateThread,这样,你是无法达到你的目的的。因为,我用
CreateThread 创建的还在,我却可以退出 CreateRemoteThread 的。

#16


mark

#17


好,我也需要这个

Mark

#18


想要不让别人用CreateRemoteThread入侵进程,只有你用另一个账号运行进程,而这个帐号权限不够才行吧,我也不明白为什么windows要留这样一个后门,许多木马可以这样藏身。