![]() ![]() The libforkmonitor_init() function is called automatically by the runtime linker before the process main() is called, and libforkmonitor_done() is called when the process returns from main() or calls exit(). Notify(TYPE_EXIT, &(data.msg), sizeof (struct message) + sizeof (int)) If (connect(commfd, (const struct sockaddr *)&addr, sizeof (addr)) = -1) while (result = -1 & errno = EINTR) Strncpy(addr.sun_path, address, sizeof addr.sun_path - 1) * Open an Unix domain datagram socket to the observer. *(void **)&actual_Exit = dlsym(RTLD_NEXT, "_exit") *(void **)&actual_Exit = dlsym(RTLD_NEXT, "_Exit") *(void **)&actual_exit = dlsym(RTLD_NEXT, "_Exit") *(void **)&actual_exit = dlsym(RTLD_NEXT, "_exit") *(void **)&actual_abort = dlsym(RTLD_NEXT, "abort") *(void **)&actual_vfork = dlsym(RTLD_NEXT, "vfork") *(void **)&actual_fork = dlsym(RTLD_NEXT, "fork") Void libforkmonitor_init(void) _attribute_((constructor)) Send(commfd, msg, sizeof (struct message) + extra, MSG_EOR | MSG_NOSIGNAL) * or partial send()s, we just fire one off and hope for the best. * Since we don't have any method of dealing with send() errors Static void notify(const int type, struct message *const msg, const size_t extra) Static void (*actual_abort)(void) = NULL Static pid_t (*actual_vfork)(void) = NULL Static pid_t (*actual_fork)(void) = NULL (This is quite safe for multithreaded programs, as the pointers will only be modified prior to main() is executed.) #define _POSIX_C_SOURCE 200809L It would be better to use atomic built-ins (_sync_bool_compare_and_swap()) to update the function pointer, and atomic getter (_sync_fetch_and_or(,0)) to retrieve the function pointer, to avoid any issues with wonky libraries. Note that I simplified the code quite a bit, leaving out multithreaded initialization (since it's rare for a library to call any of the intercepted functions, and even rarer to do it from multiple threads). Here is the library itself, libforkmonitor.c. If not defined or empty, no monitoring messages are sent. The FORKMONITOR_SOCKET environment variable (named by the FORKMONITOR_ENVNAME macro above) specifies the Unix domain datagram socket addess to the monitoring process. Unsigned char type /* One of the TYPE_ constants */Ĭhar data /* Optional payload, possibly longer */ #define TYPE_EXIT 5 /* _exit() or _Exit() */ #define TYPE_DONE 2 /* exit() or return from main() */ #define TYPE_EXEC 1 /* When a binary is executed */ #define FORKMONITOR_ENVNAME "FORKMONITOR_SOCKET" It defines the messages passed from the preload library, to the monitoring process: #ifndef FORKMONITOR_H As long as all child processes also use the preload library, you'll see all local child processes, no matter how executed.įirst, the forkmonitor.h header file. Run the target binary using a preload library that catches fork(). ![]()
0 Comments
Leave a Reply. |