I am looking for a way to be able to redefine a set of POSIX functions but then end the redefinition with a call to the original function. The idea is that I am trying to create
No, cannot be done in C++. What you want is more akin to a LISP (or derivative) language, where you can grab the slot for an existing function and 'override it in place', potentially punting back to the original implementation.
In your MY_String.h
:
... blah blah
using mynamespace::strcpy;
#endif // header guard or maybe not there if using pragma
then all strcpys that are not prefixed with std:: will use yours. If you REALLY want to ban them, grep and take a shotgun with you when you find the person who used it.
Typical way of doing is on Unix is via LD_PRELOAD, example (Unix) below proxies a function call, malloc in particular (full example):
/**
* malloc() direct call
*/
inline void * libc_malloc(size_t size)
{
typedef void* (*malloc_func_t)(size_t);
static malloc_func_t malloc_func = (malloc_func_t) dlsym(RTLD_NEXT, "malloc");
return malloc_func(size);
}
You can write a preprocessor that changes calls to the standard routine to calls to your own routine. Such a preprocessor might be complicated, depending whether you need to recognize the full C++ grammar to distinguish calls using name spaces and so on or you can get away with more casual recognition of the calls.
You can link with your own library, producing a relocatable object module with resolved names stripped. Your library would contain routines with the standard names, such as strcpy
, that execute whatever code you desire and call other names, such as Mystrcpy
. The object module produced by this is then linked with a second library and with the standard library. The second library contains routines with those names, such as Mystrcpy
, that call the original library names strcpy
. The details for doing this are of course dependent on your linker. The goal is to have a chain like this: Original code calls strcpy
. This is resolved to the version of strcpy
in the first library. That version calls Mystrcpy
. Mystrcpy
calls the standard library strcpy
.
You can compile to assembly and edit the names in the assembly so that your routines are called instead of the standard library routines.
On some systems, you can use dlsym
and other functions defined in <dlfcn.h>
to load the dynamic library that contains the standard implementations and to call them via pointers returned by dlsym
instead of by the usual names in source code.
The GCC linker has a --wrap
switch that resolves calls to foo
to your routine __wrap_foo
and resolves calls to __real_foo
(which you would use in your implementation) to the real foo
.
See also Intercepting Arbitrary Functions on Windows, UNIX, and Macintosh OS X Platforms.
If using some recent GCC (e.g. version 4.7 or newer) you could also write a GCC plugin or a GCC extension in MELT to replace every call to strcpy
to your own mystrcpy
. This probably will take you some work (perhaps days, not hours) but has the enormous advantage to work inside the compiler, on the GCC compiler's internal representations (Gimple). So it will be done even after inlining, etc. And since you extend the compiler, you can tailor its behavior to what you want.
MELT is a domain specific language to extend GCC. It is designed for such tasks.
You cannot avoid these functions to be called.
A C++
program can do anything it wants, it could have some code that loads the strcpy
symbol from libc and runs it. If a malicious developer want to call that function, you have no way to avoid it. To do that you'd need to run the C++ code in some special environment (in a sandbox, or virtual machine), but I'm afraid such technology is not available.
If you trust the developers, and you're just looking for a way to remind them not to call certain functions, then there could be some solution.
One solution could be avoiding to #include
libc headers (like cstring
), and only include your own header files where you only declared the desired functions.
Another solution could be that of looking to the compiled executable in order to find out what functions are called, or to LD_PRELOAD
a library that redefines (and thus overrides) standard functions to make them print a warning at runtime.