[SIGAR-67] Change windows proc_exe impl to use PEB
This commit is contained in:
parent
3f79564ffd
commit
f314a01aa4
|
@ -181,3 +181,24 @@ int sigar_proc_args_peb_get(sigar_t *sigar, HANDLE proc,
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sigar_proc_env_peb_get(sigar_t *sigar, HANDLE proc,
|
||||||
|
WCHAR *buf, DWORD size)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
RTL_USER_PROCESS_PARAMETERS rtl;
|
||||||
|
|
||||||
|
if ((status = sigar_rtl_get(sigar, proc, &rtl)) != SIGAR_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buf, '\0', size);
|
||||||
|
|
||||||
|
/* -2 to ensure \0\0 terminator */
|
||||||
|
if (ReadProcessMemory(proc, rtl.Environment, buf, size-2, NULL)) {
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -564,6 +564,9 @@ int sigar_proc_exe_peb_get(sigar_t *sigar, HANDLE proc,
|
||||||
int sigar_proc_args_peb_get(sigar_t *sigar, HANDLE proc,
|
int sigar_proc_args_peb_get(sigar_t *sigar, HANDLE proc,
|
||||||
sigar_proc_args_t *procargs);
|
sigar_proc_args_t *procargs);
|
||||||
|
|
||||||
|
int sigar_proc_env_peb_get(sigar_t *sigar, HANDLE proc,
|
||||||
|
WCHAR *env, DWORD envlen);
|
||||||
|
|
||||||
int sigar_parse_proc_args(sigar_t *sigar, WCHAR *buf,
|
int sigar_parse_proc_args(sigar_t *sigar, WCHAR *buf,
|
||||||
sigar_proc_args_t *procargs);
|
sigar_proc_args_t *procargs);
|
||||||
|
|
||||||
|
|
|
@ -1332,13 +1332,8 @@ int sigar_os_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sigar_local_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
static int sigar_proc_env_parse(UCHAR *ptr, sigar_proc_env_t *procenv)
|
||||||
sigar_proc_env_t *procenv)
|
|
||||||
{
|
{
|
||||||
UCHAR *ptr, *env;
|
|
||||||
|
|
||||||
env = ptr = (UCHAR*)GetEnvironmentStrings();
|
|
||||||
|
|
||||||
while (*ptr) {
|
while (*ptr) {
|
||||||
char *val;
|
char *val;
|
||||||
int klen, vlen, status;
|
int klen, vlen, status;
|
||||||
|
@ -1367,12 +1362,22 @@ static int sigar_local_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
|
|
||||||
if (status != SIGAR_OK) {
|
if (status != SIGAR_OK) {
|
||||||
/* not an error; just stop iterating */
|
/* not an error; just stop iterating */
|
||||||
break;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += klen + 1 + vlen + 1;
|
ptr += klen + 1 + vlen + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SIGAR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sigar_local_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
|
sigar_proc_env_t *procenv)
|
||||||
|
{
|
||||||
|
UCHAR *env = (UCHAR*)GetEnvironmentStrings();
|
||||||
|
|
||||||
|
sigar_proc_env_parse(env, procenv);
|
||||||
|
|
||||||
FreeEnvironmentStrings(env);
|
FreeEnvironmentStrings(env);
|
||||||
|
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
|
@ -1381,115 +1386,33 @@ static int sigar_local_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
static int sigar_remote_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
static int sigar_remote_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
sigar_proc_env_t *procenv)
|
sigar_proc_env_t *procenv)
|
||||||
{
|
{
|
||||||
FARPROC rgetenv, fstrlen;
|
|
||||||
HANDLE proc, thread, kdll;
|
|
||||||
PVOID data=NULL;
|
|
||||||
const char *key;
|
|
||||||
char *value;
|
|
||||||
DWORD rv, thrid, bytes, datalen=0, size;
|
|
||||||
LPVOID addr;
|
|
||||||
int status;
|
int status;
|
||||||
|
HANDLE proc = open_process(pid);
|
||||||
|
WCHAR env[4096];
|
||||||
|
|
||||||
/*
|
if (!proc) {
|
||||||
* Do not FreeLibrary(kdll), see:
|
|
||||||
* http://msdn2.microsoft.com/en-us/library/ms683199.aspx
|
|
||||||
*/
|
|
||||||
if (!(kdll = GetModuleHandle("msvcrt.dll"))) {
|
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(rgetenv = GetProcAddress(kdll, "getenv"))) {
|
status = sigar_proc_env_peb_get(sigar, proc, env, sizeof(env));
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(kdll = GetModuleHandle("kernel32.dll"))) {
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(fstrlen = GetProcAddress(kdll, "lstrlenA"))) {
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(proc = OpenProcess(MAXIMUM_ALLOWED, 0, (DWORD)pid))) {
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
key = procenv->key;
|
|
||||||
size = procenv->klen+1;
|
|
||||||
addr = VirtualAllocEx(proc, NULL, size,
|
|
||||||
MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
|
||||||
if (!addr) {
|
|
||||||
CloseHandle(proc);
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!WriteProcessMemory(proc, addr, (char*)&key[0], size, 0)) {
|
|
||||||
VirtualFreeEx(proc, addr, size, 0);
|
|
||||||
CloseHandle(proc);
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
thread = CreateRemoteThread(proc, NULL, 0,
|
|
||||||
(LPTHREAD_START_ROUTINE)rgetenv,
|
|
||||||
addr, 0, &thrid);
|
|
||||||
if (!thread) {
|
|
||||||
VirtualFreeEx(proc, addr, size, 0);
|
|
||||||
CloseHandle(proc);
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitForSingleObject(thread, INFINITE);
|
|
||||||
GetExitCodeThread(thread, (LPDWORD)(&data));
|
|
||||||
CloseHandle(thread);
|
|
||||||
VirtualFreeEx(proc, addr, size, 0);
|
|
||||||
|
|
||||||
if (!data) {
|
|
||||||
CloseHandle(proc);
|
|
||||||
return SIGAR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread = CreateRemoteThread(proc, NULL, 0,
|
|
||||||
(LPTHREAD_START_ROUTINE)fstrlen,
|
|
||||||
data, 0, &thrid);
|
|
||||||
if (!thread) {
|
|
||||||
CloseHandle(proc);
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
WaitForSingleObject(thread, INFINITE);
|
|
||||||
GetExitCodeThread(thread, &datalen);
|
|
||||||
CloseHandle(thread);
|
|
||||||
|
|
||||||
if (!datalen) {
|
|
||||||
CloseHandle(proc);
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
value = HeapAlloc(GetProcessHeap(),
|
|
||||||
HEAP_ZERO_MEMORY,
|
|
||||||
datalen);
|
|
||||||
|
|
||||||
if (!value) {
|
|
||||||
CloseHandle(proc);
|
|
||||||
return GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ReadProcessMemory(proc, data, value,
|
|
||||||
datalen+1, &bytes))
|
|
||||||
{
|
|
||||||
procenv->env_getter(procenv->data,
|
|
||||||
key, strlen(key),
|
|
||||||
value, bytes-1);
|
|
||||||
|
|
||||||
status = SIGAR_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
status = GetLastError();
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, value);
|
|
||||||
CloseHandle(proc);
|
CloseHandle(proc);
|
||||||
|
|
||||||
|
if (status == SIGAR_OK) {
|
||||||
|
LPBYTE ptr = (LPBYTE)env;
|
||||||
|
DWORD size = sizeof(env);
|
||||||
|
UCHAR ent[1024];
|
||||||
|
while ((size > 0) && (*ptr != L'\0')) {
|
||||||
|
DWORD len = (wcslen((LPWSTR)ptr) + 1) * sizeof(WCHAR);
|
||||||
|
SIGAR_W2A((WCHAR *)ptr, ent, sizeof(ent));
|
||||||
|
if (sigar_proc_env_parse(ent, procenv) != SIGAR_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
size -= len;
|
||||||
|
ptr += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1523,12 +1446,7 @@ SIGAR_DECLARE(int) sigar_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (procenv->type == SIGAR_PROC_ENV_KEY) {
|
return sigar_remote_proc_env_get(sigar, pid, procenv);
|
||||||
return sigar_remote_proc_env_get(sigar, pid, procenv);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return SIGAR_ENOTIMPL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue