参考 Windows核心编程(第5版中文版) source code
04-ProcessInfo
#include <windows.h>
#include <winternl.h>
#include <Psapi.h>
typedef struct
{
DWORD Filler[4];
DWORD InfoBlockAddress;
} __PEB;
typedef struct
{
DWORD Filler[17];
DWORD wszCmdLineAddress;
} __INFOBLOCK;
typedef NTSTATUS(CALLBACK* PFN_NTQUERYINFORMATIONPROCESS)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength OPTIONAL
);
NTSTATUS _NtQueryInformationProcess(
HANDLE hProcess,
PROCESSINFOCLASS pic,
PVOID pPI,
ULONG cbSize,
PULONG pLength);
bool GetProcessCmdLine(DWORD PID, WCHAR* szCmdLine, DWORD Size);
NTSTATUS _NtQueryInformationProcess(
HANDLE hProcess,
PROCESSINFOCLASS pic,
PVOID pPI,
ULONG cbSize,
PULONG pLength)
{
HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll"));
if (hNtDll == NULL)
return -1;
NTSTATUS lStatus = -1;
PFN_NTQUERYINFORMATIONPROCESS pfnNtQIP = (PFN_NTQUERYINFORMATIONPROCESS)GetProcAddress(hNtDll, "NtQueryInformationProcess");
if (pfnNtQIP != NULL)
lStatus = pfnNtQIP(hProcess, pic, pPI, cbSize, pLength);
FreeLibrary(hNtDll);
return lStatus;
}
bool GetProcessCmdLine(DWORD PID, WCHAR* szCmdLine, DWORD Size)
{
if ((PID <= 0) || (szCmdLine == NULL) || (Size == 0))
return false;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
if (hProcess == NULL)
return false;
int iReturn = 1;
DWORD dwSize;
SIZE_T size;
// 0. 获取进程环境块的地址
PROCESS_BASIC_INFORMATION pbi;
iReturn = _NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), &dwSize);
if (iReturn < 0)
return false;
// 1. 获取进程环境块
__PEB PEB;
size = dwSize;
if (ReadProcessMemory(hProcess, pbi.PebBaseAddress, &PEB, sizeof(PEB), &size) == 0)
return false;
// 2. 获取PEB块的地址(PEB包含执行命令行地址的指针)
__INFOBLOCK Block;
if (ReadProcessMemory(hProcess, (LPVOID)PEB.InfoBlockAddress, &Block, sizeof(Block), &size) == 0)
return false;
// 3. 获取命令行
WCHAR wszCmdLine[PROCESSCMDLINE_LENGTH] = { 0 };
if (ReadProcessMemory(hProcess, (LPVOID)Block.wszCmdLineAddress, wszCmdLine, sizeof(wszCmdLine), &size) == 0)
return false;
// 4. 拷贝命令行
WCHAR* pPos = wszCmdLine;
if (pPos != NULL)
{
if (*pPos != L'\0')
wcscpy_s(szCmdLine, Size, pPos);
else
szCmdLine[0] = TEXT('\0');
}
else
{
szCmdLine[0] = TEXT('\0');
}
CloseHandle(hProcess);
return true;
}
我是江鸟,即将迈向社会的程序猿,欢迎交流~