From 1e4f17441570fe5abc6ebfc711655aa49362ff88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 18 Jan 2024 14:07:29 +0800 Subject: [PATCH] Shell (macOS): improve handling of xonsh --- .../terminalshell/terminalshell_linux.c | 54 ++++++++++++------- src/modules/shell/shell.c | 1 + src/util/mallocHelper.h | 2 +- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 397191e4e..fac9df60e 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -4,14 +4,13 @@ #include "common/processing.h" #include "common/thread.h" #include "util/stringUtils.h" +#include "util/mallocHelper.h" #include #include #include -#ifdef __APPLE__ - #include -#elif defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__APPLE__) #include #include #include @@ -38,15 +37,31 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex if(ffAppendFileBuffer(cmdlineFilePath, exe)) { ffStrbufTrimRightSpace(exe); - ffStrbufSubstrBeforeFirstC(exe, '\0'); //Trim the arguments - ffStrbufTrimLeft(exe, '-'); //Happens in TTY + ffStrbufRecalculateLength(exe); //Trim the arguments + ffStrbufTrimLeft(exe, '-'); //Login shells start with a dash } #elif defined(__APPLE__) - int length = proc_pidpath((int)pid, exe->chars, exe->allocated); - if(length > 0) - exe->length = (uint32_t)length; + size_t len = 0; + int mibs[] = { CTL_KERN, KERN_PROCARGS2, pid }; + if (sysctl(mibs, sizeof(mibs) / sizeof(*mibs), NULL, &len, NULL, 0) == 0) + { + FF_AUTO_FREE char* const procArgs2 = malloc(len); + if (sysctl(mibs, sizeof(mibs) / sizeof(*mibs), procArgs2, &len, NULL, 0) == 0) + { + // https://gist.github.com/nonowarn/770696#file-getargv-c-L46 + uint32_t argc = *(uint32_t*) procArgs2; + const char* realExePath = procArgs2 + sizeof(argc); + + const char* arg0 = memchr(realExePath, '\0', len - (size_t) (realExePath - procArgs2)); + while (*arg0 == '\0') arg0++; + assert(arg0 < procArgs2 + len); + if (*arg0 == '-') arg0++; // Login shells + + ffStrbufSetS(exe, arg0); + } + } #elif defined(__FreeBSD__) @@ -89,12 +104,17 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid) #elif defined(__APPLE__) - struct proc_bsdshortinfo proc; - if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0) - return "proc_pidinfo(pid) failed"; + struct kinfo_proc proc; + size_t size = sizeof(proc); + if(sysctl( + (int[]){CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}, 4, + &proc, &size, + NULL, 0 + )) + return "sysctl(KERN_PROC_PID) failed"; - *ppid = (pid_t)proc.pbsi_ppid; - strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars + *ppid = (pid_t)proc.kp_eproc.e_ppid; + strncpy(name, proc.kp_proc.p_comm, MAXCOMLEN); //trancated to 16 chars #elif defined(__FreeBSD__) @@ -186,7 +206,7 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid) ffStrEquals(name, "git-shell") || ffStrEquals(name, "elvish") || ffStrEquals(name, "oil.ovm") || - ffStrEquals(name, "xonsh") || + ffStrEquals(name, "xonsh") || // works in Linux but not in macOS because kernel returns `Python` in this case ffStrEndsWith(name, ".sh") ) { @@ -318,8 +338,6 @@ static void setShellInfoDetails(FFShellResult* result) ffStrbufInitStatic(&result->prettyName, "PowerShell"); else if(ffStrbufEqualS(&result->processName, "nu")) ffStrbufInitStatic(&result->prettyName, "nushell"); - else if(ffStrbufEqualS(&result->processName, "python") && getenv("XONSH_VERSION")) - ffStrbufInitStatic(&result->prettyName, "xonsh"); else if(ffStrbufEqualS(&result->processName, "oil.ovm")) ffStrbufInitStatic(&result->prettyName, "Oils"); else @@ -383,9 +401,7 @@ static void setTerminalInfoDetails(FFTerminalResult* result) fftsGetTerminalVersion(&result->processName, &result->exe, &result->version); } -#ifdef __APPLE__ -#define FF_EXE_PATH_LEN PROC_PIDPATHINFO_MAXSIZE -#elif defined(MAXPATH) +#if defined(MAXPATH) #define FF_EXE_PATH_LEN MAXPATH #elif defined(PATH_MAX) #define FF_EXE_PATH_LEN PATH_MAX diff --git a/src/modules/shell/shell.c b/src/modules/shell/shell.c index 9bb590eea..0c6d82f8c 100644 --- a/src/modules/shell/shell.c +++ b/src/modules/shell/shell.c @@ -93,6 +93,7 @@ void ffGenerateShellJsonResult(FF_MAYBE_UNUSED FFShellOptions* options, yyjson_m yyjson_mut_obj_add_uint(doc, obj, "pid", result->pid); yyjson_mut_obj_add_uint(doc, obj, "ppid", result->ppid); yyjson_mut_obj_add_strbuf(doc, obj, "processName", &result->processName); + yyjson_mut_obj_add_strbuf(doc, obj, "prettyName", &result->prettyName); yyjson_mut_obj_add_strbuf(doc, obj, "version", &result->version); } diff --git a/src/util/mallocHelper.h b/src/util/mallocHelper.h index 3cf19fad2..cacba8ecd 100644 --- a/src/util/mallocHelper.h +++ b/src/util/mallocHelper.h @@ -6,7 +6,7 @@ #include #include -static inline void ffWrapFree(void* pPtr) +static inline void ffWrapFree(const void* pPtr) { assert(pPtr); if(*(void**)pPtr)