diff options
author | Ron Yorston <rmy@pobox.com> | 2018-04-04 19:55:09 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2018-04-04 19:55:09 +0100 |
commit | 33a914da6bba61e27aee82675276bf1dccc52966 (patch) | |
tree | 2242719bf4bb7705504967d54d137d6fe19cc8f3 /win32 | |
parent | 016ca978455df7257a92236bbfb0c67de4a4bcd8 (diff) | |
download | busybox-w32-33a914da6bba61e27aee82675276bf1dccc52966.tar.gz busybox-w32-33a914da6bba61e27aee82675276bf1dccc52966.tar.bz2 busybox-w32-33a914da6bba61e27aee82675276bf1dccc52966.zip |
ps: obtain applet names from other BusyBox processes
Remove the code which passed applet names to child processes using
environment variables. This only allowed ps to display names for
its ancestors.
Instead attempt to read applet names from the memory of unrelated
processes.
The Microsoft documentation alone wasn't enough to figure out how
to do this. Additional hints from:
https://stackoverflow.com/questions/4298331/exe-or-dll-image-base-address
https://stackoverflow.com/questions/14467229/get-base-address-of-process
Diffstat (limited to 'win32')
-rw-r--r-- | win32/process.c | 107 |
1 files changed, 89 insertions, 18 deletions
diff --git a/win32/process.c b/win32/process.c index d6176ca23..3219fcad4 100644 --- a/win32/process.c +++ b/win32/process.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include "libbb.h" | 1 | #include "libbb.h" |
2 | #include <tlhelp32.h> | 2 | #include <tlhelp32.h> |
3 | #include <psapi.h> | ||
3 | 4 | ||
4 | int waitpid(pid_t pid, int *status, int options) | 5 | int waitpid(pid_t pid, int *status, int options) |
5 | { | 6 | { |
@@ -406,6 +407,79 @@ static inline long long filetime_to_ticks(const FILETIME *ft) | |||
406 | HNSEC_PER_TICK; | 407 | HNSEC_PER_TICK; |
407 | } | 408 | } |
408 | 409 | ||
410 | /* | ||
411 | * Attempt to get the applet name from another instance of busybox.exe. | ||
412 | * This will only work if the other process is using the same binary | ||
413 | * as the current process. If anything goes wrong just give up. | ||
414 | */ | ||
415 | static char *get_applet_name(DWORD pid, char *exe) | ||
416 | { | ||
417 | HANDLE proc; | ||
418 | HMODULE mlist[32]; | ||
419 | DWORD needed; | ||
420 | void *address; | ||
421 | char *my_base; | ||
422 | char buffer[128]; | ||
423 | char *name = NULL; | ||
424 | int i; | ||
425 | |||
426 | if (!(proc=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, | ||
427 | FALSE, pid))) { | ||
428 | return NULL; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Search for the module that matches the name of the executable. | ||
433 | * The values returned in mlist are actually the base address of | ||
434 | * the module in the other process (as noted in the documentation | ||
435 | * for the MODULEINFO structure). | ||
436 | */ | ||
437 | if (!EnumProcessModules(proc, mlist, sizeof(mlist), &needed)) { | ||
438 | goto finish; | ||
439 | } | ||
440 | |||
441 | for (i=0; i<needed/sizeof(HMODULE); ++i) { | ||
442 | char modname[MAX_PATH]; | ||
443 | if (GetModuleFileNameEx(proc, mlist[i], modname, sizeof(modname))) { | ||
444 | if (strcasecmp(bb_basename(modname), exe) == 0) { | ||
445 | break; | ||
446 | } | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (i == needed/sizeof(HMODULE)) { | ||
451 | goto finish; | ||
452 | } | ||
453 | |||
454 | /* attempt to read the BusyBox version string */ | ||
455 | my_base = (char *)GetModuleHandle(NULL); | ||
456 | address = (char *)mlist[i] + ((char *)bb_banner - my_base); | ||
457 | if (!ReadProcessMemory(proc, address, buffer, 128, NULL)) { | ||
458 | goto finish; | ||
459 | } | ||
460 | |||
461 | if (memcmp(buffer, bb_banner, strlen(bb_banner)) != 0) { | ||
462 | /* version mismatch (or not BusyBox at all) */ | ||
463 | goto finish; | ||
464 | } | ||
465 | |||
466 | /* attempt to read the applet name */ | ||
467 | address = (char *)mlist[i] + ((char *)bb_applet_name - my_base); | ||
468 | if (!ReadProcessMemory(proc, address, buffer, 128, NULL)) { | ||
469 | goto finish; | ||
470 | } | ||
471 | |||
472 | /* check that the string really is an applet name */ | ||
473 | buffer[31] = '\0'; | ||
474 | if (find_applet_by_name(buffer) >= 0) { | ||
475 | name = auto_string(xstrdup(buffer)); | ||
476 | } | ||
477 | |||
478 | finish: | ||
479 | CloseHandle(proc); | ||
480 | return name; | ||
481 | } | ||
482 | |||
409 | /* POSIX version in libbb/procps.c */ | 483 | /* POSIX version in libbb/procps.c */ |
410 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags | 484 | procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags |
411 | #if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG | 485 | #if !ENABLE_FEATURE_PS_TIME && !ENABLE_FEATURE_PS_LONG |
@@ -414,7 +488,8 @@ UNUSED_PARAM | |||
414 | ) | 488 | ) |
415 | { | 489 | { |
416 | PROCESSENTRY32 pe; | 490 | PROCESSENTRY32 pe; |
417 | const char *comm; | 491 | const char *comm, *name; |
492 | BOOL ret; | ||
418 | 493 | ||
419 | pe.dwSize = sizeof(pe); | 494 | pe.dwSize = sizeof(pe); |
420 | if (!sp) { | 495 | if (!sp) { |
@@ -424,18 +499,16 @@ UNUSED_PARAM | |||
424 | free(sp); | 499 | free(sp); |
425 | return NULL; | 500 | return NULL; |
426 | } | 501 | } |
427 | if (!Process32First(sp->snapshot, &pe)) { | 502 | ret = Process32First(sp->snapshot, &pe); |
428 | CloseHandle(sp->snapshot); | ||
429 | free(sp); | ||
430 | return NULL; | ||
431 | } | ||
432 | } | 503 | } |
433 | else { | 504 | else { |
434 | if (!Process32Next(sp->snapshot, &pe)) { | 505 | ret = Process32Next(sp->snapshot, &pe); |
435 | CloseHandle(sp->snapshot); | 506 | } |
436 | free(sp); | 507 | |
437 | return NULL; | 508 | if (!ret) { |
438 | } | 509 | CloseHandle(sp->snapshot); |
510 | free(sp); | ||
511 | return NULL; | ||
439 | } | 512 | } |
440 | 513 | ||
441 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); | 514 | memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); |
@@ -478,19 +551,17 @@ UNUSED_PARAM | |||
478 | sp->pid = pe.th32ProcessID; | 551 | sp->pid = pe.th32ProcessID; |
479 | sp->ppid = pe.th32ParentProcessID; | 552 | sp->ppid = pe.th32ParentProcessID; |
480 | 553 | ||
481 | comm = pe.szExeFile; | ||
482 | if (sp->pid == GetProcessId(GetCurrentProcess())) { | 554 | if (sp->pid == GetProcessId(GetCurrentProcess())) { |
483 | comm = applet_name; | 555 | comm = applet_name; |
484 | } | 556 | } |
557 | else if ((name=get_applet_name(pe.th32ProcessID, pe.szExeFile)) != NULL) { | ||
558 | comm = name; | ||
559 | } | ||
485 | else { | 560 | else { |
486 | char name[32], *value; | 561 | comm = pe.szExeFile; |
487 | |||
488 | sprintf(name, "BB_APPLET_%d", sp->pid); | ||
489 | if ((value=getenv(name)) != NULL) { | ||
490 | comm = value; | ||
491 | } | ||
492 | } | 562 | } |
493 | safe_strncpy(sp->comm, comm, COMM_LEN); | 563 | safe_strncpy(sp->comm, comm, COMM_LEN); |
564 | |||
494 | return sp; | 565 | return sp; |
495 | } | 566 | } |
496 | 567 | ||