KeyTo9_Fans 发表于 2022-12-14 14:34:51

搜寻【自修改代码】的有趣例子

如果一段程序代码在运行的过程中修改了自己,并且在后续的运行过程中,执行了被修改过的代码段,我们称这种代码为“自修改代码”。

关于“自修改代码”,百科上有这样的描述:



目前大多数的编程语言,代码区、内存区和读写区都是分开的,不具有“自修改代码”这种特性。

我想探索的问题是:

如果代码区、内存区、读写区是同一个区域,会发生什么有意思的事情呢?

比如,百科里说这样就可以“制造病毒”了。你们能否找到或写出一段可以【制造病毒】的自修改代码呢?

除了“制造病毒”以外,自修改代码还有哪些有意思的行为呢?

KeyTo9_Fans 发表于 2022-12-14 15:49:54

为了寻找有意思的例子,我仿照BF语言,定义了下面这种编程语言:



注:上表的“指针”指的是内存指针。

正常情况下,代码区、输入区、输出区、内存区是分开的:



每执行一个字符,代码区的指针会右移一个字符(跳转除外)。

如果执行到读入指令,那么内存指针所指的字符就会被输入区的指针所指的字符覆盖,然后输入区的指针会右移一个字符;

如果执行到写入指令,那么内存指针所指的字符就会被拷贝到输出区的指针所指的地方,然后输出区的指针会右移一个字符。

我想探究一下,如果代码区、输入区、输出区、内存区是同一个区域,会有什么有意思的事情发生?



如果换成别的语言,会不会有更有意思的事情发生?

比如,能否让ChatGpt解析并枚举式地改进它自己的代码,

如果改进后更强了,就保留这一改进,否则改回去,它是不是就把自己越改越强了呢?

KeyTo9_Fans 发表于 2022-12-15 09:09:54

如果换成C语言,我想到了“制造病毒”的一个例子,只需短短地一句“printf(...)”语句就能实现:



由于写指针就在代码指针后面,每次运行一句“printf(...)”语句,下一行“printf(...)”代码就写好了,并且下一步就会执行到它。

这就使得“printf(...)”这段代码不断地自我复制,最终整个内存区(同时也是代码区和读写区)都被“printf(...)”这段病毒代码占满了。

你们还能不能举出别的有趣的例子呢?

liangbch 发表于 2022-12-16 11:28:26

KeyTo9_Fans 发表于 2022-12-15 09:09
如果换成C语言,我想到了“制造病毒”的一个例子,只需短短地一句“printf(...)”语句就能实现:




不懂

liangbch 发表于 2022-12-16 11:37:29

JIT 算不算?

在Linux环境, JIT的流程大概是这样的.
1. 使用 mmap 函数,分配一块内存, 属性为可读可写
2. 调用LLVM 生成一段二进制代码 (或用别的方法生成二进制代码)
3. 复制二进制代码 到mmap分配的内存块
4. 使用mprotect将块的权限从RW更改为RX,使其可执行但不再可写
5. 调用生成的代码

KeyTo9_Fans 发表于 2023-1-31 21:38:38

3楼的想法,实现起来是有技术难度的,这篇贴子的作者也在尝试解决这个问题:

https://tieba.baidu.com/p/8235648856

但经过吧友们的讨论,好像仍未实现代码的自修改……

wayne 发表于 2023-2-1 08:59:05

我搜到一个 :https://stackoverflow.com/questions/7447013/how-to-write-self-modifying-code-in-c

mathe 发表于 2023-2-1 10:56:08

看百度链接里面要求修改代码文件,这个可以比较简单实现,比如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]
查看完整版本: 搜寻【自修改代码】的有趣例子