首页
社区
课程
招聘
[求助][求助]windows如何获得一个进程的线程数目
发表于: 2012-8-29 19:26 8681

[求助][求助]windows如何获得一个进程的线程数目

2012-8-29 19:26
8681
http://bbs.pediy.com/showthread.php?t=98078
下载了这个,里面有 可以查看 线程数,不过 代码 我暂时还无法 分析。好像使用了 psapi procs 库。
请问 可以利用 windows API 来获得一个进程的线程数目么?
给出 需要使用 那些函数 也行。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 506
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
CreateToolhelp32Snapshot,行不,
2012-8-29 20:57
0
雪    币: 122
活跃值: (72)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
以下代码是网上copy的:
必须调用到ntdll.dll首先我们要有一个头文件

hypNtdll.h:

#pragma once

#include <windows.h>

typedef LONG    NTSTATUS;
typedef ULONG   ACCESS_MASK;
typedef ULONG    KPRIORITY ;
typedef DWORD    ACCESS_MASK ;

#define NT_SUCCESS(status)          ((NTSTATUS)(status)>=0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_ACCESS_DENIED        ((NTSTATUS)0xC0000022L)

typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef enum _SYSTEM_INFORMATION_CLASS {
    SystemBasicInformation,                // 0 Y N
    SystemProcessorInformation,            // 1 Y N
    SystemPerformanceInformation,        // 2 Y N
    SystemTimeOfDayInformation,            // 3 Y N
    SystemNotImplemented1,                // 4 Y N
    SystemProcessesAndThreadsInformation, // 5 Y N
    SystemCallCounts,                    // 6 Y N
    SystemConfigurationInformation,        // 7 Y N
    SystemProcessorTimes,                // 8 Y N
    SystemGlobalFlag,                    // 9 Y Y
    SystemNotImplemented2,                // 10 Y N
    SystemModuleInformation,            // 11 Y N
    SystemLockInformation,                // 12 Y N
    SystemNotImplemented3,                // 13 Y N
    SystemNotImplemented4,                // 14 Y N
    SystemNotImplemented5,                // 15 Y N
    SystemHandleInformation,            // 16 Y N
    SystemObjectInformation,            // 17 Y N
    SystemPagefileInformation,            // 18 Y N
    SystemInstructionEmulationCounts,    // 19 Y N
    SystemInvalidInfoClass1,            // 20
    SystemCacheInformation,                // 21 Y Y
    SystemPoolTagInformation,            // 22 Y N
    SystemProcessorStatistics,            // 23 Y N
    SystemDpcInformation,                // 24 Y Y
    SystemNotImplemented6,                // 25 Y N
    SystemLoadImage,                    // 26 N Y
    SystemUnloadImage,                    // 27 N Y
    SystemTimeAdjustment,                // 28 Y Y
    SystemNotImplemented7,                // 29 Y N
    SystemNotImplemented8,                // 30 Y N
    SystemNotImplemented9,                // 31 Y N
    SystemCrashDumpInformation,            // 32 Y N
    SystemExceptionInformation,            // 33 Y N
    SystemCrashDumpStateInformation,    // 34 Y Y/N
    SystemKernelDebuggerInformation,    // 35 Y N
    SystemContextSwitchInformation,        // 36 Y N
    SystemRegistryQuotaInformation,        // 37 Y Y
    SystemLoadAndCallImage,                // 38 N Y
    SystemPrioritySeparation,            // 39 N Y
    SystemNotImplemented10,                // 40 Y N
    SystemNotImplemented11,                // 41 Y N
    SystemInvalidInfoClass2,            // 42
    SystemInvalidInfoClass3,            // 43
    SystemTimeZoneInformation,            // 44 Y N
    SystemLookasideInformation,            // 45 Y N
    SystemSetTimeSlipEvent,                // 46 N Y
    SystemCreateSession,                // 47 N Y
    SystemDeleteSession,                // 48 N Y
    SystemInvalidInfoClass4,            // 49
    SystemRangeStartInformation,        // 50 Y N
    SystemVerifierInformation,            // 51 Y Y
    SystemAddVerifier,                    // 52 N Y
    SystemSessionProcessesInformation    // 53 Y N
} SYSTEM_INFORMATION_CLASS;

typedef struct _VM_COUNTERS {
    ULONG PeakVirtualSize;
    ULONG VirtualSize;
    ULONG PageFaultCount;
    ULONG PeakWorkingSetSize;
    ULONG WorkingSetSize;
    ULONG QuotaPeakPagedPoolUsage;
    ULONG QuotaPagedPoolUsage;
    ULONG QuotaPeakNonPagedPoolUsage;
    ULONG QuotaNonPagedPoolUsage;
    ULONG PagefileUsage;
    ULONG PeakPagefileUsage;
} VM_COUNTERS, *PVM_COUNTERS;

/*
*Information Class 5
*/
typedef struct _SYSTEM_PROCESSES
{
    ULONG          NextEntryDelta;          //构成结构序列的偏移量;
    ULONG          ThreadCount;             //线程数目;
    ULONG          Reserved1[6];           
    LARGE_INTEGER CreateTime;              //创建时间;
    LARGE_INTEGER UserTime;                //用户模式(Ring 3)的CPU时间;
    LARGE_INTEGER KernelTime;              //内核模式(Ring 0)的CPU时间;
    UNICODE_STRING ProcessName;             //进程名称;
    KPRIORITY      BasePriority;            //进程优先权;
    ULONG          ProcessId;               //进程标识符;
    ULONG          InheritedFromProcessId; //父进程的标识符;
    ULONG          HandleCount;             //句柄数目;
    ULONG          Reserved2[2];
    VM_COUNTERS    VmCounters;              //虚拟存储器的结构;
    IO_COUNTERS    IoCounters;              //IO计数结构; Windows 2000 only
    //SYSTEM_THREADS Threads[1];              //进程相关线程的结构数组;
}SYSTEM_PROCESSES,*PSYSTEM_PROCESSES;


// 定义NtQuerySystemInformation函数
typedef NTSTATUS (WINAPI *PFNNtQuerySystemInformation)(   
    SYSTEM_INFORMATION_CLASS   SystemInformationClass,    // 定义服务类型号
    PVOID   SystemInformation,                            // 用户存储信息的缓冲区
    ULONG   SystemInformationLength,                    // 缓冲区大小
    PULONG   ReturnLength   );                            // 返回信息长度
接下来便是穷举进程信息函数:

BOOL EnumProcessInfo()
{
    PFNNtQuerySystemInformation NtQuerySystemInformation ;
    // 检测当前进程中是否存在ntdll.dll
    HMODULE    hMod = GetModuleHandle ( L"ntdll.dll" ) ;
    if ( hMod == NULL )
    {
        // 如果不存在,就使用LoadLibrary来加载
        hMod = LoadLibrary ( L"ntdll.dll" ) ;
        if ( hMod == NULL )
            return FALSE ;
    }
    // 取得函数地址
    NtQuerySystemInformation = (PFNNtQuerySystemInformation)GetProcAddress ( hMod, "NtQuerySystemInformation" ) ;
    NTSTATUS    status ;
    UINT        nSize = DEF_BUF_SIZE ;
    LPBYTE        lpBuf = NULL ;

    // 由于事先并不知道需要多少空间来存储进程信息
    // 因而采用循环测试法,
    while ( TRUE )
    {
        // 动态分配空间,用来存储进程信息
        if ( ( lpBuf = new BYTE [ nSize ] ) == NULL )
        {
            return FALSE;
        }

        // 枚举进程信息
        status = NtQuerySystemInformation ( SystemProcessesAndThreadsInformation, lpBuf, nSize, 0 ) ;
        if ( !NT_SUCCESS(status) )
        {
            // 检测是否返回缓冲区不够大
            if ( status == STATUS_INFO_LENGTH_MISMATCH )
            {
                nSize += DEF_BUF_SIZE ;
                delete lpBuf ;
                continue ;
            }
            else
            {
                return FALSE;
            }
        }
        else
            break ;
    }
    PSYSTEM_PROCESSES pSysProcess = (PSYSTEM_PROCESSES)lpBuf ;
    while ( pSysProcess->NextEntryDelta != 0 )
    {
        if ( pSysProcess->ProcessName.Buffer != NULL )
            printf ( "ProcessName:\t%30S\n", pSysProcess->ProcessName.Buffer ) ;
        printf ("InheritedFromProcessId:\t\t%d\n",pSysProcess->InheritedFromProcessId);
        printf ("ProcessId:\t\t\t%d\n",pSysProcess->ProcessId);
        printf("HandleCount:\t\t\t%d\n",pSysProcess->HandleCount);
        printf("ThreadCount:\t\t\t%d\n",pSysProcess->ThreadCount);
        printf("-------------------------------------------------------------------------\n");
        pSysProcess = (PSYSTEM_PROCESSES)( (DWORD)pSysProcess + pSysProcess->NextEntryDelta ) ;
    }
    delete lpBuf ;
    if (hMod != 0)
    {
        FreeLibrary(hMod);
    }
    return TRUE;
}
2012-8-29 22:02
0
雪    币: 15
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
嗯 我知道了。。。http://baike.baidu.com/view/589425.htm
其实 在 之前的 例子里面有,不过 开始我不知道头文件。。现在 知道了。。。
#include <TlHelp32.h> 再使用。
2012-8-29 22:08
0
雪    币: 15
活跃值: (48)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5



#include <TlHelp32.h>

void TestProcessGetThreadNumber() 
{

	int i = 0;
	char Buff[9];
	PROCESSENTRY32 pe32;
	pe32.dwSize = sizeof(pe32);

	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
	{
		printf("CreateToolhelp32Snapshot 调用失败.\n");
		return ;
	}
	BOOL bMore = ::Process32First(hProcessSnap,&pe32);

	HANDLE hProcess;

	printf("%-30s %-20s %-20s %-15s\n","szExeFile","th32ProcessID","th32ParentProcessID","cntThreads");
	while(bMore)
	{
		printf("%-30s ",pe32.szExeFile);
		printf("%-20d ",pe32.th32ProcessID);
		printf("%-20d",pe32.th32ParentProcessID);


		//显示进程的线程数
		printf("%-15d\n",pe32.cntThreads);

		bMore = Process32Next(hProcessSnap,&pe32);
		i++;

		//pe32.th32ModuleID
	}
		
	printf("进程数:%d\n",i);
	system("pause");
	exit(0);
}


嗯 这样 到是 跟 tasklist 命令 有点类似了。。还可以添加更多信息了。。
不过 想要 查找指定的 进程的话,只需要 设置 CreateToolhelp32Snapshot的第二个参数为 进程ID 就可以了。
2012-8-29 22:23
0
游客
登录 | 注册 方可回帖
返回
//