基于visual c++之windows核心编程代码分析(19)枚举进程以及进程加载模块信息

我们进行Windows安全编程的时候,经常需要检测进程,我们来实践一下枚举进程与进程加载模块。请见代码实现与注释分析。

 

 

[cpp]  view plain  copy
  1. /* 头文件 */  
  2. #include <Windows.h>  
  3. #include <Psapi.h>  
  4. #include <Tlhelp32.h>  
  5. #include <stdio.h>  
  6. /* 预处理声明 */  
  7. #pragma comment (lib, "psapi.lib")  
  8. /* 函数声明 */  
  9. VOID WINAPI EnumProcess1();  
  10. VOID WINAPI EnumProcess2();  
  11. VOID ListProcessModules1( DWORD dwPID );  
  12. VOID ListProcessModules2( DWORD dwPID);  
  13. VOID PrintMemoryInfo( DWORD dwPID );  
  14. VOID ShowProcessMemoryInfo( DWORD dwPID );  
  15. VOID ListHeapInfo( DWORD dwPID );  
  16. VOID ListProcessThreads( DWORD dwPID );  
  17. VOID PrintError( LPTSTR msg );  
  18.   
  19. /************************************* 
  20. * VOID WINAPI EnumProcess1() 
  21. * 功能    调用EnumProcesses遍历进程, 
  22. *       并调用ListProcessModules1函数和 
  23. *       ListProcessThreads函数列举模块和线程 
  24. * 
  25. * 无参数,无返回值 
  26. **************************************/  
  27. VOID WINAPI EnumProcess1()  
  28. {  
  29.     // 假设不超过1024个进程  
  30.     DWORD aProcesses[1024], cbNeeded, cProcesses;  
  31.     unsigned int i;  
  32.     // 调用EnumProcesses  
  33.     if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )  
  34.         return;  
  35.     // 进程数  
  36.     cProcesses = cbNeeded / sizeof(DWORD);  
  37.     for ( i = 0; i < cProcesses; i++ )  
  38.     {  
  39.         // 显示进程信息  
  40.         printf( "\n\n**************************************************" );  
  41.         printf("\nPROCESS : %u\n\n",aProcesses[i]);  
  42.         printf( "\n****************************************************" );  
  43.         // 列举模块信息和线程信息  
  44.         ListProcessModules1( aProcesses[i] );  
  45.         ListProcessThreads( aProcesses[i] );  
  46.     }  
  47. }  
  48. /************************************* 
  49. * VOID WINAPI EnumProcess2() 
  50. * 功能    调用Process32First和Process32Next遍历进程, 
  51. *       并调用ListProcessModules2函数列举模块, 
  52. *       调用ShowProcessMemoryInfo函数显示内存使用情况 
  53. * 
  54. * 无参数,无返回值 
  55. **************************************/  
  56. VOID WINAPI EnumProcess2()  
  57. {  
  58.     HANDLE hProcessSnap;  
  59.     HANDLE hProcess;  
  60.     PROCESSENTRY32 pe32;  
  61.     DWORD dwPriorityClass;  
  62.     // Snapshot  
  63.     hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );  
  64.     if( hProcessSnap == INVALID_HANDLE_VALUE )  
  65.     {  
  66.         PrintError( "CreateToolhelp32Snapshot (of processes)" );  
  67.         return ;  
  68.     }  
  69.     // 设置输入参数,结构的大小  
  70.     pe32.dwSize = sizeof( PROCESSENTRY32 );  
  71.   
  72.     // 开始列举进程  
  73.     if( !Process32First( hProcessSnap, &pe32 ) )  
  74.     {  
  75.         PrintError( "Process32First" );  // 出错信息  
  76.         CloseHandle( hProcessSnap );  
  77.         return ;  
  78.     }  
  79.     do  
  80.     {  
  81.         // 打印进程名  
  82.         printf( "\n\n=====================================================" );  
  83.         printf( "\nPROCESS NAME:  %s", pe32.szExeFile );  
  84.         printf( "\n-----------------------------------------------------" );  
  85.   
  86.         // 获取优先级  
  87.         dwPriorityClass = 0;  
  88.         hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );  
  89.         if( hProcess == NULL )  
  90.             PrintError( "OpenProcess" );  
  91.         else  
  92.         {  
  93.             dwPriorityClass = GetPriorityClass( hProcess );  
  94.             if( !dwPriorityClass )  
  95.                 PrintError( "GetPriorityClass" );  
  96.             CloseHandle( hProcess );  
  97.         }  
  98.         // 打印进程相关信息  
  99.         printf( "\n  process ID        = 0x%08X", pe32.th32ProcessID );  
  100.         printf( "\n  thread count      = %d",   pe32.cntThreads );  
  101.         printf( "\n  parent process ID = 0x%08X", pe32.th32ParentProcessID );  
  102.         printf( "\n  Priority Base     = %d", pe32.pcPriClassBase );  
  103.         if( dwPriorityClass )  
  104.             printf( "\n  Priority Class    = %d", dwPriorityClass );  
  105.   
  106.         // 获取模块信息,显示内存使用情况  
  107.         ListProcessModules2( pe32.th32ProcessID );  
  108.         PrintMemoryInfo(pe32.th32ProcessID);  
  109.         ListHeapInfo(pe32.th32ProcessID);  
  110.   
  111.     } while( Process32Next( hProcessSnap, &pe32 ) );  
  112.   
  113.     CloseHandle( hProcessSnap );    //关闭句柄  
  114.     return ;  
  115. }  
  116.   
  117. /************************************* 
  118. * VOID ListProcessModules1( DWORD dwPID ) 
  119. * 功能    调用EnumProcessModules函数 
  120. *       列举和显示进程加载的模块 
  121. * 
  122. * 参数    DWORD dwPID 进程PID 
  123. **************************************/  
  124. VOID ListProcessModules1( DWORD dwPID )  
  125. {  
  126.     HMODULE hMods[1024];  
  127.     HANDLE hProcess;  
  128.     DWORD cbNeeded;  
  129.     unsigned int i;   
  130.   
  131.     printf( "\nListProcessModules1 Process ID %u\n", dwPID );  
  132.   
  133.     // 打开进程,获得句柄  
  134.     hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |  
  135.         PROCESS_VM_READ,  
  136.         FALSE, dwPID );  
  137.     if (NULL == hProcess)  
  138.         return;  
  139.     // 调用EnumProcessModules  
  140.     if( EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))  
  141.     {  
  142.         for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )  
  143.         {  
  144.             TCHAR szModName[MAX_PATH];  
  145.             // 获取获取的路径  
  146.             if ( GetModuleFileNameEx( hProcess, hMods[i], szModName,  
  147.                 sizeof(szModName)/sizeof(TCHAR)))  
  148.             {  
  149.                 // 打印  
  150.                 printf( TEXT("\t%s (0x%08X)\n"), szModName, hMods[i] );  
  151.             }  
  152.         }  
  153.     }  
  154.     CloseHandle( hProcess );    // 关闭进程句柄  
  155. }  
  156.   
  157. /************************************* 
  158. * VOID ListProcessModules2( DWORD dwPID ) 
  159. * 功能    调用Module32First和Module32Next函数 
  160. *       列举和显示进程加载的模块 
  161. * 
  162. * 参数    DWORD dwPID 进程PID 
  163. **************************************/  
  164. VOID ListProcessModules2( DWORD dwPID)  
  165. {  
  166.     HANDLE hModuleSnap = INVALID_HANDLE_VALUE;  
  167.     MODULEENTRY32 me32;  
  168.     printf( "\nListProcessModules2 Process ID %u\n", dwPID );  
  169.     // Snapshot  
  170.     hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );  
  171.     if( hModuleSnap == INVALID_HANDLE_VALUE )  
  172.     {  
  173.         PrintError( "CreateToolhelp32Snapshot (of modules)" );  
  174.         return ;  
  175.     }  
  176.     // 设置输入参数,结构的大小  
  177.     me32.dwSize = sizeof( MODULEENTRY32 );  
  178.     // 开始获取模块信息  
  179.     if( !Module32First( hModuleSnap, &me32 ) )  
  180.     {  
  181.         PrintError( "Module32First" );  // Show cause of failure  
  182.         CloseHandle( hModuleSnap );     // Must clean up the snapshot object!  
  183.         return ;  
  184.     }  
  185.     do  
  186.     {  
  187.         printf( "\n\n     MODULE NAME:     %s",             me32.szModule );  
  188.         printf( "\n     executable     = %s",             me32.szExePath );  
  189.         printf( "\n     process ID     = 0x%08X",         me32.th32ProcessID );  
  190.         printf( "\n     ref count (g)  =     0x%04X",     me32.GlblcntUsage );  
  191.         printf( "\n     ref count (p)  =     0x%04X",     me32.ProccntUsage );  
  192.         printf( "\n     base address   = 0x%08X", (DWORD) me32.modBaseAddr );  
  193.         printf( "\n     base size      = %d",             me32.modBaseSize );  
  194.   
  195.     } while( Module32Next( hModuleSnap, &me32 ) );  
  196.     CloseHandle( hModuleSnap ); // 关闭句柄  
  197.     return ;  
  198. }  
  199.   
  200. /************************************* 
  201. * VOID PrintMemoryInfo( DWORD dwPID ) 
  202. * 功能    显示进程的内存使用情况 
  203. * 
  204. * 参数    DWORD dwPID 进程PID 
  205. **************************************/  
  206. VOID PrintMemoryInfo( DWORD dwPID )  
  207. {  
  208.     HANDLE hProcess;  
  209.     PROCESS_MEMORY_COUNTERS pmc;  
  210.   
  211.     printf( "\nProcess ID: %u\n", dwPID );  
  212.   
  213.     hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |  
  214.         PROCESS_VM_READ,  
  215.         FALSE, dwPID );  
  216.     if (NULL == hProcess)  
  217.         return;  
  218.   
  219.     if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )  
  220.     {  
  221.         printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );  
  222.         printf( "\tPeakWorkingSetSize: 0x%08X\n",   
  223.             pmc.PeakWorkingSetSize );  
  224.         printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );  
  225.         printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n",   
  226.             pmc.QuotaPeakPagedPoolUsage );  
  227.         printf( "\tQuotaPagedPoolUsage: 0x%08X\n",   
  228.             pmc.QuotaPagedPoolUsage );  
  229.         printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n",   
  230.             pmc.QuotaPeakNonPagedPoolUsage );  
  231.         printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n",   
  232.             pmc.QuotaNonPagedPoolUsage );  
  233.         printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );   
  234.         printf( "\tPeakPagefileUsage: 0x%08X\n",   
  235.             pmc.PeakPagefileUsage );  
  236.     }  
  237.     CloseHandle( hProcess );  
  238. }  
  239.   
  240. /************************************* 
  241. * VOID ListHeapInfo( DWORD dwPID ) 
  242. * 功能    显示进程的堆分配情况 
  243. * 
  244. * 参数    DWORD dwPID 进程PID 
  245. **************************************/  
  246. VOID ListHeapInfo( DWORD dwPID )  
  247. {  
  248.     HEAPLIST32 hl;  
  249.     HEAPENTRY32 he;  
  250.     HANDLE hSnapshot = INVALID_HANDLE_VALUE;  
  251.   
  252.     printf( "\\ListHeapInfo Process ID %u\n", dwPID );  
  253.   
  254.     //  Snapshot  
  255.     hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST , dwPID );   
  256.     if( hSnapshot == INVALID_HANDLE_VALUE )   
  257.     {   
  258.         PrintError( "CreateToolhelp32Snapshot (of heaplist)" );   
  259.         return ;   
  260.     }  
  261.     // 设置输入参数,结构的大小  
  262.     hl.dwSize = sizeof( HEAPLIST32 );   
  263.   
  264.     // 开始获取信息  
  265.     if( !Heap32ListFirst( hSnapshot, &hl ) )   
  266.     {   
  267.         PrintError( "Heap32ListFirst" );    
  268.         CloseHandle( hSnapshot );       
  269.         return ;   
  270.     }   
  271.     do   
  272.     {   
  273.         printf( "\n\tHeap ID     =%u", hl.th32HeapID );   
  274.         printf( "\tHeap Flags     = %u", hl.dwFlags );   
  275.         he.dwSize = sizeof(HEAPENTRY32);  
  276.         if( !Heap32First(&he,dwPID,hl.th32HeapID) )   
  277.         {   
  278.             PrintError( "Heap32First" );    // 出错  
  279.             CloseHandle( hSnapshot );       
  280.             return ;   
  281.         }  
  282.         do   
  283.         {   
  284.             // 显示信息  
  285.             printf( "\n\t\t Heap Address\t= %u",he.dwAddress );   
  286.             printf( "\t Heap Size\t= %u",he.dwBlockSize);   
  287.             printf( "\t Heap Flags\t= %u",he.dwFlags);  
  288.             printf( "\t Heap Handle\t= %u",he.hHandle);  
  289.         } while( Heap32Next(&he ));   
  290.   
  291.     } while( Heap32ListNext( hSnapshot, &hl ) );   
  292.     CloseHandle( hSnapshot );   // 关闭句柄  
  293.     return ;   
  294. }  
  295.   
  296. /************************************* 
  297. * VOID ListProcessThreads( DWORD dwPID ) 
  298. * 功能    调用Thread32First和Thread32Next 
  299. *       显示一个进程的线程 
  300. * 
  301. * 参数    DWORD dwPID 进程PID 
  302. **************************************/  
  303. VOID ListProcessThreads( DWORD dwPID )  
  304. {  
  305.     HANDLE hThreadSnap = INVALID_HANDLE_VALUE;   
  306.     THREADENTRY32 te32;   
  307.   
  308.     printf( "\\ListProcessThreads Process ID %u\n", dwPID );  
  309.   
  310.     // Snapshot  
  311.     hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );   
  312.     if( hThreadSnap == INVALID_HANDLE_VALUE )   
  313.         return ;   
  314.   
  315.     // 设置输入参数,结构的大小  
  316.     te32.dwSize = sizeof(THREADENTRY32 );   
  317.   
  318.     // 开始获取信息  
  319.     if( !Thread32First( hThreadSnap, &te32 ) )   
  320.     {  
  321.         PrintError( "Thread32First" );  // Show cause of failure  
  322.         CloseHandle( hThreadSnap );     // Must clean up the snapshot object!  
  323.         return ;  
  324.     }  
  325.     do   
  326.     {   
  327.         if( te32.th32OwnerProcessID == dwPID )  
  328.         {  
  329.             // 显示相关信息  
  330.             printf( "\n   THREAD ID = 0x%08X", te32.th32ThreadID );   
  331.             printf( "\t   base priority = %d", te32.tpBasePri );   
  332.             printf( "\t   delta priority = %d", te32.tpDeltaPri );   
  333.         }  
  334.     } while( Thread32Next(hThreadSnap, &te32 ) );   
  335.   
  336.     CloseHandle( hThreadSnap );  
  337.     return ;  
  338.   
  339. }  
  340.   
  341. // 打印出错信息  
  342. VOID PrintError( LPTSTR msg )  
  343. {  
  344.     DWORD eNum;  
  345.     TCHAR sysMsg[256];  
  346.     TCHAR* p;  
  347.   
  348.     eNum = GetLastError( );  
  349.     FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,  
  350.         NULL, eNum,  
  351.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   
  352.         sysMsg, 256, NULL );  
  353.     p = sysMsg;  
  354.     while( ( *p > 31 ) || ( *p == 9 ) )  
  355.         ++p;  
  356.     do { *p-- = 0; } while( ( p >= sysMsg ) &&  
  357.         ( ( *p == '.' ) || ( *p < 33 ) ) );  
  358.     printf( "\n  WARNING: %s failed with error %d (%s)", msg, eNum, sysMsg );  
  359. }  
  360.   
  361. void main()  
  362. {  
  363.     printf("EnumProcess1 \n");  
  364.     EnumProcess1();  
  365.     printf("\n\n\nEnumProcess2 \n");  
  366.     EnumProcess2();  
  367. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值