WIN32API获取进程句柄的2种方式

摘要:
0x00相关描述:在Windows系统中,进程句柄是进程最重要的属性之一。在应用程序层,可以通过进程句柄直接读写指定进程的内存空间。0x01通过进程名称获取进程句柄:首先通过进程名称获得进程ID:1.通过CreateToolhelp32Snapshot获取当前系统中所有进程的快照。2.通过Process32First判断第一进程的信息是否正常。3.通过Process32Next循环所有快照信息,
0x00 相关说明:

Windows系统中,进程句柄是进程最重要的属性之一,在应用层可以通过进程句柄直接对指定进程的内存空间进行读写。

0x01 通过进程名获取进程句柄:

首先通过进程名得到进程ID:

1、 通过 CreateToolhelp32Snapshot 获得当前系统中所有进程的快照

2、 通过 Process32First 判断第一个进程的信息是否正常

3、 通过 Process32Next 结合循环遍历所有的快照信息,使用进程名筛选出目标进程

通过进程ID获取进程句柄:

使用 OpenProcess 可以通过进程ID获取进程句柄

完整代码如下:

HANDLE GetProcessHandle(LPCWSTR lpName)
{
     DWORD dwPid = 0;
     HANDLE hProcess = NULL;
     HANDLE hProcessSnap;
     PROCESSENTRY32 pe32;

    // Take a snapshot of all processes in the system.
     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     if (hProcessSnap == INVALID_HANDLE_VALUE)
     {
         //printf("Error: CreateToolhelp32Snapshot (of processes) ");
         return NULL;
     }

    // Set the size of the structure before using it.
     pe32.dwSize = sizeof(PROCESSENTRY32);

    // Retrieve information about the first process,
     // and exit if unsuccessful
     if (!Process32First(hProcessSnap, &pe32))
     {
         //printf("Error: Process32First "); // show cause of failure
         CloseHandle(hProcessSnap);          // clean the snapshot object
         return NULL;
     }

    // Now walk the snapshot of processes, and
     // display information about each process in turn
     int namelen = 200;
     char name[201] = { 0 };
     do
     {
         if (!wcscmp(pe32.szExeFile, lpName)) {
             dwPid = pe32.th32ProcessID;
             hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
             break;
         }

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

    CloseHandle(hProcessSnap);
     return hProcess;
}

需要包含的头文件:

#include <windows.h>
#include <TlHelp32.h>
#include <Psapi.h>

0x02 通过窗口标题获取进程句柄:

大部分的Windows应用程序都有窗口,通过窗口标题获取进程句柄非常简单:

HANDLE GetProcessHandle(LPCWSTR lpName)
{
     DWORD dwPid = 0;

    HWND hWnd = FindWindowW(NULL, lpName);
     if (hWnd == NULL) {
         return;
     }
     GetWindowThreadProcessId(hWnd, &dwPid);
     return OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
}

0x03 封装代码:

可以将上面的代码以及常用的进程读写封装在一起,方便后续的使用:

新建 Process.h :

#pragma once

#include <stdio.h>
#include <windows.h>
#include <TlHelp32.h>
#include <Psapi.h>

class Process
{
public:
     Process();
     ~Process();
     Process(LPCWSTR lpName/*ProcessName/WindowTitle*/, BOOL bWindow = FALSE);

public:
     BYTE ReadByte(LPCVOID addr, BYTE *data);
     int ReadInt(LPCVOID addr, int *data);
     long ReadLong(LPCVOID addr, long *data);
     WORD ReadWord(LPCVOID addr, WORD *data);
     DWORD ReadDword(LPCVOID addr, DWORD *data);
     float ReadFloat(LPCVOID addr, float *data);
     double ReadDouble(LPCVOID addr, double *data);
     BYTE* ReadByteArray(LPCVOID addr, BYTE *data, size_t length);

    BOOL WriteByte(LPVOID addr, BYTE data);
     BOOL WriteInt(LPVOID addr, int data);
     BOOL WriteLong(LPVOID addr, long data);
     BOOL WriteWord(LPVOID addr, WORD data);
     BOOL WriteDword(LPVOID addr, DWORD data);
     BOOL WriteFloat(LPVOID addr, float data);
     BOOL WriteDouble(LPVOID addr, double data);
     BOOL WriteByteArray(LPVOID addr, BYTE *data, size_t length);

    HMODULE GetModuleAddr(LPCWSTR lpModuleName);

public:
     DWORD dwPid=0;
     HANDLE hProcess=NULL;
};

新建 Process.cpp :

#include "Process.h"


Process::Process()
{
}

Process::~Process()
{
     if(this->hProcess){
         CloseHandle(this->hProcess);
     }
}

Process::Process(LPCWSTR lpName/*ProcessName/WindowTitle*/, BOOL bWindow)
{
     if (bWindow){
         HWND hWnd = FindWindowW(NULL, lpName);
         if(hWnd == NULL){
             return;
         }
         GetWindowThreadProcessId(hWnd, &(this->dwPid));
         this->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->dwPid);
     }
     else {
         HANDLE hProcessSnap;
         PROCESSENTRY32 pe32;

        // Take a snapshot of all processes in the system.
         hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
         if (hProcessSnap == INVALID_HANDLE_VALUE)
         {
             //printf("Error: CreateToolhelp32Snapshot (of processes) ");
             return;
         }

        // Set the size of the structure before using it.
         pe32.dwSize = sizeof(PROCESSENTRY32);

        // Retrieve information about the first process,
         // and exit if unsuccessful
         if (!Process32First(hProcessSnap, &pe32))
         {
             //printf("Error: Process32First "); // show cause of failure
             CloseHandle(hProcessSnap);          // clean the snapshot object
             return;
         }

        // Now walk the snapshot of processes, and
         // display information about each process in turn
         int namelen = 200;
         char name[201] = { 0 };
         do
         {
             if (!wcscmp(pe32.szExeFile, lpName)) {
                 this->dwPid = pe32.th32ProcessID;
                 this->hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, this->dwPid);
                 break;
             }

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

        CloseHandle(hProcessSnap);
     }
}


BYTE Process::ReadByte(LPCVOID addr, BYTE *data)
{
     BYTE  ret;
     ReadProcessMemory(this->hProcess, addr, &ret, sizeof(BYTE), NULL);
     if(data != NULL)   
         * data = ret;
     return ret;
}

int Process::ReadInt(LPCVOID addr, int *data)
{
     int  ret;
     ReadProcessMemory(this->hProcess, addr, &ret, sizeof(int), NULL);
     if (data != NULL)
         * data = ret;
     return ret;
}

long Process::ReadLong(LPCVOID addr, long *data)
{
     long  ret;
     return ReadProcessMemory(this->hProcess, addr, &ret, sizeof(long), NULL);
     if (data != NULL)
         * data = ret;
     return ret;
}

WORD Process::ReadWord(LPCVOID addr, WORD *data)
{
     WORD  ret;
     ReadProcessMemory(this->hProcess, addr, &ret, sizeof(WORD), NULL);
     if (data != NULL)
         * data = ret;
     return ret;
}

DWORD Process::ReadDword(LPCVOID addr, DWORD *data)
{
     DWORD  ret;
     ReadProcessMemory(this->hProcess, addr, &ret, sizeof(DWORD), NULL);
     if (data != NULL)
         * data = ret;
     return ret;
}

float Process::ReadFloat(LPCVOID addr, float *data)
{
     float  ret;
     ReadProcessMemory(this->hProcess, addr, &ret, sizeof(float), NULL);
     if (data != NULL)
         * data = ret;
     return ret;
}

double Process::ReadDouble(LPCVOID addr, double *data)
{
     double  ret;
     return ReadProcessMemory(this->hProcess, addr, &ret, sizeof(double), NULL);
     if (data != NULL)
         * data = ret;
     return ret;
}

BYTE* Process::ReadByteArray(LPCVOID addr, BYTE *data, size_t length)
{
     if (data == NULL)
         exit(-1);
     ReadProcessMemory(this->hProcess, addr, data, sizeof(BYTE)*length, NULL);
     return data;
}


BOOL Process::WriteByte(LPVOID addr, BYTE data)
{
     return WriteProcessMemory(this->hProcess, addr, &data, sizeof(BYTE), NULL);
}

BOOL Process::WriteInt(LPVOID addr, int data)
{
     return WriteProcessMemory(this->hProcess, addr, &data, sizeof(int), NULL);
}

BOOL Process::WriteLong(LPVOID addr, long data)
{
     return WriteProcessMemory(this->hProcess, addr, &data, sizeof(long), NULL);
}

BOOL Process::WriteWord(LPVOID addr, WORD data)
{
     return WriteProcessMemory(this->hProcess, addr, &data, sizeof(WORD), NULL);
}

BOOL Process::WriteDword(LPVOID addr, DWORD data)
{
     return WriteProcessMemory(this->hProcess, addr, &data, sizeof(DWORD), NULL);
}

BOOL Process::WriteFloat(LPVOID addr, float data)
{
     return WriteProcessMemory(this->hProcess, addr, &data, sizeof(float), NULL);
}

BOOL Process::WriteDouble(LPVOID addr, double data)
{
     return WriteProcessMemory(this->hProcess, addr, &data, sizeof(double), NULL);
}

BOOL Process::WriteByteArray(LPVOID addr, BYTE *data, size_t length)
{
     return WriteProcessMemory(this->hProcess, addr, data, sizeof(BYTE)*length, NULL);
}


HMODULE Process::GetModuleAddr(LPCWSTR lpModuleName)
{
     HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
     MODULEENTRY32 me32;
     HMODULE hModule = 0;

    // Take a snapshot of all modules in the specified process.
     hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, this->dwPid);
     if (hModuleSnap == INVALID_HANDLE_VALUE)
     {
         //printf("Error: CreateToolhelp32Snapshot (of modules) ");
         return NULL;
     }

    // Set the size of the structure before using it.
     me32.dwSize = sizeof(MODULEENTRY32);

    // Retrieve information about the first module,
     // and exit if unsuccessful
     if (!Module32First(hModuleSnap, &me32))
     {
         //printf("Error: Module32First ");  // show cause of failure
         CloseHandle(hModuleSnap);     // clean the snapshot object
         return NULL;
     }

    // Now walk the module list of the process,
     // and display information about each module
     do
     {
         if (!wcscmp(lpModuleName, me32.szModule)) {
             hModule = (HMODULE)me32.modBaseAddr;
             CloseHandle(hModuleSnap);
             return hModule;
         }

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

    CloseHandle(hModuleSnap);
     return NULL;
}

免责声明:文章转载自《WIN32API获取进程句柄的2种方式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WPF-悬浮窗(类似于360)arm64平台 Kubernetes 及 Harbor 离线部署方案下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C++里大写TRUE和小写true区别

1.C++里有区别true是bool型的;TRUE是int型的,VC里这个是ms自己定义的; C++规定不允许只通过返回类型不同区别两个函数================================================你写错了吧……原函数声明是virtual BOOL InitInstance( );你函数声明是bool,麻烦把它写成...

通过注册表修改证书选项

Windows Registry Editor Version 5.00 #不检查发行商的证书是否吊销[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionWinTrustTrust ProvidersSoftware Publishing]"State"=dword:00023e00 #不检查服务...

C++ Primer第5版 第四章课后练习答案

练习4.1 105 练习4.2 (a) *(vec.begin())  (b) (*vec.begin()+1) 练习4.3 可以,不过这需要程序员对于编译器优化过程有更深入的了解。 练习4.4 12 / 3 * 4 + 5 * 15 + 24 % 4 / 2;/*结果是91*/12 / 3 * (4 + 5) * 15 + 24 % 4 / 2;/*结果...

linux系统socket通信编程1

Linux下的Socket编程大体上包括Tcp Socket、Udp Socket即Raw Socket这三种,其中TCP和UDP方式的Socket编程用于编写应用层的socket程序,是我们用得比较多的,而Raw Socket则用得相对较少,不在本文介绍范围之列。 TCP Socket 基于TCP协议的客户端/服务器程序的一般流程一般如下: 它基本上可...

bmp24位彩色图像转8位灰度图像(纯C++)

自从上一次写了bmp文件格式分析,后来是准备马上就写程序了,谁知后来就忘了,昨天突然想起来就将其写了出来。 程序的功能是将彩色图转灰度图,中间彩色和灰度的文件header都用到了,程序的流程我想我写的还是比较清楚的。没有用到Windows下的某些函数,在Linux下应该也能运行。 #include <iostream>#include <...

windows的磁盘操作之八——格式化分区的思考

格式化分区平常在我们看来是再普通不过的操作了,点两下鼠标就可以搞定的事情,但是在程序中实现的的确确不太容易。可能有人说直接调个format命令不就好了,没错,但系统命令存在我们第一节http://cutebunny.blog.51cto.com/301216/624027中阐述的种种问题。 算上format命令,目前我发现有三种方法, 1.Windows...