有的時候,我們需要關注一下乙個動態庫的呼叫流程,但我們並不想關注內部處理。目前,現在的分析工具,多數會得到乙份完整的、複雜的呼叫關係,這裡,給出乙個很簡單的處理辦法
以獲取apache對mod_ssl.so的呼叫為例
1、在mod_ssl.so的**中,接入兩個函式,用來輸出函式呼叫和函式返回時的日誌。下面是簡單的輸出到錯誤流的辦法。
1
2
3
4
5
6
7
8
9
10
11
12
void
__cyg_profile_func_enter(
void
*funaddr,
void
*callsite)__attribute__((no_instrument_function));
void
__cyg_profile_func_enter(
void
*funaddr,
void
*callsite)
void
__cyg_profile_func_exit(
void
*funaddr,
void
*callsite)__attribute__((no_instrument_function));
void
__cyg_profile_func_exit(
void
*funaddr,
void
*callsite)
2、將mod_ssl.so編譯成debug版本, 並且支援上面的修改,新增編譯引數make cflags='-g -o0 -finstrument-functions',將生成的新的庫新增到執行環境中。
3、測試,收集輸出的日誌,具體的輸出日誌與程式的配置有關。
4、處理日誌,當前的日誌只是列出了一些函式位址,需要將位址轉義為函式名。獲取當前模組的函式位址列表
readelf -s ./.libs/mod_ssl.so | grep -v und | awk '' > fun.list
這個位址列表,只是相對位址,並不是實際的位址,實際位址每個例項都不一樣。gdb -p ***除錯程序,檢視列表中任意乙個函式的真實位址
disassemble 函式名 看到的第一行就是了,根據匯出列表的函式位址值和獲取的值,可以算出乙個偏移,用這個偏移將輸出日誌中的位址全部轉換為相對位址。
5、獲取呼叫方位址的函式位址,日誌列印出來的呼叫位址是跳轉位址,並不是呼叫函式的位址,用命令來獲取對應的函式位址
addr2line 0001ec09 -e mod_ssl.so -f這是乙個示例,需要自己用指令碼批量處理。
6、處理之後,就獲取乙份由函式相對位址組成的日誌和乙份對應的函式名,將日誌進行指替換就可以了得到用函式名表示的呼叫關係了。將呼叫函式名無法獲取的行提取(grep '\?')即獲取了乙個完整的模組,不包含內部處理呼叫關係圖。
GCC靜態庫的另乙個問題
對於c 生成的靜態庫,按照一般的想法去鏈結,會出現所有的符號都無法找到的錯誤。這裡所謂的一般的想法就是把原始檔放在最後邊,如 g o test.exe l l t test.cpp,那麼得到的錯誤資訊為 test.cpp text 0x31 undefined reference to t test...
Linux第乙個動態庫
動態庫一般以.so結尾,就是shared object的意思.其基本生成步驟為 編寫函式 編譯生成動態庫檔案,要加上 shared 和 fpic 選項 庫檔名以lib開頭,以.so 結尾。fpic 使輸出的物件模組是按照可重定位位址方式生成的。shared指定把對應的原始檔生成對應的動態鏈結庫檔案l...
Linux第乙個動態庫
動態庫一般以.so結尾,就是shared object的意思.其基本生成步驟為 編寫函式 編譯生成動態庫檔案,要加上 shared 和 fpic 選項 庫檔名以lib開頭,以.so 結尾。fpic 使輸出的物件模組是按照可重定位位址方式生成的。shared指定把對應的原始檔生成對應的動態鏈結庫檔案l...