Joe*_*oel 22 c metaprogramming self-modifying
我手上有点太多时间,开始想知道我是否可以写一个自修改程序.为此,我在C中编写了一个"Hello World",然后使用十六进制编辑器在已编译的可执行文件中查找"Hello World"字符串的位置.是否可以修改此程序以打开自身并覆盖"Hello World"字符串?
char* str = "Hello World\n";
int main(int argc, char* argv) {
printf(str);
FILE * file = fopen(argv, "r+");
fseek(file, 0x1000, SEEK_SET);
fputs("Goodbyewrld\n", file);
fclose(file);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,我假设有一些东西阻止它打开自己,因为我可以将它分成两个单独的程序(一个"Hello World"和一些修改它),它工作正常.
编辑:我的理解是,当程序运行时,它被完全加载到ram中.因此,对于所有意图和目的,硬盘驱动器上的可执行文件是一个副本.为什么修改自己会有问题?
有解决方法吗?
谢谢
Gre*_*ill 32
在Windows上,运行程序时,使用Windows中的内存映射文件功能将整个*.exe文件映射到内存中.这意味着文件不一定全部被加载,而是在访问文件的页面时按需加载.
以这种方式映射文件时,另一个应用程序(包括其自身)无法写入同一文件以在其运行时更改它.(另外,在Windows上,运行的可执行文件也不能重命名,但它可以在Linux和其他具有基于inode的文件系统的Unix系统上).
可以更改映射到内存中的位,但是如果执行此操作,则操作系统使用"写时复制"语义来执行此操作,这意味着底层文件不会在磁盘上更改,而是页面的副本( s)在内存中进行修改.在被允许这样做之前,你通常必须在有问题的存储器上摆弄保护位(例如VirtualProtect).
曾经有一段时间,在非常有限的内存环境中使用自修改代码的低级汇编程序常见.但是,没有人这样做了,因为我们不是在相同的受约束环境中运行,而现代处理器有很长的流水线,如果你开始从它们下面改变代码就会非常沮丧.
小智 6
如果您使用的是Windows,则可以执行以下操作:
分步示例:
VirtualProtect()要修改的代码页PAGE_WRITECOPY.VirtualProtect()通过PAGE_EXECUTE保护调用修改后的代码页.FlushInstructionCache().有关更多信息,请参阅如何修改内存中的可执行代码(已存档:2010年8月)