搜寻【自修改代码】的有趣例子
如果一段程序代码在运行的过程中修改了自己,并且在后续的运行过程中,执行了被修改过的代码段,我们称这种代码为“自修改代码”。关于“自修改代码”,百科上有这样的描述:
目前大多数的编程语言,代码区、内存区和读写区都是分开的,不具有“自修改代码”这种特性。
我想探索的问题是:
如果代码区、内存区、读写区是同一个区域,会发生什么有意思的事情呢?
比如,百科里说这样就可以“制造病毒”了。你们能否找到或写出一段可以【制造病毒】的自修改代码呢?
除了“制造病毒”以外,自修改代码还有哪些有意思的行为呢? 为了寻找有意思的例子,我仿照BF语言,定义了下面这种编程语言:
注:上表的“指针”指的是内存指针。
正常情况下,代码区、输入区、输出区、内存区是分开的:
每执行一个字符,代码区的指针会右移一个字符(跳转除外)。
如果执行到读入指令,那么内存指针所指的字符就会被输入区的指针所指的字符覆盖,然后输入区的指针会右移一个字符;
如果执行到写入指令,那么内存指针所指的字符就会被拷贝到输出区的指针所指的地方,然后输出区的指针会右移一个字符。
我想探究一下,如果代码区、输入区、输出区、内存区是同一个区域,会有什么有意思的事情发生?
如果换成别的语言,会不会有更有意思的事情发生?
比如,能否让ChatGpt解析并枚举式地改进它自己的代码,
如果改进后更强了,就保留这一改进,否则改回去,它是不是就把自己越改越强了呢? 如果换成C语言,我想到了“制造病毒”的一个例子,只需短短地一句“printf(...)”语句就能实现:
由于写指针就在代码指针后面,每次运行一句“printf(...)”语句,下一行“printf(...)”代码就写好了,并且下一步就会执行到它。
这就使得“printf(...)”这段代码不断地自我复制,最终整个内存区(同时也是代码区和读写区)都被“printf(...)”这段病毒代码占满了。
你们还能不能举出别的有趣的例子呢? KeyTo9_Fans 发表于 2022-12-15 09:09
如果换成C语言,我想到了“制造病毒”的一个例子,只需短短地一句“printf(...)”语句就能实现:
不懂 JIT 算不算?
在Linux环境, JIT的流程大概是这样的.
1. 使用 mmap 函数,分配一块内存, 属性为可读可写
2. 调用LLVM 生成一段二进制代码 (或用别的方法生成二进制代码)
3. 复制二进制代码 到mmap分配的内存块
4. 使用mprotect将块的权限从RW更改为RX,使其可执行但不再可写
5. 调用生成的代码
3楼的想法,实现起来是有技术难度的,这篇贴子的作者也在尝试解决这个问题:
https://tieba.baidu.com/p/8235648856
但经过吧友们的讨论,好像仍未实现代码的自修改…… 我搜到一个 :https://stackoverflow.com/questions/7447013/how-to-write-self-modifying-code-in-c 看百度链接里面要求修改代码文件,这个可以比较简单实现,比如Linux下面的方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int x=1;
#define LSIZE 1024
char line;
int main(int argc, char *argv[])
{
char fname;
FILE *f1,*f2;
sprintf(fname,"%s.c",argv);
f1=fopen(fname,"r");
f2=fopen("tmpf","w");
while(fgets(line,LSIZE,f1)){
if(strncmp(line,"int x=",6)==0){
int d=atoi(line+6);
fprintf(f2, "int x=%d;\n",d+1);
}else{
fprintf(f2,"%s",line);
}
}
fclose(f1);
fclose(f2);
sprintf(line, "mv tmpf %s.c; gcc -O3 %s.c -o%s",argv,argv,argv);
system(line);
printf("%d\n",x);
return 0;
}
页:
[1]