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

相关文章

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m

java 进程 返回值

实现 Callable 接口 与 Runnable 相比,Callable 可以有返回值,返回值通过 FutureTask 进行封装。 public class MyCallable implements Callable<Integer> {public Integer call() {return 123;}} public static void main(String[] args

C#关闭指定时间段的Excel进程的方法

private DateTime beforeTime;            //Excel启动之前时间          private DateTime afterTime;               //Excel启动之后时间          //举例          beforeTime = DateTime.Now;          Excel.Applicat

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

枚举相关知识点

1.是用户定义的数据类型,为一组相关的常量赋予有意义的名字。 2.enum常量本身带有类型信息,即Weekday.SUN类型是Weekday,编译器会自动检查出类型错误,在编译期间可检查错误。 3.enum定义的枚举类有什么特点。         a.定义的enum类型总是继承自java.lang.Enum,且不能被继承,因为enum被编译器编译为final修饰的类。         b.只能定义

Golang进程权限调度包runtime

关于 runtime 包几个方法: Gosched:让当前线程让出 cpu 以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行GOMAXPROCS:设置最大的可同时使用的 CPU 核数Goexit:退出当前 goroutine(但是defer语句会照常执行)NumGoroutine:返回正在执行和排队的任务总数GOOS:目标操作系统NumCPU:返回当前系统的 CPU 核数量 p

如何保证android程序进程不到万不得已的情况下,不会被结束

最近,做一个调用系统自带相机的那么一个功能,遇到的坑,在此记录一下。 设备:红米note4 问题起因 因为自定义的相机,很难满足客户的所有需要,比如:自拍杆的支持,优化方面等等。这些方面自定义的相机都不比系统自带的好,因为有些系统都是商家定制的,难免会出现一个奇葩的问题。比如:你在这款手机上运行,无任何问题,然而你换一款手机后,问题就出现了。 比如:小米的红米系列,你启用系统自带拍照功能后