PoEdu培训 Windows班 第十九课 Windows 进程-项目开始
文章类别: 培训笔记 0 评论

PoEdu培训 Windows班 第十九课 Windows 进程-项目开始

文章类别: 培训笔记 0 评论

Windows 进程-项目开始

进程枚举

函数发展简介

严格意义上来说, Windows标准API中没有提供进程相关的API

Tool Help库中的结构

typedef struct tagHEAPENTRY32 {
  SIZE_T    dwSize;         // sizeof(HEAPENTRY32)
  HANDLE    hHandle;        // 堆的句柄
  ULONG_PTR dwAddress;      // 堆地址
  SIZE_T    dwBlockSize;    // 堆大小
  DWORD     dwFlags;        // LF32_FIXED(不可移动的), LF32_FREE(未被使用的), LF32_MOVEABLE(可移动的) 三个值中的一个
  DWORD     dwLockCount;    // 不使用
  DWORD     dwResvd;        // 不使用
  DWORD     th32ProcessID;  // 使用这个堆的PID
  ULONG_PTR th32HeapID;     // 堆的标识符, 不是句柄
} HEAPENTRY32, *PHEAPENTRY32;
typedef struct tagHEAPLIST32 {
  SIZE_T    dwSize;         // sizeof(HEAPLIST32)
  DWORD     th32ProcessID;  // 要检查的进程PID
  ULONG_PTR th32HeapID;     // 堆标识符, 这不是句柄
  DWORD     dwFlags;        // 必须是 HF32_DEFAULT
} HEAPLIST32, *PHEAPLIST32;
typedef struct tagMODULEENTRY32 {
  DWORD   dwSize;                           // sizeof(MODULEENTRY32)
  DWORD   th32ModuleID;                     // 不使用
  DWORD   th32ProcessID;                    // PID
  DWORD   GlblcntUsage;                     // 通常是 0xFFF
  DWORD   ProccntUsage;                     // 通常是 0xFFFF
  BYTE    *modBaseAddr;                     // 模块基址
  DWORD   modBaseSize;                      // 模块大小
  HMODULE hModule;                          // 模块句柄
  TCHAR   szModule[MAX_MODULE_NAME32 + 1];  // 模块名字
  TCHAR   szExePath[MAX_PATH];              // 模块路径
} MODULEENTRY32, *PMODULEENTRY32;
typedef struct tagPROCESSENTRY32 {
  DWORD     dwSize;             // sizeof(PROCESSENTRY32)
  DWORD     cntUsage;           // 不使用
  DWORD     th32ProcessID;      // PID
  ULONG_PTR th32DefaultHeapID;  // 不使用
  DWORD     th32ModuleID;       // 不使用
  DWORD     cntThreads;         // 拥有的线程数
  DWORD     th32ParentProcessID;// 父进程PID
  LONG      pcPriClassBase;     // 进程优先级
  DWORD     dwFlags;            // 不使用
  TCHAR     szExeFile[MAX_PATH];// 可执行完整文件名
} PROCESSENTRY32, *PPROCESSENTRY32;
typedef struct tagTHREADENTRY32 {
  DWORD dwSize;             // sizeof(THREADENTRY32)
  DWORD cntUsage;           // 不使用
  DWORD th32ThreadID;       // 线程ID
  DWORD th32OwnerProcessID; // 创建这个线程的进程PID
  LONG  tpBasePri;          // 线程优先级 0--31, 0优先级最小, 31优先级最大
  LONG  tpDeltaPri;         // 不使用
  DWORD dwFlags;            // 不使用
} THREADENTRY32, *PTHREADENTRY32;

示例程序

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

// 前置声明
BOOL GetProcessList( );
BOOL ListProcessModules( DWORD dwPID );
BOOL ListProcessThreads( DWORD dwOwnerPID );
void printError( TCHAR* msg );

int main( void )
{
  GetProcessList( );
  return 0;
}

BOOL GetProcessList( )
{
  HANDLE hProcessSnap;
  HANDLE hProcess;
  PROCESSENTRY32 pe32;

  // 对系统所有进程取快照
  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {
    printError( TEXT("创建系统进程快照") );
    return( FALSE );
  }

  pe32.dwSize = sizeof( PROCESSENTRY32 );

  if( !Process32First( hProcessSnap, &pe32 ) )
  {
    printError( TEXT("Process32First") );
    CloseHandle( hProcessSnap );
    return( FALSE );
  }

  // 显示每个进程的信息
  do
  {
    _tprintf( TEXT("\n\n=====================================================" ));
    _tprintf( TEXT("\进程名称:  %s"), pe32.szExeFile );
    _tprintf( TEXT("\n-------------------------------------------------------" ));

    _tprintf( TEXT("\n  PID        = 0x%08X"), pe32.th32ProcessID );
    _tprintf( TEXT("\n  线程数      = %d"),   pe32.cntThreads );
    _tprintf( TEXT("\n  父进程PID   = 0x%08X"), pe32.th32ParentProcessID );
    _tprintf( TEXT("\n  优先级      = %d"), pe32.pcPriClassBase );

    // 显示进程的模块信息和线程信息
    ListProcessModules( pe32.th32ProcessID );
    ListProcessThreads( pe32.th32ProcessID );

  } while( Process32Next( hProcessSnap, &pe32 ) );

  CloseHandle( hProcessSnap );
  return( TRUE );
}


BOOL ListProcessModules( DWORD dwPID )
{
  HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
  MODULEENTRY32 me32;

  // 给指定的进程获取模块快照
  hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
  if( hModuleSnap == INVALID_HANDLE_VALUE )
  {
    printError( TEXT("创建进程的模块快照") );
    return( FALSE );
  }

  me32.dwSize = sizeof( MODULEENTRY32 );

  if( !Module32First( hModuleSnap, &me32 ) )
  {
    printError( TEXT("Module32First") );
    CloseHandle( hModuleSnap );
    return( FALSE );
  }

  do
  {
    _tprintf( TEXT("\n\n     模块名称: %s"),   me32.szModule );
    _tprintf( TEXT("\n     模块路径 = %s"),     me32.szExePath );
    _tprintf( TEXT("\n     PID = 0x%08X"),         me32.th32ProcessID );
    _tprintf( TEXT("\n     模块基址 = 0x%08X"), (DWORD) me32.modBaseAddr );
    _tprintf( TEXT("\n     模块大小 = %d"),             me32.modBaseSize );

  } while( Module32Next( hModuleSnap, &me32 ) );

  CloseHandle( hModuleSnap );
  return( TRUE );
}

BOOL ListProcessThreads( DWORD dwOwnerPID ) 
{ 
  HANDLE hThreadSnap = INVALID_HANDLE_VALUE; 
  THREADENTRY32 te32; 
 
  // 获取进程的线程快照
  hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); 
  if( hThreadSnap == INVALID_HANDLE_VALUE ) 
    return( FALSE ); 
 
  te32.dwSize = sizeof(THREADENTRY32); 
 
  if( !Thread32First( hThreadSnap, &te32 ) ) 
  {
    printError( TEXT("Thread32First") );
    CloseHandle( hThreadSnap );
    return( FALSE );
  }

  do 
  { 
    if( te32.th32OwnerProcessID == dwOwnerPID )
    {
      _tprintf( TEXT("\n\n     线程ID = 0x%08X"), te32.th32ThreadID ); 
      _tprintf( TEXT("\n     基本优先级 = %d"), te32.tpBasePri ); 
      _tprintf( TEXT("\n"));
    }
  } while( Thread32Next(hThreadSnap, &te32 ) ); 

  CloseHandle( hThreadSnap );
  return( TRUE );
}

void printError( TCHAR* msg )
{
  DWORD eNum;
  TCHAR sysMsg[256];
  TCHAR* p;

  eNum = GetLastError( );
  FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
         NULL, eNum,
         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
         sysMsg, 256, NULL );

  // 以 \0 结束
  p = sysMsg;
  while( ( *p > 31 ) || ( *p == 9 ) )
    ++p;
  do { *p-- = 0; } while( ( p >= sysMsg ) &&
                          ( ( *p == '.' ) || ( *p < 33 ) ) );

  _tprintf( TEXT("\n  出错了: %s失败了, 错误码[%d], 错误信息:[%s]"), msg, eNum, sysMsg );
}

未完待续...

如有错误,请提出指正!谢谢.

回复