У меня есть исполняемый модуль, созданный третьей стороной. Я хотел бы «внедрить» свой код (своего рода сторожевой таймер, работающий в отдельном потоке) в этот процесс.
Пока есть два возможных способа: один - запустить мой код как исполняемый и динамически загружать процесс поверх него (кажется очень сложным и сложным) или сделать мой код общим объектом, загрузить его через LD_PRELOAD и инициализировать из какой-то конструктор статической переменной.
Есть более удобные способы сделать это? Моя ОС - Linux x86 и Solaris-SPARC.
Обновление: если возможно, я бы хотел не патчить процесс, а динамически загружать свой код.





Похоже, вы ищете InjectSo. Есть Презентация PowerPoint, объясняющий, как это работает. Я еще не дошел до того, чтобы попробовать это.
Роб Кеннеди рассказал вам о 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 - просто найдите, что использует этот модуль.
В поле «здесь ваш код» вы можете запускать произвольные потоки, сторожевые таймеры и т. д.
Дмитрий, на какой конкретно системе вам удалось заставить ее работать? Я еще не смог этого сделать с большим количеством старых и новых систем.