博客参考:​​获取进程的信息​​

ReadProcessMemory 报错 ERROR_PARTIAL_COPY:部分读或者部分写主要原因就是32位程序读取64位程序进程信息

下面代码为获取进程启动参数代码:​​ProcUtils.h​

#pragma once

#define NT_SUCCESS(x) ((x) >= 0)
#define ProcessBasicInformation 0

typedef NTSTATUS(NTAPI *pfnNtWow64QueryInformationProcess64)(
IN HANDLE ProcessHandle,
IN ULONG ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);


typedef NTSTATUS(NTAPI *pfnNtWow64ReadVirtualMemory64)(
IN HANDLE ProcessHandle,
IN PVOID64 BaseAddress,
OUT PVOID Buffer,
IN ULONG64 Size,
OUT PULONG64 NumberOfBytesRead
);

typedef
NTSTATUS(WINAPI *pfnNtQueryInformationProcess)
(HANDLE ProcessHandle, ULONG ProcessInformationClass,
PVOID ProcessInformation, UINT32 ProcessInformationLength,
UINT32* ReturnLength);

typedef struct _PROCESS_BASIC_INFORMATION32 {
NTSTATUS ExitStatus;
UINT32 PebBaseAddress;
UINT32 AffinityMask;
UINT32 BasePriority;
UINT32 UniqueProcessId;
UINT32 InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION32;

typedef struct _UNICODE_STRING32
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING32, *PUNICODE_STRING32;

typedef struct _PEB32
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
UCHAR BitField;
ULONG Mutant;
ULONG ImageBaseAddress;
ULONG Ldr;
ULONG ProcessParameters;
ULONG SubSystemData;
ULONG ProcessHeap;
ULONG FastPebLock;
ULONG AtlThunkSListPtr;
ULONG IFEOKey;
ULONG CrossProcessFlags;
ULONG UserSharedInfoPtr;
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
ULONG ApiSetMap;
} PEB32, *PPEB32;

typedef struct _RTL_USER_PROCESS_PARAMETERS32 {
BYTE Reserved1[16];
ULONG Reserved2[10];
UNICODE_STRING32 ImagePathName;
UNICODE_STRING32 CommandLine;
} RTL_USER_PROCESS_PARAMETERS32, *PRTL_USER_PROCESS_PARAMETERS32;

typedef struct _PEB_LDR_DATA32
{
ULONG Length;
BOOLEAN Initialized;
ULONG SsHandle;
LIST_ENTRY32 InLoadOrderModuleList;
LIST_ENTRY32 InMemoryOrderModuleList;
LIST_ENTRY32 InInitializationOrderModuleList;
ULONG EntryInProgress;
} PEB_LDR_DATA32, *PPEB_LDR_DATA32;

typedef struct _LDR_DATA_TABLE_ENTRY32
{
LIST_ENTRY32 InLoadOrderLinks;
LIST_ENTRY32 InMemoryOrderModuleList;
LIST_ENTRY32 InInitializationOrderModuleList;
ULONG DllBase;
ULONG EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING32 FullDllName;
UNICODE_STRING32 BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY32 HashLinks;
ULONG SectionPointer;
};
ULONG CheckSum;
union
{
ULONG TimeDateStamp;
ULONG LoadedImports;
};
ULONG EntryPointActivationContext;
ULONG PatchInformation;
} LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32;

typedef struct _PROCESS_BASIC_INFORMATION64 {
NTSTATUS ExitStatus;
UINT32 Reserved0;
UINT64 PebBaseAddress;
UINT64 AffinityMask;
UINT32 BasePriority;
UINT32 Reserved1;
UINT64 UniqueProcessId;
UINT64 InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION64;

typedef struct _PEB64
{
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
UCHAR BitField;
ULONG64 Mutant;
ULONG64 ImageBaseAddress;
ULONG64 Ldr;
ULONG64 ProcessParameters;
ULONG64 SubSystemData;
ULONG64 ProcessHeap;
ULONG64 FastPebLock;
ULONG64 AtlThunkSListPtr;
ULONG64 IFEOKey;
ULONG64 CrossProcessFlags;
ULONG64 UserSharedInfoPtr;
ULONG SystemReserved;
ULONG AtlThunkSListPtr32;
ULONG64 ApiSetMap;
} PEB64, *PPEB64;

typedef struct _PEB_LDR_DATA64
{
ULONG Length;
BOOLEAN Initialized;
ULONG64 SsHandle;
LIST_ENTRY64 InLoadOrderModuleList;
LIST_ENTRY64 InMemoryOrderModuleList;
LIST_ENTRY64 InInitializationOrderModuleList;
ULONG64 EntryInProgress;
} PEB_LDR_DATA64, *PPEB_LDR_DATA64;

typedef struct _UNICODE_STRING64
{
USHORT Length;
USHORT MaximumLength;
ULONG64 Buffer;
} UNICODE_STRING64, *PUNICODE_STRING64;

typedef struct _LDR_DATA_TABLE_ENTRY64
{
LIST_ENTRY64 InLoadOrderLinks;
LIST_ENTRY64 InMemoryOrderModuleList;
LIST_ENTRY64 InInitializationOrderModuleList;
ULONG64 DllBase;
ULONG64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING64 FullDllName;
UNICODE_STRING64 BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY64 HashLinks;
ULONG64 SectionPointer;
};
ULONG CheckSum;
union
{
ULONG TimeDateStamp;
ULONG64 LoadedImports;
};
ULONG64 EntryPointActivationContext;
ULONG64 PatchInformation;
} LDR_DATA_TABLE_ENTRY64, *PLDR_DATA_TABLE_ENTRY64;

typedef struct _RTL_USER_PROCESS_PARAMETERS64 {
BYTE Reserved1[16];
ULONG64 Reserved2[10];
UNICODE_STRING64 ImagePathName;
UNICODE_STRING64 CommandLine;
} RTL_USER_PROCESS_PARAMETERS64, *PRTL_USER_PROCESS_PARAMETERS64;

class ProcUtils
{
public:
static bool get_proc_id(const std::string& proc_name, DWORD &pid);
static int get_proc_command(DWORD pid, std::string& cmd_line);
};

​ProcUtils.cpp​

#include "stdafx.h"
#include "ProcUtils.h"
#include <algorithm>
#include <Tlhelp32.h>
#include "StringUtil.h"

bool ProcUtils::get_proc_id(const std::string& proc_name, DWORD& pid)
{
pid = 0;
HANDLE proc_snap = INVALID_HANDLE_VALUE;
bool ret_value = false;
do {
if (!proc_name.length()) break;
std::string proc_name_tmp = proc_name;
std::transform(proc_name_tmp.begin(), proc_name_tmp.end(), proc_name_tmp.begin(), ::tolower);
proc_snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == proc_snap) break;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
BOOL flag = ::Process32First(proc_snap, &pe32);
while (flag)
{
std::string exe_name = pe32.szExeFile;
std::transform(exe_name.begin(), exe_name.end(), exe_name.begin(), ::tolower);
if (exe_name == proc_name_tmp)
{
ret_value = true;
pid = pe32.th32ProcessID;
break;
}
flag = ::Process32Next(proc_snap, &pe32);
}
} while (0);

if (INVALID_HANDLE_VALUE != proc_snap)
{
CloseHandle(proc_snap);
proc_snap = INVALID_HANDLE_VALUE;
}
return ret_value;
}

int ProcUtils::get_proc_command(DWORD pid, std::string& cmd_line)
{

HANDLE proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_ALL_ACCESS, false, pid);
int err = GetLastError();
if (NULL == proc) return -2;

BOOL bTarget = FALSE;
BOOL bSource = FALSE;
IsWow64Process(GetCurrentProcess(), &bSource);
IsWow64Process(proc, &bTarget);
SYSTEM_INFO si = {0};
GetSystemInfo(&si);

if (bTarget == FALSE && bSource == TRUE)
{
HMODULE NtdllModule = GetModuleHandle("ntdll.dll");
pfnNtWow64QueryInformationProcess64 NtWow64QueryInformationProcess64 = (pfnNtWow64QueryInformationProcess64)GetProcAddress(NtdllModule, "NtWow64QueryInformationProcess64");
pfnNtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = (pfnNtWow64ReadVirtualMemory64)GetProcAddress(NtdllModule, "NtWow64ReadVirtualMemory64");
PROCESS_BASIC_INFORMATION64 pbi64 = { 0 };
if (NT_SUCCESS(NtWow64QueryInformationProcess64(proc, ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL)))
{
PEB64 peb = { 0 };
if (NT_SUCCESS(NtWow64ReadVirtualMemory64(proc, (PVOID64)(pbi64.PebBaseAddress), &peb, sizeof(peb), NULL)))
{
RTL_USER_PROCESS_PARAMETERS64 user_proc_params = { 0 };
if (NT_SUCCESS(NtWow64ReadVirtualMemory64(proc, (PVOID64)(peb.ProcessParameters), &user_proc_params, sizeof(user_proc_params), NULL)))
{
wchar_t buf[4096] = { 0 };
DWORD data_size = user_proc_params.CommandLine.Length > 4090 ? 4090 : user_proc_params.CommandLine.Length;
if (NT_SUCCESS(NtWow64ReadVirtualMemory64(proc, (PVOID64)(user_proc_params.CommandLine.Buffer), &buf, data_size, NULL)))
{
cmd_line = StringUtil::Easy_UnicodeToAnsi(buf + 1);
}
}
}
}

}
else if (bTarget == TRUE && bSource == TRUE || si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64 ||
si.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_IA64)
{
HMODULE NtdllModule = GetModuleHandle("ntdll.dll");
pfnNtQueryInformationProcess NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(NtdllModule, "NtQueryInformationProcess");
PROCESS_BASIC_INFORMATION32 pbi32 = { 0 };
if (NT_SUCCESS(NtQueryInformationProcess(proc, ProcessBasicInformation, &pbi32, sizeof(pbi32), NULL)))
{
PEB32 peb = { 0 };
if (ReadProcessMemory(proc, (PVOID)(pbi32.PebBaseAddress), &peb, sizeof(peb), NULL))
{
RTL_USER_PROCESS_PARAMETERS32 user_proc_params = {0};
if (ReadProcessMemory(proc, (PVOID)(peb.ProcessParameters), &user_proc_params, sizeof(user_proc_params), NULL))
{
wchar_t buf[4096] = { 0 };
DWORD data_size = user_proc_params.CommandLine.Length > 4090 ? 4090 : user_proc_params.CommandLine.Length;
if (ReadProcessMemory(proc, (PVOID)(user_proc_params.CommandLine.Buffer), &buf, data_size, NULL))
{
cmd_line = StringUtil::Easy_UnicodeToAnsi(buf + 1);
}
}
}
}
}
CloseHandle(proc);


return 0;
}