diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 48e5e2c38..b5f68c58f 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -11,6 +11,10 @@ #include #include +#ifdef __APPLE__ + #include +#endif + static void setExeName(FFstrbuf* exe, const char** exeName) { assert(exe->length > 0); @@ -19,64 +23,92 @@ static void setExeName(FFstrbuf* exe, const char** exeName) *exeName = exe->chars + lastSlashIndex + 1; } -static void getProcessInformation(const char* pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName) +static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* exe, const char** exeName) { assert(processName->length > 0); - - FFstrbuf cmdlineFilePath; - ffStrbufInit(&cmdlineFilePath); - ffStrbufAppendS(&cmdlineFilePath, "/proc/"); - ffStrbufAppendS(&cmdlineFilePath, pid); - ffStrbufAppendS(&cmdlineFilePath, "/cmdline"); - ffStrbufClear(exe); - if(ffAppendFileBuffer(cmdlineFilePath.chars, exe)) + + #if defined(__linux__) || defined(__MSYS__) + + char cmdlineFilePath[64]; + snprintf(cmdlineFilePath, sizeof(cmdlineFilePath), "/proc/%d/cmdline", (int)pid); + + if(ffAppendFileBuffer(cmdlineFilePath, exe)) { ffStrbufSubstrBeforeFirstC(exe, '\0'); //Trim the arguments ffStrbufTrimLeft(exe, '-'); //Happens in TTY } + #elif defined(__APPLE__) + + int length = proc_pidpath((int)pid, exe->chars, exe->allocated); + if(length > 0) + exe->length = (uint32_t)length; + + #else + + //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) + + #endif + if(exe->length == 0) ffStrbufSet(exe, processName); setExeName(exe, exeName); - - ffStrbufDestroy(&cmdlineFilePath); } -static void getTerminalShell(FFTerminalShellResult* result, const char* pid) +static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid) { - FFstrbuf statFilePath; - ffStrbufInit(&statFilePath); - ffStrbufAppendS(&statFilePath, "/proc/"); - ffStrbufAppendS(&statFilePath, pid); - ffStrbufAppendS(&statFilePath, "/stat"); + const char* error = NULL; - FILE* stat = fopen(statFilePath.chars, "r"); - - ffStrbufDestroy(&statFilePath); + #if defined(__linux__) || defined(__MSYS__) + char statFilePath[64]; + snprintf(statFilePath, sizeof(statFilePath), "/proc/%d/stat", (int)pid); + FILE* stat = fopen(statFilePath, "r"); if(stat == NULL) - return; + return "fopen(statFilePath, \"r\") failed"; + *ppid = 0; + if( + fscanf(stat, "%*s (%255[^)]) %*c %d", name, ppid) != 2 || //stat (comm) state ppid + !ffStrSet(name) || + *ppid == 0 + ) + error = "fscanf(stat) failed"; + + fclose(stat); + + #elif defined(__APPLE__) + + struct proc_bsdshortinfo proc; + if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0) + error = "proc_pidinfo(pid) failed"; + else + { + *ppid = (pid_t)proc.pbsi_ppid; + strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars + } + + #else + + //TODO: support bsd (https://www.freebsd.org/cgi/man.cgi?query=kinfo_getproc) + error = "unimplemented"; + + #endif + + return error; +} + +static void getTerminalShell(FFTerminalShellResult* result, pid_t pid) +{ char name[256]; name[0] = '\0'; - char ppid[256]; - ppid[0] = '\0'; + pid_t ppid = 0; - if( - fscanf(stat, "%*s (%255[^)]) %*c %255s", name, ppid) != 2 || //stat (comm) state ppid - !ffStrSet(name) || - !ffStrSet(ppid) || - *ppid == '-' || - strcasecmp(ppid, "0") == 0 - ) { - fclose(stat); + if(getProcessNameAndPpid(pid, name, &ppid)) return; - } - - fclose(stat); //Common programs that are between terminal and own process, but are not the shell if( @@ -86,7 +118,9 @@ static void getTerminalShell(FFTerminalShellResult* result, const char* pid) strcasecmp(name, "strace") == 0 || strcasecmp(name, "sshd") == 0 || strcasecmp(name, "gdb") == 0 || - strcasecmp(name, "guake-wrapped") == 0 + strcasecmp(name, "lldb") == 0 || + strcasecmp(name, "guake-wrapped") == 0 || + strcasestr(name, "debug") != NULL ) { getTerminalShell(result, ppid); return; @@ -308,9 +342,7 @@ const FFTerminalShellResult* result.userShellExeName = result.userShellExe.chars; ffStrbufInit(&result.userShellVersion); - char ppid[32]; - snprintf(ppid, sizeof(ppid) - 1, "%i", getppid()); - getTerminalShell(&result, ppid); + getTerminalShell(&result, getppid()); getTerminalFromEnv(&result); getUserShellFromEnv(&result);