2009-07-31 103 views
1

在不更改構建過程或包含源文件的情況下,任何人都可以想出一種方法來編譯兩段代碼,它們在編譯時會生成相同的程序集,但仍然執行不同的操作?我已經知道爲什麼這個應該是是不可能的,所以請不要麻煩解釋。確實有辦法做到這一點,主要是通過尋找方法來隱藏源代碼中的信息,而這些信息在可執行的地方以外的地方結束。聰明的方式使相同的程序集以不同的方式執行?

這是一個相當枯燥乏味的例子,它可以做到這一點:創建一段代碼,需要很長時間才能解析,但在編譯過程中得到優化(或者只是添加太多的空白,以至於磁盤I/O速度變慢彙編)。在構建過程中,讓您的程序同時生成一個exe和一個dll。根據dll和exe上創建的時間戳之間的差異,讓程序的行爲有所不同。儘管如此,這是一個非常糟糕的例子。我想知道是否有人能夠更聰明地提出任何事情。

也可以以某種方式生成不同的調試輸出,並改變代碼的運行方式,但這也有點蹩腳。

當然,如果您的代碼似乎沒有檢查自身或輸出,那麼它更令人印象深刻。如果有人看着你的代碼會感到震驚,這兩個版本的表現不一樣,這是一個很好的答案。

回答

3

下面是使用Python作爲僞一個普通的例子:

input = raw_input("type something!\n") 
if "a" in input: 
    print "Great job!" 
else: 
    print "Ohh, too bad." 

如果寫道,編譯語言和編譯它,大會將是完全一樣的,但它可能每次都產生不同的行爲,你執行它!順便說一句,這正是你的例子所描述的。基於外部輸入改變執行路徑是編程的一個非常重要的部分。

要說明:當兩個可執行文件的程序集完全相同時,執行將會完全相同。行爲可能不同,但這完全取決於每次運行時接收到的輸入。使輸入成爲創建可執行文件的時間是有效的,但實質上是無用的。

+0

@Darth:我同意製作輸入是創建時間非常蹩腳。我想知道是否有更巧妙的技巧可以使用。 – Brian 2009-07-31 14:44:39

1

讓我們看看我是否理解。假設你聲稱你可以做到這一點。您編寫兩個不同的程序,從而生成相同的程序集。你把每個都放在CD-ROM上。這些CD-ROM是一點一點的。你用鋼筆標註他們A和B.我把一個或另一個放入我的電腦並安裝它。如果我安裝了標有「A」的磁盤,程序將顯示「我是程序A」。如果我安裝了標有「B」的磁盤,程序將顯示「我是程序B」。

我看不出這是怎麼可能的。

你肯定有一些技巧。如果您可以看到我放入哪個磁盤,您可以在手機上祕密按A或B,向程序檢索到的Web服務器發送消息。

+0

我並不是聲稱這些CD-ROM是一點一點地相同的。我只是說* *程序集是相同的,並且用於生成每個程序的構建過程是相同的。 – Brian 2009-07-31 14:42:01

+0

你的意思是機器語言代碼?可能存在環境差異;例如CPU的零標誌最初可能是0或1,所以「分支如果爲零」的執行方式不同。在一些舊的操作系統上,分配的內存不會被清零,因此如果您在一步中編譯並執行,程序可以分配大量內存並在其中搜索編譯器留下的工件。 – 2009-08-02 22:56:52

1

如果你工作得很辛苦,你應該可以擁有完全相同的機器指令塊,通過跳轉到原始指令之一的「中間」執行兩個不同的操作,在這種情況下,CPU會看到一個完全不同的指令序列。 IIRC是在80年代初爲8位計算機提供的高度優化的ROM空間代碼,爲節省空間做了相當多的工作。

+0

這也許是讓你看代碼的人抓住正在發生的事情的一種微妙和聰明的方式。但是,實際上造成這種跳躍的發生並沒有在組裝上有什麼不同,這是我所問的。 – Brian 2009-07-31 14:43:22

1

如果它在內存中的位模式相同,並且程序在相同的起始狀態下執行,則各個指令的確定性將強制確定性答案。 (否則你將無法調試任何東西)。

現在,您可能會得到基於外部狀態(「近期發生的宇宙射線CPU芯片?」)產生不同結果的說明。這會產生不同的結果。 在x86上產生這種效應的一個特定指令是RDTSC,即「讀取時間戳記計數器」,讀取自執行開始以來當前CPU的時鐘數量。如果操作系統中斷你的應用程序,並且不保存/恢復RDTSC內容,則不同的執行將在代碼中的同一點(「最近的宇宙中斷命中CPU芯片」)看到不同的RDTSC值。

真正的問題在於結果不受程序控制,因此很難確保程序的行爲以可控的方式不同。

你想用這個完成什麼?

1

那麼,它不能真正被'執行'不同。它只能以你所描述的方式執行(不過,模糊的是,它仍然遵循給定環境的執行規則)。

這聽起來像你希望你的代碼行爲不同,同時完全避免使用條件語句。

這是不可能的,出於好的理由:計算機是合乎邏輯的,即使您對它進行編程以使其在不同的環境中表現不同,它仍然遵循您佈局的規則。並感謝天啊,因爲如果計算機有可能根據它自己的敏感性來決定,那麼我們的程序員將會遇到一些麻煩...

int k = 2; 

// computer internally has decided k should = 5, because it is upset about a prior 
// argument, so you must actually write: 

computer.pleaseWork(); 
int k = 2; 
相關問題