kwinject intercepts process creation requests, then tries to match the name of the created program against the list of known compilers (see the -P option for kwinject). If a match is found, the command line is passed through the option filter, and written into an output file. Then the originally requested process is created. If no match was found, the process creation request is passed directly to the system.
How kwinject captures executed processes depends on the target platform.
On Unix, kwinject sets up the LD_PRELOAD environmental variable to point to an interception library before starting the user process. After the user command line has been started, the kwinject main module opens a local socket and starts listening for events. Every time a program calls a function that is part of a dynamically linked library, the system dynamic linker/loader first looks it up in preloaded libraries, then in other places. The kwinject preloaded library redefines a number of system calls (execv, execvp and execve), so that each time a program tries to execute a new process, a function from the preloaded library momentarily takes control over the application. Redefined system functions report the executed command line to the main kwinject module through a socket, and then call the original system function.
On Windows, kwinject starts the user process in debug mode and listens to CREATE_PROCESS debug events. There's no need to maintain a separate interception module or some interprocess communication channel, because information about new processes is passed to kwinject directly by the system. Essentially, kwinject on Windows works as a simplified debugger. As soon as a new CREATE_PROCESS event is received, kwinject inspects the process address space to capture some information (like the current working directory, the command line and environment variables).