读取另一个进程的环境变量
问题描述:
我正在尝试获取进程环境字符串,下面的代码是我已经编写的.
I'm trying to get a process environment strings, the code below is what I already wrote.
#include <windows.h>
#include <tchar.h>
#define ProcessBasicInformation 0
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR AffinityMask;
LONG BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
int _tmain(int argc, TCHAR* argv[]) {
TCHAR *app;
DWORD pid;
HANDLE proc;
NTSTATUS nts;
PVOID rupp; // RTL_USER_PROCESS_PARAMETERS, offset 0x10
PVOID env; // Environment, offset 0x48
TCHAR *buf;
PROCESS_BASIC_INFORMATION pbi;
MEMORY_BASIC_INFORMATION mbi;
if (argc != 2) {
app = _tcsrchr(argv[0], '\\');
_tprintf(TEXT("Usage: %s [PID]\n"), app ? ++app : argv[0]);
return -1;
}
_stscanf_s(argv[1], TEXT("%lu"), &pid);
if (!(proc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid))) {
return -1;
}
if (!(nts = NtQueryInformationProcess(
proc, ProcessBasicInformation, &pbi, sizeof(pbi), NULL
))) {
if (ReadProcessMemory(
proc, (PCHAR)pbi.PebBaseAddress + 0x10, &rupp, sizeof(rupp), NULL
)) {
if (ReadProcessMemory(proc, (PCHAR)rupp + 0x48, &env, sizeof(env), NULL)) {
//what I need to do to get enironment strings?
}
}
}
CloseHandle(proc);
return 0;
}
有人可以解释我需要做什么才能获取进程的环境字符串吗?
Can somebody explain what I need to do to get environment strings of a process?
答
首先你的代码只适用于 x86,但是 x64 系统呢?在 x64 上,您必须从 x64 代码运行才能访问 x64 进程的环境.但是 Wow64 进程呢?他们有 2 个环境!1 天真和 1 哇,这不是等号的字符串.所以任务可以足够复杂.但当然存在解决方案.
first of all your code only for x86, but how about x64 systems ? on x64 you must run from x64 code for access environment of x64 processes. but how about Wow64 processes ? they have 2 environments ! 1 naive and 1 Wow and this is not equal strings. so task can be enough complex. but however of course exist solution.
NTSTATUS ReadProcessEnv(HANDLE hProcess, PVOID Environment, PWSTR* ppsz)
{
NTSTATUS status;
MEMORY_BASIC_INFORMATION mbi;
if (0 > (status = ZwQueryVirtualMemory(hProcess, Environment, MemoryBasicInformation, &mbi, sizeof(mbi), 0))) return status;
if (mbi.State != MEM_COMMIT || mbi.Type != MEM_PRIVATE)
{
return STATUS_UNSUCCESSFUL;
}
mbi.RegionSize -= RtlPointerToOffset(mbi.BaseAddress, Environment);
//Environment must be WCHAR aligned and how minimum 2*sizeof(WCHAR) size
if (mbi.RegionSize < 2*sizeof(WCHAR) || ((ULONG_PTR)Environment & (__alignof(WCHAR) - 1)))
{
return STATUS_UNSUCCESSFUL;
}
if (mbi.RegionSize > 0x10000)// >64Kb Environment ??
{
mbi.RegionSize = 0x10000;
}
if (PWSTR buf = new WCHAR[mbi.RegionSize])
{
if (0 <= (status = ZwReadVirtualMemory(hProcess, Environment, buf, mbi.RegionSize, 0)))
{
buf[mbi.RegionSize - 2] = 0;
buf[mbi.RegionSize - 1] = 0;
*ppsz = buf;
return STATUS_SUCCESS;
}
delete buf;
return status;
}
return STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS ReadProcessEnv(HANDLE hProcess, PWSTR* ppsz)
{
NTSTATUS status;
PROCESS_BASIC_INFORMATION pbi;
_RTL_USER_PROCESS_PARAMETERS* ProcessParameters;
PVOID Environment;
if (
0 > (status = ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), 0))
||
0 > (status = ZwReadVirtualMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters, &ProcessParameters, sizeof(PVOID), 0))
||
0 > (status = ZwReadVirtualMemory(hProcess, &ProcessParameters->Environment, &Environment, sizeof(PVOID), 0))
)
return status;
return ReadProcessEnv(hProcess, Environment, ppsz);
}
#ifdef _WIN64
NTSTATUS ReadProcessEnvWow(HANDLE hProcess, PWSTR* ppsz)
{
ULONG WowPeb, ProcessParameters;
NTSTATUS status;
PVOID Environment = 0;
if (0 > (status = ZwQueryInformationProcess(hProcess, ProcessWow64Information, &WowPeb, sizeof(PVOID), 0))) return status;
if (!WowPeb)
{
return STATUS_SUCCESS;
}
enum {
ofs32_ProcessParameters = 0x10,
ofs32_Environment = 0x48
};
if (
0 > (status = ZwReadVirtualMemory(hProcess, RtlOffsetToPointer(WowPeb, ofs32_ProcessParameters), &ProcessParameters, sizeof(ULONG), 0))
||
0 > (status = ZwReadVirtualMemory(hProcess, RtlOffsetToPointer(ProcessParameters, ofs32_Environment), &Environment, sizeof(ULONG), 0))
)
return status;
return ReadProcessEnv(hProcess, Environment, ppsz);
}
#endif
NTSTATUS ReadProcessEnv(
PCLIENT_ID cid,
PWSTR* ppsz,
PNTSTATUS pstatus
#ifdef _WIN64
,
PWSTR* ppszWow,
PNTSTATUS pstatusWow
#endif
)
{
HANDLE hProcess;
NTSTATUS status = ZwOpenProcess(&hProcess, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, &zoa, cid);
if (0 <= status)
{
*ppsz = 0;
*pstatus = ReadProcessEnv(hProcess, ppsz);
#ifdef _WIN64
*ppszWow = 0;
*pstatusWow = ReadProcessEnvWow(hProcess, ppszWow);
#endif
ZwClose(hProcess);
}
return status;
}
void DumpEnv(PCWSTR sz)
{
while (*sz)
{
DbgPrint("%S\n", sz);
sz += wcslen(sz) + 1;
}
}
void test(PCLIENT_ID cid)
{
PWSTR env, envWow;
NTSTATUS status, s;
#ifdef _WIN64
NTSTATUS sWow;
#endif
if (0 <= (status = ReadProcessEnv(cid, &env, &s
#ifdef _WIN64
, &envWow, &sWow
#endif
)))
{
if (0 <= s)
{
DumpEnv(env);
delete env;
}
#ifdef _WIN64
if (0 <= sWow)
{
if (envWow)
{
DumpEnv(envWow);
delete envWow;
}
}
#endif
}
}