aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--Makefile.flags2
-rw-r--r--applets/applet_tables.c9
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/appletlib.c19
-rw-r--r--shell/ash.c7
-rw-r--r--win32/process.c107
6 files changed, 104 insertions, 42 deletions
diff --git a/Makefile.flags b/Makefile.flags
index 6bb6a8fb1..86ab0a0ec 100644
--- a/Makefile.flags
+++ b/Makefile.flags
@@ -126,7 +126,7 @@ endif
126ifeq ($(CONFIG_PLATFORM_MINGW32),y) 126ifeq ($(CONFIG_PLATFORM_MINGW32),y)
127CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 -fno-builtin-stpcpy -fno-ident 127CFLAGS += -Iwin32 -DHAVE_STRING_H=1 -DHAVE_CONFIG_H=0 -fno-builtin-stpcpy -fno-ident
128EXEEXT = .exe 128EXEEXT = .exe
129LDLIBS += userenv ws2_32 129LDLIBS += userenv psapi ws2_32
130endif 130endif
131 131
132# Android has no separate crypt library 132# Android has no separate crypt library
diff --git a/applets/applet_tables.c b/applets/applet_tables.c
index 9a2aa5329..858429ac2 100644
--- a/applets/applet_tables.c
+++ b/applets/applet_tables.c
@@ -61,6 +61,7 @@ static int str_isalnum_(const char *s)
61int main(int argc, char **argv) 61int main(int argc, char **argv)
62{ 62{
63 int i, j; 63 int i, j;
64 unsigned MAX_APPLET_NAME_LEN = 1;
64 65
65 // In find_applet_by_name(), before linear search, narrow it down 66 // In find_applet_by_name(), before linear search, narrow it down
66 // by looking at N "equidistant" names. With ~350 applets: 67 // by looking at N "equidistant" names. With ~350 applets:
@@ -124,8 +125,8 @@ int main(int argc, char **argv)
124 printf("const char applet_names[] ALIGN1 = \"\"\n"); 125 printf("const char applet_names[] ALIGN1 = \"\"\n");
125 for (i = 0; i < NUM_APPLETS; i++) { 126 for (i = 0; i < NUM_APPLETS; i++) {
126 printf("\"%s\" \"\\0\"\n", applets[i].name); 127 printf("\"%s\" \"\\0\"\n", applets[i].name);
127// if (MAX_APPLET_NAME_LEN < strlen(applets[i].name)) 128 if (MAX_APPLET_NAME_LEN < strlen(applets[i].name))
128// MAX_APPLET_NAME_LEN = strlen(applets[i].name); 129 MAX_APPLET_NAME_LEN = strlen(applets[i].name);
129 } 130 }
130 printf(";\n\n"); 131 printf(";\n\n");
131 132
@@ -193,8 +194,8 @@ int main(int argc, char **argv)
193#endif 194#endif
194 //printf("#endif /* SKIP_definitions */\n"); 195 //printf("#endif /* SKIP_definitions */\n");
195 196
196// printf("\n"); 197 printf("\n");
197// printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); 198 printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN);
198 199
199 if (argv[2]) { 200 if (argv[2]) {
200 FILE *fp; 201 FILE *fp;
diff --git a/include/libbb.h b/include/libbb.h
index da3459224..d948f88f3 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -2075,7 +2075,7 @@ extern const char bb_path_wtmp_file[] ALIGN1;
2075#define bb_dev_null "/dev/null" 2075#define bb_dev_null "/dev/null"
2076#if ENABLE_PLATFORM_MINGW32 2076#if ENABLE_PLATFORM_MINGW32
2077#define bb_busybox_exec_path get_busybox_exec_path() 2077#define bb_busybox_exec_path get_busybox_exec_path()
2078extern char *bb_applet_pid(void); 2078extern char bb_applet_name[];
2079#else 2079#else
2080extern const char bb_busybox_exec_path[] ALIGN1; 2080extern const char bb_busybox_exec_path[] ALIGN1;
2081#endif 2081#endif
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 1488d4bd6..3e740363a 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -796,13 +796,6 @@ static void install_links(const char *busybox UNUSED_PARAM,
796 796
797static void run_applet_and_exit(const char *name, char **argv) NORETURN; 797static void run_applet_and_exit(const char *name, char **argv) NORETURN;
798 798
799#if ENABLE_PLATFORM_MINGW32
800char *bb_applet_pid(void)
801{
802 return auto_string(xasprintf("BB_APPLET_%d=%s", getpid(), applet_name));
803}
804#endif
805
806# if ENABLE_BUSYBOX 799# if ENABLE_BUSYBOX
807# if ENABLE_FEATURE_SH_STANDALONE && ENABLE_FEATURE_TAB_COMPLETION 800# if ENABLE_FEATURE_SH_STANDALONE && ENABLE_FEATURE_TAB_COMPLETION
808 /* 801 /*
@@ -979,6 +972,11 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
979# endif 972# endif
980 973
981# if NUM_APPLETS > 0 974# if NUM_APPLETS > 0
975
976# if ENABLE_PLATFORM_MINGW32
977char bb_applet_name[MAX_APPLET_NAME_LEN+1];
978# endif
979
982void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) 980void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv)
983{ 981{
984 int argc = string_array_len(argv); 982 int argc = string_array_len(argv);
@@ -988,6 +986,9 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
988 * "-/sbin/halt" -> "halt", for example. 986 * "-/sbin/halt" -> "halt", for example.
989 */ 987 */
990 applet_name = name; 988 applet_name = name;
989#if ENABLE_PLATFORM_MINGW32
990 strcpy(bb_applet_name, applet_name);
991#endif
991 992
992 /* Special case. POSIX says "test --help" 993 /* Special case. POSIX says "test --help"
993 * should be no different from e.g. "test --foo". 994 * should be no different from e.g. "test --foo".
@@ -1014,10 +1015,6 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar
1014 if (ENABLE_FEATURE_SUID) 1015 if (ENABLE_FEATURE_SUID)
1015 check_suid(applet_no); 1016 check_suid(applet_no);
1016 1017
1017#if ENABLE_PLATFORM_MINGW32
1018 putenv(bb_applet_pid());
1019#endif
1020
1021 xfunc_error_retval = applet_main[applet_no](argc, argv); 1018 xfunc_error_retval = applet_main[applet_no](argc, argv);
1022 /* Note: applet_main() may also not return (die on a xfunc or such) */ 1019 /* Note: applet_main() may also not return (die on a xfunc or such) */
1023 xfunc_die(); 1020 xfunc_die();
diff --git a/shell/ash.c b/shell/ash.c
index 2a1ddac39..6d24fb55a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -14975,13 +14975,6 @@ reinitvar(void)
14975 varinit[i].var_func = varinit_data[i].var_func; 14975 varinit[i].var_func = varinit_data[i].var_func;
14976 } 14976 }
14977 vlineno.var_text = linenovar; 14977 vlineno.var_text = linenovar;
14978
14979 /*
14980 * BB_APPLET_<pid> was correct when 'sh --forkshell' was started
14981 * but has now been overwritten by the environment from the forkshell
14982 * data block. Reinstate it.
14983 */
14984 setvareq(bb_applet_pid(), VEXPORT);
14985} 14978}
14986 14979
14987/* FIXME: should consider running forkparent() and forkchild() */ 14980/* FIXME: should consider running forkparent() and forkchild() */
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