用於所有C專家那裏挑戰: 在Linux計算機上,你有一個已編譯的C程序,並且給出了它的源代碼:執行代碼內的,如果(0)塊
...
char buffer[20];
int code;
gets(buffer);
if(code==1234) ...
...
...
if(0) func();
您不擁有root權限並且該程序是隻讀的。找到一種執行func的方法。我確信這是可能的,所以請不要發佈任何「這是不可能的」答案。 祝你好運!
用於所有C專家那裏挑戰: 在Linux計算機上,你有一個已編譯的C程序,並且給出了它的源代碼:執行代碼內的,如果(0)塊
...
char buffer[20];
int code;
gets(buffer);
if(code==1234) ...
...
...
if(0) func();
您不擁有root權限並且該程序是隻讀的。找到一種執行func的方法。我確信這是可能的,所以請不要發佈任何「這是不可能的」答案。 祝你好運!
由於我們的源代碼,我想作以下修改和重新編譯:
-if(0) func();
+func();
認真的回答,有成千上萬的做這件事的方式(砍死環境,緩衝區溢出等) ,但常見的錯誤是一個好的編譯器應該優化if (0) {}
。如果是這種情況,將不可能執行func()
。如果沒有,那麼我會啓動我的可靠調試器並跳到正確的位置。
您不能編輯源代碼並重新編譯程序,您必須使用tho原始編譯程序 – 2011-05-06 00:44:36
您說過'該程序是隻讀的',而不是來源。 – orlp 2011-05-06 00:45:08
「如果是這種情況,就沒有辦法執行func()」 - 這根本就不是真的。如果'func'被編譯到二進制文件中,它可以通過將其地址存儲在堆棧中來調用; 'if(0)func();'只是錯誤的方向。 – 2011-05-10 01:39:59
它可能或不可能。如果沒有其他引用func(),編譯器可能已經決定不首先爲其生成代碼 - 死代碼可以完全被優化。
這個問題是相當得以確認,反正。 「該程序是隻讀的」是什麼意思?源代碼或可執行文件?我們是否在運行時從進程內部攻擊它,在進程內部通過改變源代碼,在進程外嘗試以有趣的方式調用它,...?
如果編譯器爲該函數生成了代碼(即它沒有被死代碼優化器切斷),並且您有一個調試器和調試符號,只需附加一個調試器並告訴它查找並調用func()。
如果您想在運行時利用代碼,您可以在gets()中導致緩衝區溢出,並從內部控制進程,但仍然必須找到func()以便跳轉到該進程 - - 如果編譯器沒有爲它生成代碼,讓源代碼在這裏不會幫助你,沒有什麼能夠幫到你。
的確,除非你的編譯器被完全破壞,'func'甚至不會存在於發出的二進制文件中。所以它不能被調用。 – 2011-05-06 01:04:50
@R ..不,只有* call * to'func'不存在。如果編譯代碼,則聲明'func',amd * may *可能被定義 - 在這種情況下,它的地址可以通過溢出gets來存儲在堆棧上的返回地址。如果可執行文件沒有被剝離,'func'的地址可能已經通過nm獲得。 – 2011-05-10 01:36:17
「如果沒有其他對func()的引用,編譯器可能已經決定不首先爲它生成代碼」 - 只有當func是靜態時纔會生成代碼。如果它是全局的,編譯器不能消除它。 – 2011-05-10 01:49:53
顯然,在運行可執行文件之前執行著名的set 0=1
命令。
但嚴重的是,這是後題外話......
的答案就在那等待與gets(buffer);
發生的未經檢查的緩衝區溢出和什麼樣的堆棧看起來像一個瞭解。
您可以嘗試通過溢出buffer
返回地址設置爲func()
通話。
http://en.wikipedia.org/wiki/Stack_buffer_overflow#Exploiting_stack_buffer_overflows
在這裏粘貼一個鏈接並不是一個好主意,除非你在它周圍添加一些評論來表達你的答案。 – vpit3833 2011-05-06 00:50:30
什麼是'...'s? – SLaks 2011-05-06 00:42:16
我想這是可能的,但你需要指定更多的信息(一個例子:用於構建程序的編譯器和選項 - 海灣合作委員會建立與優化的任何級別甚至不會有'FUNC()的調用'由於死碼消除而在程序映像中)。 – 2011-05-06 00:47:03
-1和F給你的教授/助教。這個問題完全是無稽之談。 – 2011-05-06 01:05:49