cht電腦資訊Linux
adm Find login register

LD_PRELOAD

eliu
1 LD_PRELOAD
Promote 0 Bookmark 02008-07-04quote  

我的喇叭是華碩 lcd monitor 內建的,在螢幕休眠時是關閉的,沒有聲音。因為 skype 在來電鈴聲時沒有辦法打開螢幕,所以聽不到。

後來想用 LD_PRELOAD 把 function open/fopen 包一層,當 skype open 來電鈴聲的 file,就執行 xset來打開螢幕。LD_PRELOAD environment variable 可以設定成自己想要先 load 的 .so,系統 load  進來你的 function 之後,就會忽略其他的 .so 的同名 function,這樣我們就可以把 libc.so  libgtk*.so  ... 裏面 的 function 取代掉。

 

這個小程式是可以用,可以用來紀錄 open 什麼 file, firefox/gedit ... 都可以用。惟獨 skype 不行, Orz.

不知道 skype 做了什麼手腳。


$ export LD_PRELOAD=./sky-wrap.so 

$ firefox 


Makefile

 sky-wrap.so:    myopen.c
    rm -f core.*
        cc -g -shared -o $@ -fPIC $< -ldl


myopen.c 

#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

static int (*org_open)(__const char *__file, int __oflag, ...);
static void *handle;
static FILE *(*org_fopen)(const char *path, const char *mode);
#define LOG 1
#if LOG
static int fd, fdf;
#endif

void __attribute__((constructor)) __open_init()
{
  unsetenv("LD_PRELOAD");
  if (!handle)
    handle = dlopen("/lib/libc.so.6", RTLD_LAZY);

  if (!handle)
    exit(0);

  *(void **) (&org_open) = dlsym(handle, "open");
  *(void **) (&org_fopen) = dlsym(handle, "fopen");
}

#if 1
int open (__const char *__file, int __oflag, ...)
{
  va_list ap;
  va_start(ap, __oflag);

  if (__oflag & O_CREAT) {
    mode_t mod = va_arg(ap,  mode_t);
    va_end(ap);

    return (*org_open)(__file, __oflag, mod);
  } else {
    va_end(ap);

#if LOG
    if (!fd) {
      char tt[16];
      sprintf(tt, "l.%d", getpid());
      fd = creat(tt, S_IRUSR|S_IWUSR);
    }
    write(fd, __file, strlen(__file));
    write(fd, "\n", 1);
#endif
    return (*org_open)(__file, __oflag);
  }
}
#endif


#if 1
FILE *fopen(const char *path, const char *mode)
{
#if LOG
  if (!fdf) {
    char tt[16];
    sprintf(tt, "fl.%d", getpid());
    fdf = creat(tt, S_IRUSR|S_IWUSR);
  }
  write(fdf, path, strlen(path));
  write(fdf, "\n", 1);
#endif
  return (*org_fopen)(path, mode);
}
#endif

本人已不在此站活動
2 LD_PRELOAD
Promote 0 Bookmark 02008-07-04quote  
eliu

$ export LD_PRELOAD=./sky-wrap.so 

小小聲的問一下。如果是放在其他指定的絕對路徑的話呢? 

$ export LD_PRELOAD=/tmp/sky-wrap.so

eliu
3
Promote 0 Bookmark 02008-07-04quote  
本人已不在此站活動
4
Promote 0 Bookmark 02008-07-04quote  

我的意思是說, so 沒效果,是否和載入路徑有關。也就是說程式 preload 時的 ./,和你的 ./ 並不一樣?雖然可能性很小…… :p

eliu
5
Promote 0 Bookmark 02008-07-04quote  
dou0228
6
Promote 0 Bookmark 02009-06-11quote  

如果轉用 inotify 去做呢?

不管 skype, 只 monitor 檔案, 當事件發生, 就 xset大笑

eliu
7
Promote 0 Bookmark 02009-06-11quote  

CC: C/C++
cht電腦資訊Linux
adm Find login register
views:24352