aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-04-04 19:55:09 +0100
committerRon Yorston <rmy@pobox.com>2018-04-04 19:55:09 +0100
commit33a914da6bba61e27aee82675276bf1dccc52966 (patch)
tree2242719bf4bb7705504967d54d137d6fe19cc8f3 /win32
parent016ca978455df7257a92236bbfb0c67de4a4bcd8 (diff)
downloadbusybox-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.c107
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
4int waitpid(pid_t pid, int *status, int options) 5int 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 */
415static 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 */
410procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags 484procps_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