簡體   English   中英

如何找出程序或其他庫使用共享對象的哪些功能?

[英]How do I find out which functions of a shared object are used by a program or an other library?

如何找出程序或其他庫使用共享對象的哪些功能? 在這種特定情況下,我想看看/lib/libgcc1_s.so.1中的哪些函數被其他動態庫使用。 由於它們是動態鏈接的,因此objdump -d不解析函數調用地址。 有沒有辦法在調試器中運行程序或靜態重新鏈接? 謝謝,

盧卡

編輯:

nm和readelf不會這樣做,我不需要查看共享對象中存在哪些符號,但實際上在鏈接到它的其他對象中使用了哪些符號。

nm僅在庫未被刪除其符號時才起作用。 但是, nm -D可以顯示一些信息:

nm -D /lib/libgcc_s.so.1

但是還有另一種工具可以幫助你: readelf

readelf - 顯示有關ELF文件的信息。

如果檢查手冊頁,選項-sDisplays the entries in symbol table section of the file, if it has one.

readelf -s /lib/libgcc_s.so.1

編輯:

好吧,在你用nm檢查的對象中沒有實現的符號會出現在它前面的U標志,但是nm不會告訴你系統上哪個庫實現了那個符號。

所以你正在尋找的東西可能是用lddnm的混合物來實現的。 ldd告訴您的應用程序鏈接了哪些庫,nm告訴哪些符號未定義( U標志)或本地實現( T標志)。

在目標應用程序上列出所有未定義的符號(帶有nm)之后,您應該遍歷ldd報告的所有庫以搜索這些符號(再次使用nm)。 如果你找到符號並且它前面有T標志,你就找到了它。

順便說一句,我只是用bash寫這個單行來說明我的想法。 它分析名為win的應用程序,並嘗試查找實現報告為undefined的所有符號的庫。

target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo "Found symbol: $symbol at [$library]"; fi ; done; done; done;

或者,如果您的終端支持顏色:

target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo -e "Found symbol: \e[1;36m$symbol\033[0m at \e[1;34m$library\033[0m"; fi ; done; done; done;

我相信有人會發現性能提升。

輸出:

Found symbol: XCreateColormap at [/usr/lib/libX11.so.6]
Found symbol: XCreateWindow at [/usr/lib/libX11.so.6]
Found symbol: XIfEvent at [/usr/lib/libX11.so.6]
Found symbol: XMapWindow at [/usr/lib/libX11.so.6]
Found symbol: XOpenDisplay at [/usr/lib/libX11.so.6]
Found symbol: __libc_start_main at [/lib/tls/i686/cmov/libc.so.6]
Found symbol: __stack_chk_fail at [/lib/tls/i686/cmov/libc.so.6]
Found symbol: glClear at [/usr/lib/mesa/libGL.so.1]
Found symbol: glClearColor at [/usr/lib/mesa/libGL.so.1]
Found symbol: glFlush at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXChooseFBConfig at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXChooseVisual at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateContext at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateNewContext at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateWindow at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXGetVisualFromFBConfig at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXMakeContextCurrent at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXMakeCurrent at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXQueryVersion at [/usr/lib/mesa/libGL.so.1]

你看過ltrace了嗎? 它在運行時攔截對共享庫函數的調用,並在它們發生時打印有關它們的信息。

由於這是一個動態解決方案,因此它不會打印任何部分程序中永遠不會執行的庫調用的信息。 但根據您的需求,它可能仍然有用。

我不知道一個,甚至nm對於你似乎想要的東西也是有限的。 此外,預加載(GNU鏈接器)可能會使您使用據稱可以執行此操作的工具后所做的任何假設無效。 請參見ld.so手冊頁 任何人都可以使用LD_PRELOAD覆蓋符號的分辨率,因為它在正常情況下會發生。

但是,即使沒有調試器,也可以使用LD_DEBUG來查看最終使用的函數。

也許nm工具可以幫助您,因為它顯示二進制文件中包含的符號名稱。
它就像ABC一樣簡單:

nm my_binary

這可以使用逆向工程中稱為靜態分析的技術來實現

你需要一個反匯編程序。 http://en.wikipedia.org/wiki/Disassembler

IDA PRO是一個很好的反匯編程序,可以回答你的問題。它能夠讀取ELF文件格式,但不幸的是它不是免費的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM