change proc_args to use the PEB

This commit is contained in:
Doug MacEachern 2004-07-28 21:47:14 +00:00
parent a35333223b
commit 2fa069d068
3 changed files with 79 additions and 6 deletions

View File

@ -34,12 +34,12 @@ static int sigar_peb_get(sigar_t *sigar, HANDLE proc, DWORD *base)
return SIGAR_OK; return SIGAR_OK;
} }
//point scratch to PATH env var //point scratch to env block
#define PEB_PATH(scratch, base) \ #define PEB_FIRST(scratch, base) \
scratch = sigar->peb + ((DWORD)START_ADDRESS - base) scratch = sigar->peb + ((DWORD)START_ADDRESS - base)
//point scratch to EXE (assumes PEB_PATH) //point scratch to next string (assumes PEB_FIRST)
#define PEB_EXE(scratch) \ #define PEB_NEXT(scratch) \
scratch = scratch + (wcslen((LPWSTR)scratch) + 1) * sizeof(WCHAR) scratch = scratch + (wcslen((LPWSTR)scratch) + 1) * sizeof(WCHAR)
int sigar_proc_exe_name_get(sigar_t *sigar, HANDLE proc, char *name) int sigar_proc_exe_name_get(sigar_t *sigar, HANDLE proc, char *name)
@ -54,9 +54,9 @@ int sigar_proc_exe_name_get(sigar_t *sigar, HANDLE proc, char *name)
} }
//skip env PATH //skip env PATH
PEB_PATH(scratch, base); PEB_FIRST(scratch, base);
PEB_EXE(scratch); PEB_NEXT(scratch);
//seems common, reason unknown. //seems common, reason unknown.
if (*scratch == '\0') { if (*scratch == '\0') {
@ -70,3 +70,36 @@ int sigar_proc_exe_name_get(sigar_t *sigar, HANDLE proc, char *name)
return SIGAR_OK; return SIGAR_OK;
} }
int sigar_proc_cmdline_get(sigar_t *sigar, HANDLE proc, char *cmdline)
{
int status;
LPBYTE scratch;
DWORD base;
WCHAR buf[MAX_PATH];
if ((status = sigar_peb_get(sigar, proc, &base)) != SIGAR_OK) {
return status;
}
//skip env block
PEB_FIRST(scratch, base);
PEB_NEXT(scratch);
//seems common, reason unknown.
if (*scratch == '\0') {
scratch += sizeof(WCHAR);
}
PEB_NEXT(scratch);
if (*scratch == '\0') {
scratch += sizeof(WCHAR);
}
wcsncpy(buf, (LPWSTR)scratch, MAX_PATH);
buf[MAX_PATH-1] = L'\0';
SIGAR_W2A(buf, cmdline, MAX_PATH);
return SIGAR_OK;
}

View File

@ -121,6 +121,8 @@ int sigar_wsa_init(sigar_t *sigar);
int sigar_proc_exe_name_get(sigar_t *sigar, HANDLE proc, char *name); int sigar_proc_exe_name_get(sigar_t *sigar, HANDLE proc, char *name);
int sigar_proc_cmdline_get(sigar_t *sigar, HANDLE proc, char *cmdline);
unsigned int sigar_cpu_count(sigar_t *sigar); unsigned int sigar_cpu_count(sigar_t *sigar);
int sigar_cpu_info_get(sigar_t *sigar, sigar_cpu_info_t *info); int sigar_cpu_info_get(sigar_t *sigar, sigar_cpu_info_t *info);

View File

@ -804,6 +804,10 @@ static char *getarg(char **line)
return res; return res;
} }
#if 0
/* this was the first shot, works but injects a remote thread
* in the process. probably best to avoid that.
*/
/* /*
* this is ugly, but there is no alternative. * this is ugly, but there is no alternative.
* we spawn a remote thread within the process * we spawn a remote thread within the process
@ -901,6 +905,40 @@ static int sigar_remote_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
CloseHandle(proc); CloseHandle(proc);
return SIGAR_OK; return SIGAR_OK;
} }
#else
/* second shot, using the PEB.
* read-only, minimum access privs and in general seems to work
* better than the method above. lets roll...
*/
static int sigar_remote_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
sigar_proc_args_t *procargs)
{
int status;
char cmdline[MAX_PATH], *ptr = cmdline, *arg;
HANDLE proc = open_process(pid);
if (!proc) {
return GetLastError();
}
status = sigar_proc_cmdline_get(sigar, proc, cmdline);
CloseHandle(proc);
if (status != SIGAR_OK) {
return status;
}
sigar_proc_args_create(procargs);
while (*ptr && (arg = getarg(&ptr))) {
SIGAR_PROC_ARGS_GROW(procargs);
procargs->data[procargs->number++] = strdup(arg);
}
return SIGAR_OK;
}
#endif
static int sigar_local_proc_args_get(sigar_t *sigar, sigar_pid_t pid, static int sigar_local_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
sigar_proc_args_t *procargs) sigar_proc_args_t *procargs)