2015-09-29 28 views
-1

我已經搜索了相當多的答案,沒有成功。 在調試器中,可以編寫指令然後執行它們。 這需要可執行映像中的特殊權限。 我試圖在沒有調試器的情況下執行此功能。跨平臺自我修改代碼(僅適用於Intel/AMD)

請告訴我一個ASM的「Hello World」程序,它具有自修改代碼 (也許代碼爲大寫在你好的「H」替換了一系列090H的) 和命令需要啓用它的執行。 接下來的2行是用於h-> H替換的機器碼前後。

90 90 90 90 90 90 90 90 90 90 90 ; 11 NOPs 
8a 26 50 00 80 e4 df 88 26 50 00 ; MOV AH,[BX]; AND AH,0DFH; MOV [BX],AH; 

我有完整的能力和自信構建iAPX86機器碼。 我的問題是令人信服的Linux,達爾文/優勝美地,和Windows允許執行。最後,我希望能夠爲我正在編寫的新語言實時構建和修改可執行文件 。 新語言的體系結構在現代實踐中沒有相似之處。

我希望在面對約會時有很多批評, ,但我會盡管繼續我的計劃。

+0

我不相信有一個平臺不可知的方式做到這一點。我可以告訴你如何在32位或64位代碼的Windows上執行此操作,但我相信您也可以在Google上查看這些信息。 - 你在評論中展示的是16位代碼 - 是有意的嗎? –

+0

另外,你說你想消除調試器,但是你的代碼必須在某些東西,某些進程上下文中執行 - 沒有調試器會怎麼樣? –

+1

您必須使用操作系統特定的機制將代碼段標記爲可寫。在Linux和BSD上,你會這樣做的方式是通過[mprotect](http://linux.die.net/man/2/mprotect) –

回答

1

謝謝大家認真對待我的問題。 此代碼有效!事實證明,這比我想象的要簡單得多。沒有特殊的編譯器標誌,或者ELF或者MACHO專門化。 在iAPX86機器代碼中,C3靠近RET,沒有返回值。 我有一些改進,在代碼後面列出, 但這個問題,如問,完全回答我的滿意。

工作代碼

#include <cstdio> 
#include <cstdlib> 
#include <iostream> 
#include <string> 

using namespace std; 

typedef void (*fptr)(); 

int main(int argc, char **argv) { 
    try { 
    fptr p = (fptr)"\xc3"; 
    p(); 
    cout << "Hello world" << endl; 
    } 
    catch (const int  e) { cout << "int  exception: " << e << endl; } 
    catch (const char e) { cout << "char exception: " << e << endl; } 
    catch (const string &e) { cout << "string exception: " << e << endl; } 
    catch (...)    { cout << "default exception"  << endl; } 
    exit(0); 
} 

TODO

  • 安全代碼支架操作碼串。
  • 防止某些操作碼出現在字符串中。
  • 捕獲信號以及例外。
+0

你的問題說「構建和修改可執行文件」。這不完全是你在這裏做的。假設目標OS允許可執行堆棧,您正在有效地創建新代碼(而不是修改可執行文件)。這正是緩衝區溢出漏洞的工作原理。如果你擔心的是字符串將包含嵌入的空字符並分解字符串,我認爲這可以很容易地處理。但是,如果由於某種原因需要將nuls編碼爲其他內容,那麼我建議您查看一些JMP-CALL-POP編碼器/解碼器。 –

+0

謝謝。你很好地掌握了我的意圖,但我沒有充分明確地問我的問題。通過創建一種新的語言,我的目標是構建新的機器碼碎片,這些碎片不可能由我知道的任何編譯器生成,以實現有價值的效率目標。我打算這樣做,試驗做「禁止」並實施與標準實踐不一致的神經模型。我在防病毒工作了10年,所以緩衝區溢出漏洞很熟悉。我想混合編譯代碼的價值,老式的意大利麪代碼和發行版。 P();是我想要的。 – jlettvin

+0

你能解釋一下代碼的功能嗎?我用g ++編譯它,並打印出「Hello world \ n」。字符文字代表什麼? – Joonazan