Ring3枚举进程

2024-06-17 01:08
文章标签 进程 枚举 ring3

本文主要是介绍Ring3枚举进程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在Ring3枚举进程通常有一下几种方法:
  • ToolHelper32
  • Psapi
  • ZwQuerySystemInformation
  • WTSEnumerateProcesses

一、ToolHelper32

头文件:TlHelp32.h
关键函数:CreateToolhelp32Snapshot,Process32Next

BOOL EnumProcessesByToolHelper32()
{
    PROCESSENTRY32 ProcessEntry32 = { 0 };
    HANDLE hSnapshot = INVALID_HANDLE_VALUE;
    BOOL IsOk = FALSE;
    
    hSnapshot = CreateToolhelp32Snapshot(2, 0);
    if (INVALID_HANDLE_VALUE == hSnapshot)
    {
        return FALSE;
    }
    //不添加这句会出现 0x0018 错误
    ProcessEntry32.dwSize = sizeof(ProcessEntry32);
    //遍历名字查找
    _tprintf(TEXT("ProcessID\tProcessImageName\r\n"));
    if (Process32First(hSnapshot, &ProcessEntry32))
    {
        do
        {
            _tprintf(TEXT("%d\t%s\r\n"), ProcessEntry32.th32ProcessIDProcessEntry32.szExeFile);
        } while (Process32Next(hSnapshot, &ProcessEntry32));
    }
    CloseHandle(hSnapshot);
    getchar();
}

二、Psapi

头文件:Psapi.h
关键函数:EnumProcessesOpenProcess,EnumProcessModules,GetProcessImageFileName,GetModuleBaseName
总结:由于该方法需要进程句柄,如果得不到进程句柄,什么信息都得不到,不建议使用。

// 注意:32位程序只能枚举32位程序,枚举不出64位程序
BOOL  EnumProcessByPsapi()
{
    TCHAR ProcessDosPath[0x200] = {};
    TCHAR ProcessNtPath[MAX_PATH];
    TCHAR ProcessName[MAX_PATH];
    DWORD ProcessID[1024];
    DWORD ProcessesCount;
    DWORD CbNeeded;
    
    HANDLE ProcessHandle = NULL;
    HMODULE hMod = NULL;
    if (!EnumProcesses(ProcessIDsizeof(ProcessID), &CbNeeded))
    {
        return FALSE;
    }
    ProcessesCount = CbNeeded / sizeof(DWORD);
    _tprintf(TEXT("ProcessID\t ProcessImageName\t ProcessImageFullPath\r\n"));
    for (size_t i = 0; i < CbNeededi++)
    {
        if (0 != ProcessID[i])
        {
            // 没有PROCESS_VM_READ 权限是枚举不出来的
            ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                FALSEProcessID[i]);
            if (ProcessHandle != NULL)
            {
                // 完整路径
                if (GetProcessImageFileName(ProcessHandleProcessDosPath_countof(ProcessDosPath)) > NULL)
                {
                    // The GetProcessImageFileName function returns the path in device form, rather than drive letters.
                    // For example, the file name C:\Windows\System32\Ctype.nls would look as follows in 
                    // device form :\Device\Harddisk0\Partition1\Windows\System32\Ctype.nls
                    DosPathToNtPath(ProcessDosPathProcessNtPathMAX_PATH);
                }
                //进程名称()
                if (EnumProcessModules(ProcessHandle, &hModsizeof(hMod), &CbNeeded))
                {
                    GetModuleBaseName(ProcessHandlehModProcessNamesizeof(ProcessName) / sizeof(TCHAR));
                }
                else
                {
                    _stprintf_s(ProcessNameTEXT("%s"), TEXT("<unknow>"));
                }
                _tprintf(TEXT("%d\t%s\t%s\r\n"), ProcessID[i], ProcessNameProcessNtPath);
                CloseHandle(ProcessHandle);
            }
        }
    }
    return TRUE;
}
BOOL DosPathToNtPath(IN LPTSTR DosPathOUT LPTSTR NtPath,IN ULONG CchNtPath)
{
    // DosPath: \Device\HarddiskVolume2\Windows\System32\sihost.exe
    TCHAR DosPathOfVolume[0x200];
    TCHAR DeviceName[3] = TEXT("A:");
    
    TCHAR COMDeviceName[5] = TEXT("COM0");
    ULONG StringLength = 0;
    while (DeviceName[0] <= 'Z')  //Z
    {
        // 如果指定DeviceName为NULL,那么该函数将输出所有存在的 MS-DOS device names 
        if (QueryDosDevice(DeviceNameDosPathOfVolume, 0x100 /sizeof(TCHAR)))
        {
            // C: 对应的DosPath是 \Device\HarddiskVolume2
            StringLength = lstrlen(DosPathOfVolume);
            // \Device\HarddiskVolume2 --> \Device\HarddiskVolume2\Windows\System32\sihost.exe
            lstrcat(DosPathOfVolumeDosPath + StringLength);
            // 判断是否是待转换的路径
            if (lstrcmpi(DosPathOfVolumeDosPath) == NULL)
            {
                lstrcpy(NtPathDeviceName);  // D:
                lstrcat(NtPathDosPath + StringLength);  // D:\Windows\system32
                return TRUE;
            }
        }
        DeviceName[0]++;
    }
    while (COMDeviceName[3] <= '9')  //9
    {
        if (QueryDosDevice(COMDeviceNameDosPathOfVolumeMAX_PATH * 2) > NULL)
        {
            StringLength = lstrlen(DosPathOfVolume);
            lstrcat(DosPathOfVolume, (DosPath + StringLength));
            if (lstrcmpi(DosPathOfVolumeDosPath) == NULL)
            {
                lstrcpy(NtPathCOMDeviceName);
                lstrcat(NtPath, (DosPath + StringLength));
                return TRUE;
            }
        }
        COMDeviceName[3]++;
    }
    return FALSE;
}

三、NtQuerySystemInformation

头文件:Winternl.h(头文件中的结构体都是不全的,需要自己定义,通常都是从ntdll.dll 中 Get 到函数地址)
关键函数:NtQuerySystemInformation
关键宏:SystemProcessInformation
关键结构:SYSTEM_PROCESS_INFORMATION

BOOL EnumProcessByZwQuerySystemInformation()
{
    LPFN_NtQuerySystemInformation __NtQuerySystemInformation;
    HMODULE hNtdll = LoadLibraryW(L"ntdll.dll");
    if (!hNtdll)
    {
        return FALSE;
    }
    __NtQuerySystemInformation = (LPFN_NtQuerySystemInformation)GetProcAddress(hNtdll"NtQuerySystemInformation");
    if (!__NtQuerySystemInformation)
    {
        return FALSE;
    }
    PSYSTEM_PROCESS_INFORMATION SystemProcessInfo = NULL;
    DWORD ReturnLength = 0;
    DWORD BufferLength = 1;
    // 将BufferLength置位1,查询需要的缓冲区大小
    if (STATUS_INFO_LENGTH_MISMATCH == __NtQuerySystemInformation(SystemProcessInformation, &SystemProcessInfoBufferLength, &ReturnLength))
    {
        BufferLength = ReturnLength;
        SystemProcessInfo = (PSYSTEM_PROCESS_INFORMATION)malloc(BufferLength);
        
        if (!SystemProcessInfo)
        {
            return FALSE;
        }
        if (__NtQuerySystemInformation(SystemProcessInformationSystemProcessInfoBufferLength, &ReturnLength) != STATUS_SUCCESS)
        {
            GetLastError();
            return FALSE;
        }
        while (SystemProcessInfo->NextEntryOffset != 0)
        {
            wprintf(L"%d\t%s\r\n"SystemProcessInfo->UniqueProcessIdSystemProcessInfo->ImageName.Buffer);
            SystemProcessInfo = (PSYSTEM_PROCESS_INFORMATION)((PUINT8)SystemProcessInfo + SystemProcessInfo->NextEntryOffset);
        }
    }
}

四、WTSEnumerateProcesses

头文件:Wtsapi32.h(该方法需要获得计算机名,局域网内的其它计算机应该也能枚举)
关键函数:GetComputerName,WTSOpenServer,WTSEnumerateProcesses
关键结构:PWTS_PROCESS_INFO 

int EnumProcessByWTSEnumerateProcesses()
{
    TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 2];
    DWORD BufferSize;
    BufferSize = sizeof ComputerName - 1;
    GetComputerName(ComputerName, &BufferSize);
    PWTS_PROCESS_INFO wts;
    DWORD dwCount;
    HANDLE hWtsServer = WTSOpenServer(ComputerName);
    if (!WTSEnumerateProcesses(hWtsServer, 0, 1, &wts, &dwCount))
        return 0;
    for (DWORD i = 0; i < dwCounti++)
    {
        printf("%d\t%s\n"wts[i].ProcessIdwts[i].pProcessName);
    }
    getchar();
    return 0;
}

这篇关于Ring3枚举进程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1068068

相关文章

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

C++11作用域枚举(Scoped Enums)的实现示例

《C++11作用域枚举(ScopedEnums)的实现示例》枚举类型是一种非常实用的工具,C++11标准引入了作用域枚举,也称为强类型枚举,本文主要介绍了C++11作用域枚举(ScopedEnums... 目录一、引言二、传统枚举类型的局限性2.1 命名空间污染2.2 整型提升问题2.3 类型转换问题三、C

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

Java进程CPU使用率过高排查步骤详细讲解

《Java进程CPU使用率过高排查步骤详细讲解》:本文主要介绍Java进程CPU使用率过高排查的相关资料,针对Java进程CPU使用率高的问题,我们可以遵循以下步骤进行排查和优化,文中通过代码介绍... 目录前言一、初步定位问题1.1 确认进程状态1.2 确定Java进程ID1.3 快速生成线程堆栈二、分析

Java 枚举的基本使用方法及实际使用场景

《Java枚举的基本使用方法及实际使用场景》枚举是Java中一种特殊的类,用于定义一组固定的常量,枚举类型提供了更好的类型安全性和可读性,适用于需要定义一组有限且固定的值的场景,本文给大家介绍Jav... 目录一、什么是枚举?二、枚举的基本使用方法定义枚举三、实际使用场景代替常量状态机四、更多用法1.实现接

Python多进程、多线程、协程典型示例解析(最新推荐)

《Python多进程、多线程、协程典型示例解析(最新推荐)》:本文主要介绍Python多进程、多线程、协程典型示例解析(最新推荐),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定... 目录一、multiprocessing(多进程)1. 模块简介2. 案例详解:并行计算平方和3. 实现逻

C#通过进程调用外部应用的实现示例

《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下... 目录窗口程序类进程信息类 系统设置类 以WINFORM应用程序为例,在C#应用程序中调用python程序

Python如何精准判断某个进程是否在运行

《Python如何精准判断某个进程是否在运行》这篇文章主要为大家详细介绍了Python如何精准判断某个进程是否在运行,本文为大家整理了3种方法并进行了对比,有需要的小伙伴可以跟随小编一起学习一下... 目录一、为什么需要判断进程是否存在二、方法1:用psutil库(推荐)三、方法2:用os.system调用

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚