Tomoya Kabe
Tomoya Kabe

Reputation: 1197

Hook arbitrary function on to _exit(2)

I'm interested in whether I can call an arbitrary function on _exit(2) call, which bypasses other hooking architectures, so it doesn't seem easy to me.

Is there a way to do it without LD_PRELOAD, say, overriding _exit(2)?


Edit: The problem I'm facing is fork(2)ed Perl programs with CoW. The program's children processes run destructors on exit(3) call, in which they touch many memory locations, to cause large memory copy, in spite they will exit. It's hard to bypass destructors with ordinary exit call in Perl, so an idea is call POSIX::_exit instead. However, there is a dynamically loaded library with LD_PRELOAD, and I want to call a function in it on process exit.

Upvotes: 1

Views: 888

Answers (2)

user3629249
user3629249

Reputation: 16540

could you make use of the 'atexit()' function call?

Near the beginning of main() call atexit() with a parameter of the function that you want executed when the program exits.

You can call atexit() numerous time, thereby stacking several things to be executed when the application exits.

Upvotes: 0

AFAIU, it is simply not possible without LD_PRELOAD tricks, or ptrace(2) with PTRACE_SYSCALLfrom another process (e.g. the parent process running gdb). At the lowest level, _exit(2) is a system call so is an "atomic" operation using the SYSENTER machine instruction, e.g. thru vdso(7).

Notice that a C program could use some asm to invoke the _exit syscall (or use the indirect syscall(2))

Assuming a dynamically linked executable to GNU libc or musl-libc, your only way is to catch exit(3) library function (not the _exit(2) syscall!) using atexit(3)

You could redefine _exit and hope that the dynamic linker would call your _exit, not the one in libc. I won't play such tricks.

Alternatively, write a small wrapping C program which fork, execve and waitpid the original program.

Upvotes: 2

Related Questions