代码注入 - Solaris& Linux的

时间:2008-12-18 15:19:37

标签: linux gcc solaris elf

我有一个由第三方创建的可执行模块。我想将我的代码(在单独的线程中运行的监视程序)“注入”到这个过程中。

到目前为止,有两种可能的方法 - 一种是将我的代码作为可执行文件运行并在其上动态加载一个程序(似乎非常困难和棘手)或者使我的代码成为共享对象,通过LD_PRELOAD加载它并从一些静态变量构造函数初始化。

有更方便的方法吗? 我的操作系统是Linux x86和Solaris-SPARC。

更新:如果可能的话,我不想修补这个过程,而是动态加载我的代码。

4 个答案:

答案 0 :(得分:4)

听起来像是在寻找InjectSo。有Powerpoint presentation解释了它是如何工作的。我还没有尝试过。

答案 1 :(得分:2)

Hotpatch应该为你做这件事。它比注射器更有能力。

答案 2 :(得分:0)

Rob Kennedy告诉你有关InjectSo的信息 - 这可能就是你所需要的。

请注意,将线程引入非线程进程会充满同步问题。如果应用程序已经过线程化,问题就不那么严重了,但即便如此,应用程序也可能会反对它不知道的线程。

答案 3 :(得分:0)

我没有使用上面提到的InjectSo,但它是一个值得注意的信息。 如果您正在寻找替代方法,这是一种注入代码的简单方法:

#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

使用LD_LIBRARY_PATH=. LD_PRELOAD=libinject.so ./test

运行

应该说hocus pocus。您可以覆盖任意libc个函数,例如printfsnprintf - 只需找到该模块使用的内容。

在“你的代码在这里”你可以启动任意线程,看门狗等。