2012-09-26 49 views
3

幾天前,我在Notepad ++中意外地打開了商業應用程序的C++可執行文件,發現存儲在可執行文件中的原始源代碼有相當多的信息。在C++可執行文件中存儲了多少源信息

可執行我能找到的文件名(app.c,dlgstat.c,...),函數名(GetTickCountDispatchMessageA,...)和小片的源代碼,主要是條件(szChar != TEXT('\0')iRow < XTGetRows(hwndList)內)。之後,我檢查了另一個QT可執行文件,並且:是,再次輸入源文件名和方法簽名。因此,我想知道在C/C++可執行文件中真正存儲了多少源代碼信息(例如,使用QT或MinGW編譯)。這可能是某種調試版本仍然包含原始源代碼?這些信息是用於某些反思的東西嗎?出版商是否有任何理由不刪除這些東西?

+6

的條件可能是從'assert'宏(並且不定義'NDEBUG'一個版本)的字符串文字。如果您使用調試信息編譯包含 –

+0

了很多東西(即「-g」如果你是一個古老的計時器),而不是如果你關掉調試信息和優化(即「-O3」)。 –

+0

它可能是用存儲在其中的調試符號編譯的。或者像@ R.MartinhoFernandes所建議的那樣。 – nullpotent

回答

11

C/C++可執行文件中存儲了多少源代碼信息?

在實踐中,並不多。運行時不需要源代碼。你的名字來自於兩件事情中的字符串:

  • 函數名(例如GetTickCount)是從其他模塊導入函數的名稱。這些名稱在運行時是必需的,因爲函數是動態解析的(通過調用GetProcAddress和函數名稱)。

  • 條件可能是斷言:assert宏將其參數字符串化,以便在它觸發時知道未滿足什麼條件。

如果你建立一個DLL,它也將包含所有的它導出函數的名字,這樣他們就可以在運行時得到解決(這同樣適用於其他共享對象的格式可能是真的)。

調試符號也可能包含一些原始源代碼,儘管它取決於調試符號使用的格式。這些符號可能包含在二進制文件本身或輔助文件中(例如Windows上使用的.pdb文件)。

+1

謝謝,這很有道理。我認爲我發現的部分是肯定的,它們都是條件表達式。我猜測斷言還確保源文件的路徑被打包到二進制文件中。 – Danielku15

2

Windows函數名稱:它們可能只是因爲它們是動態訪問的 - 在您的程序的某處有一個GetProcAddress來獲取它們的地址。儘管如此,沒有理由擔心,每個應用程序都使用WinAPI,所以從這些信息中找不到有關您的可執行文件的信息。

條件:可能從一些assert-like宏;它們包含在內以允許assert打印失敗條件觸發失敗的斷言。無論如何,在發佈模式下,斷言應該被自動刪除。

源文件名和方法簽名:可能來自某些用法的__FILE____func__宏;大概再次從assert

有關程序內部結構的其他信息源是RTTI,它必須爲每個類型提供一些表示,以便typeid可以使用。如果你不需要它的功能,你可以禁用它(但我不知道這是否可能在Qt項目中)。

0

混合成一個C++應用程序(如果在編譯器中啓用和調試符號),你會發現大部分全局符號的名稱的二進制文件,但與編碼符號的調用簽名,如果它是多餘的「裝飾文字」功能或方法。同樣,字符串的文字也以明文形式嵌入。但是,不能在哪裏找到類似於編譯器用於創建二進制可執行文件的實際源代碼。該信息在編譯過程中丟失,如果在構建中使用C++模板,則特別難以進行反向工程。

相關問題