2010-10-05 69 views
3
$ chmod +x libsomelibrary.so 
$ ./libsomelibrary.so 
Segmentation fault 

$ gcc -O2 http://vi-server.org/vi/bin/rundll.c -ldl -o rundll 
$ ./rundll ./libsomelibrary.so main 
(application starts normally) 

爲什麼我不能只啓動libsomelibrary.so,如果它有可用的入口點?爲什麼我無法在Linux中直接啓動共享庫?

rundll.c很簡單:

void* d = dlopen(argv[1], RTLD_LAZY); 
void* m = dlsym(d, argv[2]); 
return ((int(*)(int,char**,char**))m)(argc-2, argv+2, envp); 

爲什麼不能在內部使用嘗試加載一個二進制文件時?

+0

此功能非常有用:作爲一個庫是NS插件,但是如果它是「主」開始的,它只是桌面GUI應用程序,它更易於調試。並且不需要有多個項目,靜態庫和依賴關係。 – 2010-10-05 01:11:43

回答

4

main不是內核或動態鏈接程序所識別的入口點 - 它在編譯時被鏈接到可執行文件中的啓動代碼調用(默認情況下此類啓動代碼未鏈接到共享庫中)。

ELF標題包含起始地址。

3

共享庫不能直接運行。它們被設計爲鏈接到另一個代碼庫。它可能有一個可用的入口點,但可執行需要的不僅僅是具有可用的入口點。 rundll實用程序就是這方面的證明。你的第二個測試表明共享庫的確是可執行的,但只有在rundll做了一些工作。如果您對圖書館代碼執行之前需要完成的工作感到好奇,請查看rundll的源代碼。

+0

「rundll」是我剛寫的一個程序。但這是一件微不足道的事情。系統很容易做到這一點(如果我們正在嘗試執行該庫,請將其刪除,dlsym「main」並執行它)。 – 2010-10-05 01:09:20

+0

爲什麼「可執行」不僅僅意味着「僅僅具有可用的入口點」?請提供一些額外的解釋。 – wj32 2010-10-05 01:15:13

+0

這是微不足道的。我見過一些應用程序,其主要可執行文件是一個像這樣的小包裝器,用於''dlopen''主庫並跳轉到一個預定義的函數。系統不會自動執行此操作,因爲在一般情況下,它不知道入口點在哪裏(或者在多個入口點的情況下使用哪個入口點),或者需要先進行什麼樣的設置跳到那個入口點。 – bta 2010-10-05 01:17:47

3

可以在Linux中啓動共享庫。

例如,如果你開始/lib/libc.so.6,它會打印出它的版本號:

$ /lib/libc.so.6 
GNU C Library stable release version 2.12, by Roland McGrath et al. 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. 
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A 
PARTICULAR PURPOSE. 
Compiled by GNU CC version 4.5.0 20100520 (prerelease). 
Compiled on a Linux 2.6.34 system on 2010-05-29. 
Available extensions: 
     crypt add-on version 2.1 by Michael Glad and others 
     GNU Libidn by Simon Josefsson 
     Native POSIX Threads Library by Ulrich Drepper et al 
     BIND-8.2.3-T5B 
libc ABIs: UNIQUE IFUNC 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/libc/bugs.html>. 

一定有什麼東西從資料庫中失蹤。