簡體   English   中英

如何找出用於構建二進制文件的* .c和* .h文件?

[英]How to find out *.c and *.h files that were used to build a binary?

我正在建立一個構建多個共享庫和可執行文件的項目。 用於構建這些二進制文件的所有源文件都在單個/ src目錄中。 因此,弄清楚使用哪個源文件來構建每個二進制文件並不明顯(存在多對多關系)。

我的目標是編寫一個腳本,該腳本將為每個二進制文件解析一組C文件,並確保僅從它們中調用正確的函數。

一種選擇似乎是嘗試從Makefile中提取此信息。 但這不適用於生成的文件和標頭(由於依賴於Includes)。

另一種選擇是簡單地瀏覽調用圖,但這會變得很復雜,因為許多函數是通過使用函數指針來調用的。

還有其他想法嗎?

您可以首先使用調試信息(gcc -g)編譯您的項目,然后使用objdump獲取包含的源文件。

objdump -W <some_compiled_binary>

矮格式應包含您要查找的信息。

 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    < c>   DW_AT_producer    : (indirect string, offset: 0x5f): GNU C 4.4.3 
    <10>   DW_AT_language    : 1    (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0x28): test_3.c    
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x36): /home/auselen/trials    
    <19>   DW_AT_low_pc      : 0x82f0   
    <1d>   DW_AT_high_pc     : 0x8408   
    <21>   DW_AT_stmt_list   : 0x0  

在此示例中,我從test_3編譯了目標文件,該文件位於... / trials目錄中。 然后,當然,您需要為此編寫一些腳本來收集相關的源文件名。

這是一個想法,需要根據您的特定構建進行優化。 進行構建,並使用腳本對其進行記錄(例如, script log.txt make clean all )。 最后一步(或最后一步)應該是目標文件的鏈接。 (提示:尋找cc -o <your_binary_name> )。 該行應鏈接所有.o文件,這些文件應在樹中具有相應的.c文件。 然后grep將所有包含的頭文件的.c文件。

如果樹中.c文件中的名稱重復,那么我們需要查看鏈接器行中的完整路徑,或者從Makefile

馬哈茂德(Mahmood)以下建議也應該起作用。 如果您的圖像帶有符號,則strings <debug_image> | grep <full_path_of_src_directory> strings <debug_image> | grep <full_path_of_src_directory>應該會給您C文件列表。

首先,您需要將調試符號與剛剛編譯的二進制文件分開。 檢查有關如何執行此問題的方法: 如何在構建目標之外生成gcc調試符號?

然后,您可以嘗試自己解析該文件。 我知道如何為Visual Studio做到這一點,但是當您使用GCC時,我將無法進一步為您提供幫助。

您可以使用Unix nm工具。 它顯示了對象中定義的所有符號。 因此,您需要:

  1. 在二進制文件上運行nm並獲取所有未定義的符號
  2. 在二進制文件上運行ldd以獲取其所有動態依賴項的列表(二進制文件鏈接到的.so文件)
  3. 在步驟2中找到的每個.so文件上運行nm

這將為您提供二進制文件使用的動態符號的完整列表。

例:

nm -C --dynamic /bin/ls
....skipping.....
00000000006186d0 A _edata
0000000000618c70 A _end
                 U _exit
0000000000410e34 T _fini
0000000000401d88 T _init
                 U _obstack_begin
                 U _obstack_newchunk
                 U _setjmp
                 U abort
                 U acl_extended_file
                 U bindtextdomain
                 U calloc
                 U clock_gettime
                 U closedir
                 U dcgettext
                 U dirfd

ls命令使用所有大寫字母“ U”的符號。

如果您的目標是分析C源文件,則可以通過自定義GCC編譯器來實現。 您可以為此目的使用MELT (MELT是擴展GCC的高級領域特定語言)-在GCC內添加以MELT編碼的自己的分析過程,但您應該首先了解GCC中端內部表示形式(Gimple,Tree ,...)。

自定義GCC需要花費幾天的時間(主要是因為GCC內部細節非常復雜)。

隨時詢問我有關MELT的更多信息。

暫無
暫無

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

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