2013-05-18 205 views
3

問題:運行代碼

運行存儲在另一C程序作爲彙編指令的堆或數據部分中的非平凡的C程序。

我的進步:

冉一組打印的東西到stdout簡單的指令。指令存儲在堆中,我允許包含指令的頁面被執行,然後調用原始數據,就像它是一個函數一樣。這工作得很好。

接下來,我想給出任何靜態鏈接的C程序,只是看它的二進制文件,並能夠運行它的主要功能,而它在從其他C程序存儲器。

我相信問題是: *跳躍到的主要功能代碼 *改變其被鏈接時,使它們相對於創建的二進制文件的地址,現在的代碼就在於在內存

請讓我知道我的方法是好的還是我錯過了一些重要的事情,以及最好的方式是什麼。

謝謝

+2

的問題正是你所列舉的那些。第一個叫做「跳入入口」,第二個叫「重新定位」。您可能需要查閱操作系統的二進制加載器的源代碼。 – 2013-05-18 19:50:04

+0

如果你已經有了靜態鏈接的其他程序,你不能只使用'exec'嗎? –

+0

是的,你錯過了一些東西:考慮到在其他編程語言中,你將執行基本相同的步驟,而對於其他操作系統,這些步驟將會改變。你現在可以看到這個問題與C很少有關係,幾乎與你的實現有關嗎?你可能想找出什麼「實施」的意思,順便...... – Sebivor

回答

1

現代操作系統儘量不要讓你在你的數據執行代碼正是因爲它是一個安全噩夢。 http://en.wikipedia.org/wiki/No-execute_bit

即使你已經過去了,也會有更多'陷阱',因爲兩個程序都會認爲他們'擁有'堆棧/堆等。一旦新程序執行完畢,舊程序中的各種內存將被禁用。 (exec存在只是爲了這個原因,乾淨地從一個程序轉到另一個。)

如果你真的需要加載代碼,你應該做的第一個庫,然後使用dlopen運行它。 (您可以使用objcopy提取你想要的子程序,並把它變成一個庫)。

或者,你可以啓動程序(在另一個進程),並使用strace注入代碼的一點點到他們的過程來控制它。

(如果你真的想進入shell代碼,你應該這麼說的。這是蠕蟲的一個整體「諾特爾即可。)

+1

你錯過了「我允許執行包含指令的頁面」的問題的一部分。 – 2013-05-18 20:26:23

+0

哎呀,你是對的,我錯過了。您仍然需要手動重新鏈接。讓objcopy和dlopen爲你做這件事會更容易。 – BraveNewCurrency