我有一个由第三方创建的可执行模块。我想将我的代码(一种在单独线程中运行的看门狗)“注入”到这个进程中。
到目前为止,有两种可能的方法 - 一种是将我的代码作为可执行文件运行并在其之上动态加载一个过程(似乎非常困难和棘手)或使我的代码成为共享对象,通过 LD_PRELOAD 加载它并从一些静态变量构造函数。
有没有更方便的方法来做到这一点?我的操作系统是 Linux x86 和 Solaris-SPARC。
更新:如果可能的话,我不想修补这个过程,而是动态加载我的代码。
听起来您正在寻找InjectSo。有一个Powerpoint 演示文稿解释了它是如何工作的。我还没来得及尝试一下。
Hotpatch应该为您执行此操作。它比injectso更有能力。
Rob Kennedy 向您介绍了 InjectSo——这可能就是您所需要的。
请注意,将线程引入非线程进程将充满同步问题。如果应用程序已经线程化,问题就不那么严重了,但即便如此,应用程序可能会反对它不知道的线程。
我没有使用过上面提到的 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
函数,例如printf
, snprintf
- 只需找到该模块使用的是什么。
在“您的代码”中,您可以启动任意线程、看门狗等。