2011-05-06 81 views
-2

用於所有C專家那裏挑戰: 在Linux計算機上,你有一個已編譯的C程序,並且給出了它的源代碼:執行代碼內的,如果(0)塊

... 
char buffer[20]; 
int code; 
gets(buffer); 
if(code==1234) ... 
... 
... 
if(0) func(); 

您不擁有root權限並且該程序是隻讀的。找到一種執行func的方法。我確信這是可能的,所以請不要發佈任何「這是不可能的」答案。 祝你好運!

+1

什麼是'...'s? – SLaks 2011-05-06 00:42:16

+2

我想這是可能的,但你需要指定更多的信息(一個例子:用於構建程序的編譯器和選項 - 海灣合作委員會建立與優化的任何級別甚至不會有'FUNC()的調用'由於死碼消除而在程序映像中)。 – 2011-05-06 00:47:03

+7

-1和F給你的教授/助教。這個問題完全是無稽之談。 – 2011-05-06 01:05:49

回答

1

由於我們的源代碼,我想作以下修改和重新編譯:

-if(0) func(); 
+func(); 

認真的回答,有成千上萬的做這件事的方式(砍死環境,緩衝區溢出等) ,但常見的錯誤是一個好的編譯器應該優化if (0) {}。如果是這種情況,將不可能執行func()。如果沒有,那麼我會啓動我的可靠調試器並跳到正確的位置。

+2

您不能編輯源代碼並重新編譯程序,您必須使用tho原始編譯程序 – 2011-05-06 00:44:36

+0

您說過'該程序是隻讀的',而不是來源。 – orlp 2011-05-06 00:45:08

+0

「如果是這種情況,就沒有辦法執行func()」 - 這根本就不是真的。如果'func'被編譯到二進制文件中,它可以通過將其地址存儲在堆棧中來調用; 'if(0)func();'只是錯誤的方向。 – 2011-05-10 01:39:59

3

它可能或不可能。如果沒有其他引用func(),編譯器可能已經決定不首先爲其生成代碼 - 死代碼可以完全被優化。

這個問題是相當得以確認,反正。 「該程序是隻讀的」是什麼意思?源代碼或可執行文件?我們是否在運行時從進程內部攻擊它,在進程內部通過改變源代碼,在進程外嘗試以有趣的方式調用它,...?

如果編譯器爲該函數生成了代碼(即它沒有被死代碼優化器切斷),並且您有一個調試器和調試符號,只需附加一個調試器並告訴它查找並調用func()。

如果您想在運行時利用代碼,您可以在gets()中導致緩衝區溢出,並從內部控制進程,但仍然必須找到func()以便跳轉到該進程 - - 如果編譯器沒有爲它生成代碼,讓源代碼在這裏不會幫助你,沒有什麼能夠幫到你。

+0

的確,除非你的編譯器被完全破壞,'func'甚至不會存在於發出的二進制文件中。所以它不能被調用。 – 2011-05-06 01:04:50

+1

@R ..不,只有* call * to'func'不存在。如果編譯代碼,則聲明'func',amd * may *可能被定義 - 在這種情況下,它的地址可以通過溢出gets來存儲在堆棧上的返回地址。如果可執行文件沒有被剝離,'func'的地址可能已經通過nm獲得。 – 2011-05-10 01:36:17

+1

「如果沒有其他對func()的引用,編譯器可能已經決定不首先爲它生成代碼」 - 只有當func是靜態時纔會生成代碼。如果它是全局的,編譯器不能消除它。 – 2011-05-10 01:49:53

-1

顯然,在運行可執行文件之前執行著名的set 0=1命令。

但嚴重的是,這是後題外話......

4

的答案就在那等待與gets(buffer);發生的未經檢查的緩衝區溢出和什麼樣的堆棧看起來像一個瞭解。