題:
機器代碼中的哪些提示可以指向用於生成它的編譯器?
WilliamKF
2013-03-20 01:01:49 UTC
view on stackexchange narkive permalink

當我查看應用程序的機器代碼時,是否可以從生成的機器代碼中辨別出提示和模式,這些提示和模式可以指示使用哪個編譯器(可能是版本)來生成它?

了解用於生成應用程序的編譯器是否可以幫助我更有效地將工程從生成的對象反向轉換為源代碼,如果確實有幫助,怎麼做?

當您說“幫助我更有效地將生成的對象反向工程到源代碼可能是什麼”時,您的目標是反編譯代碼還是理解代碼的功能?
甚至有可能完全反編譯代碼?我會說如果可能要反編譯,否則至少要了解其功能。
七 答案:
Andrew
2013-03-20 01:46:22 UTC
view on stackexchange narkive permalink

這方面有一些學術研究,您想要的關鍵字是“工具鏈來源”。 Nate Rosenblum上有一篇關於這個主題的不錯的論文,距離我閱讀本文已有一段時間了,但是您可以使用許多技術來建立此信息。我認為有些人使用機器學習,而另一些人可以使用一大堆關於編譯器行為的啟發式或公理式。

確定此名稱的用途僅限於IMO。在對抗性情況下,當您試圖獲取有關惡意軟件組或威脅參與者的情報時,它可能會很有用,但請記住,此類信息可能會被混淆或破壞。該信息的一種潛在用途是確定使用某些公司的SDK編譯了一些二進制軟件,其中包括具有該公司獨有的簽名信息的編譯器。建立工具鏈來源可以幫助您確定購買SDK的人違反了許可或合同,例如製造惡意軟件。

行為差異的一個例子是參數編寫。有兩種方法可以將值放置到堆棧上,一種使用'push',另一種使用 mov ,其地址基於 esp 作為目標操作數。因此,一個編譯器可以執行以下操作:

 push eaxpush ebx 

另一個編譯器可以這樣做:

 mov [esp + foo],eaxmov [esp + foo + 4],ebx 

他們做到了。通常,至少在一些非常有限的測試/觀察中,MSVC做第一個示例,GCC做第二個示例...

Mike
2013-03-20 01:46:15 UTC
view on stackexchange narkive permalink

在查看機器代碼時,通常會出現一個“痕跡”,除非產生的二進制代碼是如何清除的。例如,如果您使用的工具是 hexedit 代碼>,您可以在機器代碼中看到包含構建信息的部分:

enter image description here

很顯然,您可以在其中看到,我使用GCC版本4.6.3。其他編譯器將具有其他類型的簽名 Microsoft的“豐富”簽名

有趣的是,剝離文件後的外觀如何...
問題特別是關於機器代碼。希望OP在詢問之前已經嘗試了一些基本方法,例如使用十六進制編輯器或“ objdump”並查找瑣碎的字符串。在這種情況下,這不是答案。但是可以肯定的是,如果他們不知何故,那將是有意義的。 ;-)
@underscore_d-“一個希望”,確實是一個。我只是在確保我們不必僅希望OP知道這一點。我喜歡不要做太多的假設!
Igor Skochinsky
2013-03-20 02:29:37 UTC
view on stackexchange narkive permalink

在Recon上有一個名為“包裝遺傳學:自私密碼”的演講,描述了一種解決方法。他們使用一些統計信息從編譯的程序中提取最常見的代碼序列,並用它來檢測解包的結束,但是該方法可以輕鬆地用於識別特定的編譯器。

請參見幻燈片15: http://blog.zynamics.com/2010/07/16/recon-slides-packer-genetics-the-selfish-code-bochspython/

幻燈片似乎被截斷了,我相信實際演示會獲得更多信息。

Remko
2013-03-20 19:53:24 UTC
view on stackexchange narkive permalink

了解用於生成應用程序的編譯器是否可以幫助我更有效地將生成的對象反向工程到源代碼,如果確實有幫助,怎麼做?

由於以下原因,我認為了解二手編譯器是非常重要的一步:

  1. 它可以幫助您選擇合適的工具來分析目標。 li>
  2. 知道運行時對於分析很重要,例如在Delphi中, TFileStream 是用於讀取/寫入文件的常用對象。了解該對象的vtable可以幫助我了解是否可以讀取/寫入/尋找偏移量等。
  3. ol>

    使用一個例子來闡明1:諸如 IDR之類的工具可能比IDA Pro更適合Delphi目標。或者至少我們可以用它生成一個MAP文件/ IDC腳本,以改善IDA中的符號。但是對於用Visual Basic編寫的目標,可以使用 VB反編譯器等。

waliedassar
2013-04-17 11:57:13 UTC
view on stackexchange narkive permalink

我想確定編譯器版本之前應該做的第一件事,除非從字面上講是編譯器版本而不是鏈接器版本,否則請檢查可執行文件的PE標頭的“ MajorLinkerVersion”和“ MinorLinkerVersion”字段,是否為EXE。 ,DLL或SYS。參見下面的列表。

次要版本

0x5 0x0(5.0)Borland C ++ / MS Linker 5.0

0x6 0x0(6.0)Microsoft VIsual Studio 6

0x7 0xA(7.10)Microsoft VIsual Studio 2003

0x8 0x0(8.0)Microsoft VIsual Studio 2005

0x9 0x0(9.0)Microsoft VIsual Studio 2008

0xA 0x0(10.0)Microsoft VIsual Studio 2010

0x2 0x15(2.21)MinGw

0x2 0x19(2.0.0.25)Borland Delphi(鏈接器2.0.0.25)

不幸的是,打包程序和保護程序傾向於覆蓋這些值以編寫自己的值和/或加強猜測原始編譯器的過程。

此外,可執行文件的資源目錄也是搜索特定鏈接器信息的好地方。例如具有名為“ DVCLAL”的資源的RT_RCDATA是Borland C ++或Delphi的標誌,在MSVC生成的可執行文件的情況下,“ RT_MANIFEST”可以告訴我們它鏈接到的運行時DLL的特定版本,因此也可以告訴我們編譯器版本。 / p>

此外,“ TimeDateStamp”字段設置為0x2A425E19的可執行文件是使用Delphi構建的標誌。

現在,如果要從彙編代碼確定編譯器,則該標誌的最新MSVC編譯器版本看到在入口處生成堆棧cookie的函數。

似乎,入口處有一條JMP指令,後跟字符串“ fb:C ++ Hook” Borland C ++的標誌,等等。

Michael Anderson
2013-03-20 03:35:49 UTC
view on stackexchange narkive permalink

了解用於生成應用程序的編譯器是否可以幫助我更有效地將生成的對象反向工程到源代碼,如果確實有幫助,怎麼做?

是的,應該會有所幫助。

甚至更好:

  • 確切的編譯器版本;
  • 確切的命令行參數;
  • 構建環境(操作系統,補丁程序級別,...)。

該想法是:

  • 為許多不同的案例(小的小程序)構建測試案例,以展示不同的結構並進行編譯;

  • 查看生成的機器代碼(注意模式)。

其中許多情況可以在編譯器的主要版本( if 和其他控制結構,基本語言函數等)上進行概括。

對於同一程序,可能有一些特定於編譯器的優化會大相徑庭。

(我想知道是否有用於comm的測試用例庫開/有用的案例,以幫助對特定編譯器生成的機器代碼進行逆向工程。)

抱歉,直言不諱,但您需要進行格式化,並擺脫掉隨機大寫字母。現在,答案很難讀。
編輯是一項改進嗎?
Yifan
2013-03-20 01:17:21 UTC
view on stackexchange narkive permalink

如果僅談論機器代碼(或彙編代碼),則沒有太多信息。大多數現代編譯器會產生類似的輸出,否則輸出將不足以看到差異。可能表明問題的一件事是編譯器優化,這是我沒有經驗的,應該由其他人來介紹。如果您確實擁有整個ELF文件,並且有可用的符號,則可以根據哪種類型得出結論。庫是鏈接的(例如, libgcc 將是贈品)或編譯器特定功能的名稱。如果ELF包含調試信息,您甚至可能會看到類似“ GCC:(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3”的信息。如果您正在使用C ++代碼,則符號名稱修飾可以將其放棄。

但是,正如您問自己的那樣,我很好奇為什麼需要此信息。我不知道知道使它起作用的編譯器將為您帶來多少幫助。我在ARM上進行了更多工作,並且在該平台上知道,編譯器/彙編代碼必須遵守一個應用程序二進制接口。該ABI提供有關如何調用函數,應將哪些寄存器用作什麼的信息,等等。我知道,對於沒有嚴格ABI的平台,操作系統通常會向開發人員提供有關此類主題的信息。無論如何,編譯器都應創建兼容的代碼,因此我不知道用於標識創建代碼的編譯器有什麼用。

對於為什麼輸出沒有差異,這個答案缺乏理論依據或參考。我在x86上的個人經歷與此矛盾,但是我的樣本量太小,不能說總體上是正確的。還要問為什麼需要此信息並不是答案的真正內容,而是更多的澄清要求,更適合於對該問題的評論。
感謝您的建設性批評。我是新來的回答問題的人,所以我不了解所有細節。我將嘗試查找更多參考。
編譯器之間有許多驚人的差異,尤其是在x86代碼中,有很多不同的指令可供選擇。 Switch語句的實現,堆棧佈局決策和寄存器選擇都可以提供有關使用哪個編譯器的提示。


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...