Giriş
dlsym ile bir metodu ismen bulmak mümkün. Çağrının döndürdüğü sonuç bir function pointer'a atanarak metod çağrısı yapılor. Yani çağrılmak istenen metodun imzasını bilmek gerekir.
C++ Uygulaması
dlsym ile bir metodu ismen bulmak mümkün. Çağrının döndürdüğü sonuç bir function pointer'a atanarak metod çağrısı yapılor. Yani çağrılmak istenen metodun imzasını bilmek gerekir.
C++ Uygulaması
Eğer C++ uygulaması ise isimler mangled olacağı için nm ile ismi bulmak gerekir. Şöyle yaparız.
void* ptr = dlsym(handle, "mangled_name_you_got_from_nm");
Şöyle yaparız.auto ptr = reinterpret_cast<int(*)(int)>(dlsym(handle, "mangled_name"));
C Uygulaması
Örnek
Elimizdeki C .so dosyasında var isimli değişken olsun. libhello.c
int var;
int func() {
return 7;
}
libhello.h
extern int var;
int func();
Şöyle yaparız.
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>
#include "libhello.h"
int main() {
void* h = dlopen("libhello.so", RTLD_NOW);
uintptr_t&var = (uintptr_t)dlsym(h, "var" );
uintptr_t&func = (uintptr_t)dlsym(h, "func");
}
Örnek
Şöyle yaparız. Çağrı sonucu f function pointer'ına atanıyor.
RTLD_MAIN_ONLY
Örnek'te ana uygulama içindeki main_greeting() metodu zaten yüklü. dlsym RTLD_MAIN_ONLY seçeneği ile kullanılarak .so dosyalarını aramadan main_greeting() metodunu veriyor.
RTLD_NEXT
Örnek'te cos metodu ismi ile bulunuyor ve bir function pointer'a atanıyor.
#define _GNU_SOURCE /* for RTLD_NEXT */
#include <dlfcn.h>
/* ... */
void f (*exit_addr)(int) = dlsym(RTLD_NEXT, "exit");
Hata Kontrolü
Örnek
dlerror() ile yapılabilir. Şöyle yaparız.
RTLD_NEXT ve RDLD_MAIN_ONLY ne anlama gelir
dlsym metodları ararken zaten yüklü bir metodu bul veya tüm .so kütüphanelerini ara seçeneği ile kullanılabilir.Örnek
dlerror() ile yapılabilir. Şöyle yaparız.
typedef int (*add_func_ptr)(int);
void *handle;
char *error;
handle = dlopen("./add.so", RTLD_LAZY);
if (!handle)
{
fputs(dlerror(), stderr);
exit(1);
}
add_func_ptr addfun;
addfun = (add_func_ptr)dlsym(handle, "add");
if ((error = dlerror()) != NULL)
{
fputs(error, stderr);
exit(1);
}
printf("%d\n", (*addfun)(2));
dlclose(handle);
RTLD_NEXT ve RDLD_MAIN_ONLY ne anlama gelir
RTLD_MAIN_ONLY
Örnek'te ana uygulama içindeki main_greeting() metodu zaten yüklü. dlsym RTLD_MAIN_ONLY seçeneği ile kullanılarak .so dosyalarını aramadan main_greeting() metodunu veriyor.
#include <dlfcn.h>
#include <stdio.h>
void main_greeting(void)
{
printf("%s\n", "hello world");
}
void lib_func(void)
{
void (*greeting)(void) = dlsym(RTLD_MAIN_ONLY, "main_greeting");
greeting ? greeting() : printf("%s\n", dlerror());
}
int main(void)
{
lib_func();
return 0;
}
RTLD_NEXT
Örnek'te cos metodu ismi ile bulunuyor ve bir function pointer'a atanıyor.
#include <stdlib.h> #include <stdio.h> #include <dlfcn.h> int main(int argc, char **argv) { void *handle; double (*cosine)(double); char *error; handle = dlopen ("/lib/libm.so.6", RTLD_LAZY); if (!handle) { fputs (dlerror(), stderr); exit(1); } cosine = dlsym(handle, "cos"); if ((error = dlerror()) != NULL) { fputs(error, stderr); exit(1); } printf ("%f\n", (*cosine)(2.0)); dlclose(handle); }
Hiç yorum yok:
Yorum Gönder