несколько переменных общего доступа LD_REPLOAD

Моя цель довольно проста: когда я запускаю сервер mongoose, сервер инициализирует переменную, которую я определяю. Для этого я подсел __libc_start_main, Затем, когда сервер получит запрос, он распечатает эту инициализированную переменную. Для этого я подсел recv, Ниже мой код.

#include <string>
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include "common-structure.h"
#  define dprintf(fmt...)

data datainfo; //defined in common-structure.h

typedef int (*main_type)(int, char**, char**);

struct arg_type
{
char **argv;
int (*main_func) (int, char **, char **);
};

main_type saved_init_func = NULL;
void tern_init_func(int argc, char **argv, char **env){
dprintf("%04d: __tern_init_func() called.\n", (int) pthread_self());
if(saved_init_func)
saved_init_func(argc, argv, env);
datainfo.age = 10;
}

typedef void (*fini_type)(void*);
fini_type saved_fini_func = NULL;

extern "C" int my_main(int argc, char **pt, char **aa)
{
int ret;
arg_type *args = (arg_type*)pt;
dprintf("%04d: __libc_start_main() called.\n", (int) pthread_self());
ret = args->main_func(argc, args->argv, aa);
return ret;
}

extern "C" int __libc_start_main(
void *func_ptr,
int argc,
char* argv[],
void (*init_func)(void),
void (*fini_func)(void),
void (*rtld_fini_func)(void),
void *stack_end)
{
typedef void (*fnptr_type)(void);
typedef int (*orig_func_type)(void *, int, char *[], fnptr_type,
fnptr_type, fnptr_type, void*);
orig_func_type orig_func;
arg_type args;

void * handle;
int ret;

// Get lib path.
Dl_info dli;
dladdr((void *)dlsym, &dli);
std::string libPath = dli.dli_fname;
libPath = dli.dli_fname;
size_t lastSlash = libPath.find_last_of("/");
libPath = libPath.substr(0, lastSlash);
libPath += "/libc.so.6";
libPath = "/lib/x86_64-linux-gnu/libc.so.6";
if(!(handle=dlopen(libPath.c_str(), RTLD_LAZY))) {
puts("dlopen error");
abort();
}

orig_func = (orig_func_type) dlsym(handle, "__libc_start_main");

if(dlerror()) {
puts("dlerror");
abort();
}

dlclose(handle);

dprintf("%04d: __libc_start_main is hooked.\n", (int) pthread_self());

args.argv = argv;
args.main_func = (main_type)func_ptr;
saved_init_func = (main_type)init_func;

saved_fini_func = (fini_type)rtld_fini_func;
ret = orig_func((void*)my_main, argc, (char**)(&args),
(fnptr_type)tern_init_func, (fnptr_type)fini_func,
rtld_fini_func, stack_end);

return ret;

}

//hook recv
extern "C" ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
ssize_t (*orig_recv)(int sockfd, void *buf, size_t len, int flags);
orig_recv = dlsym(RTLD_NEXT, "recv");
orig_recv(sockfd, buf, len, flags);

printf("age is %d\n", datainfo.age);
}

Однако, когда я создаю файл, я получаю сообщение об ошибке: invalid conversion from ‘void*’ to ‘ssize_t (*)(int, void*, size_t, int) приходящий из dlsym(RTLD_NEXT, "recv");, Мой другой вопрос: могу ли я достичь своей цели таким образом? Если нет, каков правильный путь?

0

Решение

C ++ гораздо сильнее типизирован, чем C, вам нужно явно привести void * к правильному типу.

Например:

extern "C" ssize_t recv(int sockfd, void *buf, size_t len, int flags)
{
using orig_recv_t = ssize_t (*)(int, void *, size_t, int);
// Or for pre C++11 compilers: typedef ssize_t (*orig_recv_t)(int, void *, size_t, int);
orig_recv_t orig_recv;

orig_recv = reinterpret_cast<orig_recv_t>(dlsym(RTLD_NEXT, "recv"));
orig_recv(sockfd, buf, len, flags);

printf("age is %d\n", datainfo.age);
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]