Question

I have an executable module created by third party. I would like to "inject" my code (kind of watchdog running in separate thread) into this process.

So far there are two possible ways - one is to run my code as executable and dynamically load a proess on top of it (seems to be very hard and tricky) or to make my code a shared object, load it via LD_PRELOAD and initialize from some static variable constructor.

Are there more convenient ways to do this ? My OS are Linux x86 and Solaris-SPARC.

Update: If possible, I'd like not to patch the process, but load my code dynamicaly.

Was it helpful?

Solution

Sounds like you're looking for InjectSo. There's a Powerpoint presentation that explains how it works. I haven't gotten around to trying it out yet.

OTHER TIPS

Hotpatch should do this for you. It is more capable than injectso.

Rob Kennedy told you about InjectSo - that's probably what you need.

Beware that the introduction of a thread into a non-threaded process would be fraught with synchronization issues. The problems are less serious if the application is already threaded, but even so, the application may object to a thread that it doesn't know about.

I have not used the mentioned InjectSo but it is a noteworthy information. If you are looking for alternatives here is a simple way to inject your code:

#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
int main()
{
    struct passwd* pswd = getpwuid(1000);
    if(pswd) 
        printf("%s\n", pswd->pw_name);
    return 0;
}

gcc test.c -o test

#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
#include <stdio.h>

static char* hocus = "hocus pocus";

struct passwd *getpwuid(uid_t uid)
{
    static struct passwd *(*orig_getpwuid)(uid_t uid);
    if(!orig_getpwuid) {
        orig_getpwuid = (struct passwd* (*)(uid_t))dlsym(RTLD_NEXT, "getpwuid");
    }

    struct passwd* original_passwd = (*orig_getpwuid)(uid);
    if(original_passwd) {
        original_passwd->pw_name = hocus;
    }
    // your code here
    return original_passwd;
}

gcc inject.c -shared -o libinject.so

run with LD_LIBRARY_PATH=. LD_PRELOAD=libinject.so ./test

Should say hocus pocus. You can override arbitrary libc functions, like printf, snprintf - just find what is that module using.

In the "your code here" you can start arbitrary threads, watchdogs etc.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top