以使用 libsqlite 為例說明如何找到程式的進入點

一直對於如何善用 runtime 資訊找到程式進入點很有興趣, 終於有個不錯的小例子。

目標

假設要觀察的專案有用到 sqlite 儲存資料, 從使用方式知道一開始會先載入 sqlite 的內容, 現在想找到程式讀取第一筆資料的進入點。

第一步先觀察程式如何使用 sqlite, 是用 shared lib 或是直接包含在程式裡:

$ ldd PROG | grep sqlite

Case 1: 沒有結果, 表示 sqlite 的實作直接含在 PROG 裡面

找出和 sqlite 相關的 API:

$ nm PROG | grep sqlite | awk '{print $NF}' | xargs c++filt

或是查官網文件也成, 不過個人覺得 nm + c++filt 這招比較方便也比較酷。

觀察一下後, 得知開檔的 API 有: sqlite3_open, sqlite3_open16, sqlite3_open_v2, 之後用 cgdb 執行程式, 都設中斷點, 就結案了。

Case 2: 有 grep 結果, 表示在 shared lib 裡

若不想看官方文件, 也想來個動態搜集 API, 可用 ltrace:

$ ltrace -l /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 PROG

其中 libsqlite3 的路徑是從 ldd PROG 得知的。

安裝需要的 debug symbol, 以做進一步觀察:

$ aptitude search sqlite | grep dbg # 找到 libsqlite3-0-dbg
$ sudo aptitude install libsqlite3-0-dbg

再來就用 cgdb 執行程式, 準備設中斷點, 結案。

相關參考資料:

留言

這個網誌中的熱門文章

virtualbox 使用 USB 裝置

熟悉系統工具好處多多

如何 git merge 更改檔名的檔案