自修改代码的编程语言?

发布于 2024-09-06 06:42:31 字数 532 浏览 7 评论 0原文

  • 我最近在考虑编写自修改程序,我认为它可能很强大并且有趣。所以我目前正在寻找一种允许轻松修改程序自身代码的语言。
  • 我读到了C#(作为一种解决方法)以及在运行时编译和执行代码的能力,但这太痛苦了。
  • 我也在考虑组装。在那里更改正在运行的代码更容易,但它不是很强大(非常原始)。

您能建议一种支持在运行时修改代码的强大语言或功能吗?

示例

这就是我所说的在运行时修改代码的意思:

  Start:
  a=10,b=20,c=0;
  label1: c=a+b;
  ....
  label1= c=a*b;
  goto label1;

并且可能正在构建指令列表:

  code1.add(c=a+b);
  code1.add(c=c*(c-1));
  code1. execute();
  • I am recently thinking about writing self-modifying programs, I think it may be powerful and fun. So I am currently looking for a language that allows modifying a program's own code easily.
  • I read about C# (as a way around) and the ability to compile and execute code in runtime, but that is too painful.
  • I am also thinking about assembly. It is easier there to change running code but it is not very powerful (very raw).

Can you suggest a powerful language or feature that supports modifying code in runtime?

Example

This is what I mean by modifying code in runtime:

  Start:
  a=10,b=20,c=0;
  label1: c=a+b;
  ....
  label1= c=a*b;
  goto label1;

and may be building a list of instructions:

  code1.add(c=a+b);
  code1.add(c=c*(c-1));
  code1. execute();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

蓝眼泪 2024-09-13 06:42:31

Malbolge 将是一个很好的起点。每条指令都是自我修改的,而且玩起来很有趣(*)。

(*) 免责声明:实际上可能并不有趣。

Malbolge would be a good place to start. Every instruction is self-modifying, and it's a lot of fun(*) to play with.

(*) Disclaimer: May not actually be fun.

打小就很酷 2024-09-13 06:42:31

我强烈推荐 Lisp。 Lisp 数据可以作为代码读取和执行。 Lisp 代码可以作为数据写出。

它被认为是规范的自修改语言之一。

示例列表(数据):

'(+ 1 2 3) 

或者,以代码形式调用数据来

(eval '(+ 1 2 3)) 

运行 + 函数。

您还可以即时编辑列表中的成员。

编辑:

我编写了一个程序来动态生成一个程序并即时评估它,然后向我报告它与基线相比的表现(除以 0 是通常的报告,哈哈)。

I highly recommend Lisp. Lisp data can be read and exec'd as code. Lisp code can be written out as data.

It is considered one of the canonical self-modifiable languages.

Example list(data):

'(+ 1 2 3) 

or, calling the data as code

(eval '(+ 1 2 3)) 

runs the + function.

You can also go in and edit the members of the lists on the fly.

edit:

I wrote a program to dynamically generate a program and evaluate it on the fly, then report to me how it did compared to a baseline(div by 0 was the usual report, ha).

枕梦 2024-09-13 06:42:31

到目前为止,每个答案都是关于反射/运行时编译,但在您提到的评论中,您对实际 感兴趣自修改代码 - 在内存中修改自身的代码。

在 C#、Java 甚至(可移植)C 中都无法做到这一点 - 也就是说,您无法使用这些语言修改加载的内存中二进制文件。

一般来说,执行此操作的唯一方法是使用汇编,并且它高度依赖于处理器。事实上,它也高度依赖于操作系统:为了防范多态病毒,大多数现代操作系统(包括 Windows XP+、Linux 和 BSD)强制W^X< /a>,这意味着您必须经历一些麻烦< /a> 在那些允许的操作系统中编写多态可执行文件。

在某些解释性语言中,程序可以在运行时修改其自己的源代码。 Perl、Python (参见此处 ,但我所知道的每个 Javascript 实现都不允许这样做。

Every answer so far is about reflection/runtime compilation, but in the comments you mentioned you're interested in actual self-modifying code - code that modifies itself in-memory.

There is no way to do this in C#, Java, or even (portably) in C - that is, you cannot modify the loaded in-memory binary using these languages.

In general, the only way to do this is with assembly, and it's highly processor-dependent. In fact, it's highly operating-system dependent as well: to protect against polymorphic viruses, most modern operating systems (including Windows XP+, Linux, and BSD) enforce W^X, meaning you have to go through some trouble to write polymorphic executables in those operating systems, for the ones that allow it at all.

It may be possible in some interpreted languages to have the program modify its own source-code while it's running. Perl, Python (see here), and every implementation of Javascript I know of do not allow this, though.

赠我空喜 2024-09-13 06:42:31

就我个人而言,我觉得很奇怪的是,你发现汇编比 C# 更容易处理。我发现更奇怪的是,您认为汇编没有那么强大:您无法获得比原始机器语言更强大的功能。无论如何,对于每个人来说。

C# 具有出色的反射服务,但如果您对此感到厌恶……如果您真的对 C 或 C++ 很满意,那么您始终可以编写一个程序来编写 C/C++ 并将其发布给编译器。仅当您的解决方案不需要快速的自重写周转时间(大约数十秒或更长)时,这才可行。

Javascript 和 Python 也都支持反射。如果您正在考虑学习一门新的、有趣的、功能强大但技术要求不高的编程语言,我建议您选择 Python。

Personally, I find it quite strange that you find assembly easier to handle than C#. I find it even stranger that you think that assembly isn't as powerful: you can't get any more powerful than raw machine language. Anyway, to each his/her own.

C# has great reflection services, but if you have an aversion to that.. If you're really comfortable with C or C++, you could always write a program that writes C/C++ and issues it to a compiler. This would only be viable if your solution doesn't require a quick self-rewriting turn-around time (on the order of tens of seconds or more).

Javascript and Python both support reflection as well. If you're thinking of learning a new, fun programming language that's powerful but not massively technically demanding, I'd suggest Python.

偏爱你一生 2024-09-13 06:42:31

我可以建议Python,一种很好的非常高级的动态语言,其中包含丰富的内省(例如通过使用compileevalexec 允许某种形式的自修改代码)。基于您的问题的一个非常简单的示例:

def label1(a,b,c):
    c=a+b
    return c

a,b,c=10,20,0    
print label1(a,b,c) # prints 30

newdef= \
"""
def label1(a,b,c):
    c=a*b
    return c
"""
exec(newdef,globals(),globals())

print label1(a,b,c) # prints 200

请注意,在上面的代码示例中, c 仅在函数范围内更改。

May I suggest Python, a nice very high-level dynamic language which has rich introspection included (and by e.g. usage of compile, eval or exec permits a form of self-modifying code). A very simple example based upon your question:

def label1(a,b,c):
    c=a+b
    return c

a,b,c=10,20,0    
print label1(a,b,c) # prints 30

newdef= \
"""
def label1(a,b,c):
    c=a*b
    return c
"""
exec(newdef,globals(),globals())

print label1(a,b,c) # prints 200

Note that in the code sample above c is only altered in the function scope.

歌入人心 2024-09-13 06:42:31

Common Lisp 在设计时就考虑到了这种情况。您还可以尝试 Smalltalk,其中使用反射来修改正在运行的代码并不陌生。

在这两种语言中,您可能会替换整个函数或整个方法,而不是一行代码。 Smalltalk 方法往往比 Lisp 函数更细粒度,因此这可能是一个很好的起点。

Common Lisp was designed with this sort of thing in mind. You could also try Smalltalk, where using reflection to modify running code is not unknown.

In both of these languages you are likely to be replacing an entire function or an entire method, not a single line of code. Smalltalk methods tend to be more fine-grained than Lisp functions, so that may be a good place to begin.

故笙诉离歌 2024-09-13 06:42:31

许多语言允许您在运行时eval代码。

  • Lisp
  • Perl
  • Python
  • PHP
  • Ruby
  • Groovy(通过 GroovyShell)

Many languages allow you to eval code at runtime.

  • Lisp
  • Perl
  • Python
  • PHP
  • Ruby
  • Groovy (via GroovyShell)
双马尾 2024-09-13 06:42:31

在运行时编译和执行代码的高级语言中,它并不是真正的自修改代码,而是动态类加载。使用继承原则,您可以替换类工厂并在运行时更改应用程序行为。

只有在汇编语言中,通过直接写入代码段,您才能真正实现真正的自我修改。但它的实际用途很少。如果您喜欢挑战,请编写一个自加密的病毒,也许是多态病毒。那会很有趣。

In high-level languages where you compile and execute code at run-time, it is not really self-modifying code, but dynamic class loading. Using inheritance principles, you can replace a class Factory and change application behavior at run-time.

Only in assembly language do you really have true self-modification, by writing directly to the code segment. But there is little practical usage for it. If you like a challenge, write a self-encrypting, maybe polymorphic virus. That would be fun.

不交电费瞎发啥光 2024-09-13 06:42:31

我有时(尽管很少)在 Ruby 中进行自修改代码。

有时,您有一种方法,您并不真正知道您正在使用的数据(例如某些惰性缓存)是否已正确初始化。因此,您必须在方法的开头检查数据是否已正确初始化,然后可能对其进行初始化。但你实际上只需要进行一次初始化,但你每次都会检查它。

因此,有时我会编写一个方法来进行初始化,然后将其自身替换为不包含初始化代码的版本。

class Cache
  def [](key)
    @backing_store ||= self.expensive_initialization

    def [](key)
      @backing_store[key]
    end

    @backing_store[key]
  end
end

但老实说,我认为这不值得。事实上,我很尴尬地承认,我从来没有真正进行过基准测试来看看这个条件是否真的有任何区别。 (在具有积极优化配置文件反馈驱动的 JIT 编译器的现代 Ruby 实现上,可能不会。)

请注意,根据您定义“自修改代码”的方式,这可能是也可能不是。你想要的。您正在替换当前正在执行的程序的某些部分,因此...

编辑:现在我想了一下,这种优化没有多大意义。无论如何,昂贵的初始化只执行一次。修改唯一避免的是条件。最好举一个支票本身很昂贵的例子,但我想不出一个例子。

不过,我想到了一个很酷的自修改代码示例:Maxine JVM。 Maxine 是一个完全用 Java 编写的研究 VM(从技术上来说,它实际上不允许被称为“JVM”,因为它的开发人员不运行兼容性测试套件)。现在,有很多自行编写的 JVM,但据我所知,Maxine 是唯一一个可以自行运行的 JVM。这是非常强大的。例如,JIT 编译器可以对自身进行 JIT 编译,以使其适应 JIT 编译的代码类型。

非常类似的事情发生在 Klein VM 中,它是一个用于自编程语言的 VM。

在这两种情况下,虚拟机都可以在运行时优化并重新编译自身。

I sometimes, although very rarely do self-modifying code in Ruby.

Sometimes you have a method where you don't really know whether the data you are using (e.g. some lazy cache) is properly initialized or not. So, you have to check at the beginning of your method whether the data is properly initialized and then maybe initialize it. But you really only have to do that initialization once, but you check for it every single time.

So, sometimes I write a method which does the initialization and then replaces itself with a version that doesn't include the initialization code.

class Cache
  def [](key)
    @backing_store ||= self.expensive_initialization

    def [](key)
      @backing_store[key]
    end

    @backing_store[key]
  end
end

But honestly, I don't think that's worth it. In fact, I'm embarrassed to admit that I have never actually benchmarked to see whether that one conditional actually makes any difference. (On a modern Ruby implementation with an aggressively optimizing profile-feedback-driven JIT compiler probably not.)

Note that, depending on how you define "self-modifying code", this may or may not be what you want. You are replacing some part of the currently executing program, so …

EDIT: Now that I think about it, that optimization doesn't make much sense. The expensive initialization is only executed once anyway. The only thing that modification avoids, is the conditional. It would be better to take an example where the check itself is expensive, but I can't think of one.

However, I thought of a cool example of self-modifying code: the Maxine JVM. Maxine is a Research VM (it's technically not actually allowed to be called a "JVM" because its developers don't run the compatibility testsuites) written completely in Java. Now, there are plenty of JVMs written in itself, but Maxine is the only one I know of that also runs in itself. This is extremely powerful. For example, the JIT compiler can JIT compile itself to adapt it to the type of code that it is JIT compiling.

A very similar thing happens in the Klein VM which is a VM for the Self Programming Language.

In both cases, the VM can optimize and recompile itself at runtime.

朦胧时间 2024-09-13 06:42:31

我编写了 Python 类 Code,它使您能够向对象添加和删除新代码行、打印代码并执行它。类代码显示在最后。

示例:如果 x == 1,代码将其值更改为 x = 2,然后删除带有检查该条件的条件的整个块。

#Initialize Variables
x = 1

#Create Code
code = Code()
code + 'global x, code' #Adds a new Code instance code[0] with this line of code => internally             code.subcode[0]
code + "if x == 1:"     #Adds a new Code instance code[1] with this line of code => internally code.subcode[1]
code[1] + "x = 2"       #Adds a new Code instance 0 under code[1] with this line of code => internally code.subcode[1].subcode[0]
code[1] + "del code[1]" #Adds a new Code instance 0 under code[1] with this line of code => internally code.subcode[1].subcode[1]

创建代码后,您可以打印它:

#Prints
print "Initial Code:"
print code
print "x = " + str(x)

输出:

Initial Code:

global x, code
if x == 1:
    x = 2
    del code[1]

x = 1

通过调用对象执行 cade:code()

print "Code after execution:"
code() #Executes code
print code
print "x = " + str(x)

输出 2:

Code after execution:

global x, code

x = 2

如您所见,代码将变量 x 更改为值 2 并删除了整个 if 块。这可能有助于避免在满足条件后进行检查。在现实生活中,这种情况可以由协程系统处理,但这种自修改代码实验只是为了好玩。

class Code:

    def __init__(self,line = '',indent = -1):

        if indent < -1:
            raise NameError('Invalid {} indent'.format(indent))

        self.strindent = ''
        for i in xrange(indent):
            self.strindent = '    ' + self.strindent

        self.strsubindent = '    ' + self.strindent

        self.line = line
        self.subcode = []
        self.indent = indent


    def __add__(self,other):

        if other.__class__ is str:
            other_code = Code(other,self.indent+1)
            self.subcode.append(other_code)
            return self

        elif other.__class__ is Code:
            self.subcode.append(other)
            return self

    def __sub__(self,other):

        if other.__class__ is str:
            for code in self.subcode:
                if code.line == other:
                    self.subcode.remove(code)
                    return self


        elif other.__class__ is Code:
            self.subcode.remove(other)


    def __repr__(self):
        rep = self.strindent + self.line + '\n'
        for code in self.subcode: rep += code.__repr__()
        return rep

    def __call__(self):
        print 'executing code'
        exec(self.__repr__())
        return self.__repr__()


    def __getitem__(self,key):
        if key.__class__ is str:
                for code in self.subcode:
                    if code.line is key:
                        return code
        elif key.__class__ is int:
            return self.subcode[key]

    def __delitem__(self,key):
        if key.__class__ is str:
            for i in range(len(self.subcode)):
                code = self.subcode[i]
                if code.line is key:
                    del self.subcode[i]
        elif key.__class__ is int:
            del self.subcode[key]

I wrote Python class Code that enables you to add and delete new lines of code to the object, print the code and excecute it. Class Code shown at the end.

Example: if the x == 1, the code changes its value to x = 2 and then deletes the whole block with the conditional that checked for that condition.

#Initialize Variables
x = 1

#Create Code
code = Code()
code + 'global x, code' #Adds a new Code instance code[0] with this line of code => internally             code.subcode[0]
code + "if x == 1:"     #Adds a new Code instance code[1] with this line of code => internally code.subcode[1]
code[1] + "x = 2"       #Adds a new Code instance 0 under code[1] with this line of code => internally code.subcode[1].subcode[0]
code[1] + "del code[1]" #Adds a new Code instance 0 under code[1] with this line of code => internally code.subcode[1].subcode[1]

After the code is created you can print it:

#Prints
print "Initial Code:"
print code
print "x = " + str(x)

Output:

Initial Code:

global x, code
if x == 1:
    x = 2
    del code[1]

x = 1

Execute the cade by calling the object: code()

print "Code after execution:"
code() #Executes code
print code
print "x = " + str(x)

Output 2:

Code after execution:

global x, code

x = 2

As you can see, the code changed the variable x to the value 2 and deleted the whole if block. This might be useful to avoid checking for conditions once they are met. In real-life, this case-scenario could be handled by a coroutine system, but this self modifying code experiment is just for fun.

class Code:

    def __init__(self,line = '',indent = -1):

        if indent < -1:
            raise NameError('Invalid {} indent'.format(indent))

        self.strindent = ''
        for i in xrange(indent):
            self.strindent = '    ' + self.strindent

        self.strsubindent = '    ' + self.strindent

        self.line = line
        self.subcode = []
        self.indent = indent


    def __add__(self,other):

        if other.__class__ is str:
            other_code = Code(other,self.indent+1)
            self.subcode.append(other_code)
            return self

        elif other.__class__ is Code:
            self.subcode.append(other)
            return self

    def __sub__(self,other):

        if other.__class__ is str:
            for code in self.subcode:
                if code.line == other:
                    self.subcode.remove(code)
                    return self


        elif other.__class__ is Code:
            self.subcode.remove(other)


    def __repr__(self):
        rep = self.strindent + self.line + '\n'
        for code in self.subcode: rep += code.__repr__()
        return rep

    def __call__(self):
        print 'executing code'
        exec(self.__repr__())
        return self.__repr__()


    def __getitem__(self,key):
        if key.__class__ is str:
                for code in self.subcode:
                    if code.line is key:
                        return code
        elif key.__class__ is int:
            return self.subcode[key]

    def __delitem__(self,key):
        if key.__class__ is str:
            for i in range(len(self.subcode)):
                code = self.subcode[i]
                if code.line is key:
                    del self.subcode[i]
        elif key.__class__ is int:
            del self.subcode[key]
深府石板幽径 2024-09-13 06:42:31

您可以在 Maple(计算机代数语言)中执行此操作。与上面的许多答案不同,这些答案使用编译语言,只允许您在运行时创建和链接代码,在这里您可以诚实地修改当前正在运行的程序的代码。 (Ruby 和 Lisp,正如其他回答者所指出的,也允许你这样做;可能 Smalltalk 也是如此)。

实际上,在 Maple 中,大多数库函数都是小存根,它们会在第一次调用时从磁盘加载其“真实”自身,然后将自身修改为加载的版本,这在 Maple 中曾经是标准的。由于库加载已经虚拟化,这种情况已不再存在。

正如其他人所指出的:您需要一种具有强大反射和具体化功能的解释语言来实现这一目标。

我为 Maple 代码编写了一个自动规范化器/简化器,我继续在整个库(包括它本身)上运行它;因为我对所有代码都不太小心,所以规范化器确实修改了自己。我还写了一个部分评估器(最近被SCP接受),名为MapleMIX - 在 sourceforge 上可用 - 但无法完全将其应用到自身(这不是设计目标)。

You can do this in Maple (the computer algebra language). Unlike those many answers above which use compiled languages which only allow you to create and link in new code at run-time, here you can honest-to-goodness modify the code of a currently-running program. (Ruby and Lisp, as indicated by other answerers, also allow you to do this; probably Smalltalk too).

Actually, it used to be standard in Maple that most library functions were small stubs which would load their 'real' self from disk on first call, and then self-modify themselves to the loaded version. This is no longer the case as the library loading has been virtualized.

As others have indicated: you need an interpreted language with strong reflection and reification facilities to achieve this.

I have written an automated normalizer/simplifier for Maple code, which I proceeded to run on the whole library (including itself); and because I was not too careful in all of my code, the normalizer did modify itself. I also wrote a Partial Evaluator (recently accepted by SCP) called MapleMIX - available on sourceforge - but could not quite apply it fully to itself (that wasn't the design goal).

悲喜皆因你 2024-09-13 06:42:31

Lua 中,您可以“挂钩”现有代码,这允许您将任意代码附加到函数调用中。它是这样的:

local oldMyFunction = myFunction
myFunction = function(arg)
    if arg.blah then return oldMyFunction(arg) end
    else
        --do whatever
    end
end

您也可以简单地遍历函数,这会给您自我修改代码。

In Lua, you can "hook" existing code, which allows you to attach arbitrary code to function calls. It goes something like this:

local oldMyFunction = myFunction
myFunction = function(arg)
    if arg.blah then return oldMyFunction(arg) end
    else
        --do whatever
    end
end

You can also simply plow over functions, which sort of gives you self modifying code.

何止钟意 2024-09-13 06:42:31

你看过Java吗? Java 6 有一个编译器 API ,因此您可以编写代码并在 Java VM 中编译它。

Have you looked at Java ? Java 6 has a compiler API, so you can write code and compile it within the Java VM.

西瓜 2024-09-13 06:42:31

Dlang 的 LLVM 实现包含 @dynamicCompile 和 @dynamicCompileConst 函数属性,允许您在编译时根据本机主机的指令集进行编译,并在运行时通过重新编译更改编译时常量。

https://forum.dlang.org/thread/[电子邮件受保护]

Dlang's LLVM implementation contains the @dynamicCompile and @dynamicCompileConst function attributes, allowing you to compile according to the native host's the instruction set at compile-time, and change compile-time constants in runtime through recompilation.

https://forum.dlang.org/thread/[email protected]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文