2014-02-06 48 views

回答

1

不可移植性,沒有。

在很多風格的Windows中,您無法修改正在運行的程序的可執行文件。這通常是非常煩人的,即使在做比您提議的「更理智」的事情時也是如此。

在Linux中,我認爲這樣可以,只需打開argv[0]並修改它即可。當然,如果你的進程從你遷移的路徑上加載了問題找到正確的文件,但應該有一些/sys條目或可能導致你(下)絕對路徑的東西。

+0

'argv [0]'是程序本身嗎?哇!我只認爲這是該計劃的名稱。 – NlightNFotis

+1

@NlightNFotis這是唯一的名字,他意味着要知道打開你需要知道的名字:) – Jite

+0

@NlightNFotis它是程序的名稱。不知道你以爲我的意思。我想象OP在做'open(argv [0],...)'打開包含正在運行的程序進行修改的文件。 – unwind

2

這不可能以可移植的方式完成(每個系統上可執行文件的結構將會有所不同 - ELF與.exe,amb64與ARM),但是您可以將libgcc或libclang之類的東西與您的輸出文件應該允許codegeneration +編譯。

看看clang可執行文件here的代碼,它應該給你一些好的想法。

你可能會做(在僞代碼)什麼:

string myNewCode("#include <stdio.h>\nint main(int argc, char *argv[]){ printf(\"Bus error\\n\");return 1; }"); 
var compiler = new Compiler(); 
var temp_file = new tempFile(); 
compiler->compile(myNewCode, temp_file); 
move_file(temp_file, argv[0]); 

(二次編輯:具有此給予多一點思考,這是完全可能的,並與libclang便攜式)

0

我繼續的試過了。下面的例子在Linux上工作,按您的規格(請注意,這是哈克,非動態代碼!)

#include <stdio.h> 

const char str1[]="Hello world!"; //12 chars + \0 
//  echo -n "Bus error"| wc -c # 9 + \0 -- need to pad by 3 

int main(int argc, char const * const argv[]){ 
    puts(str1); 
    system("sed 's/Hello world!/Bus error\\x0\\x0\\x0/' a.out -i~\n" 
     "rm a.out~\n"); 
    return 0; 
} 

,除非你想要把應用程序下來你不能寫入到地方的文件,但(到嘈雜的碰撞)。使用-i~不會寫入,而是將原始文件移動到a.out~,同時創建名爲a.out的修改副本。 (操作系統繼續讀取同一個文件,而不管名稱是否改變。移除/取消鏈接也是可以的 - Linux程序可以繼續訪問未鏈接的文件,如果它們在解除鏈接之前打開它們(不關閉))。