【问题标题】:Can I compile the code on the fly in Delphi and execute it?我可以在 Delphi 中即时编译代码并执行它吗?
【发布时间】:2013-04-25 10:48:21
【问题描述】:

是否可以生成一个字节数组,然后让 Windows 像普通代码一样执行它? 假设我们有一些汇编代码:

inc  ecx

这是程序的一部分。用 Nasm 编译后,我们得到一个 EXE,其中上面的行被转换成这样的:

00000035 41 

是否有可能创建一个字节数组,用上面的字节填充它并执行 - 以便实际发生增量?

我已经制作了超级简单的解释型语言,但由于它是解释型的,所以速度很慢。我不想为它编写一个真正的编译器,但我想让它更快地编译和运行。

【问题讨论】:

    标签: delphi winapi assembly compilation interpreter


    【解决方案1】:

    当然。支持数据执行预防的处理器和操作系统可能会犹豫不决,但这很容易规避。只需调用VirtualProtect 将内存块标记为可执行。最好使用VirtualAlloc 来分配您计划执行的内存。这样,您就有了专门用于可执行代码的一整页内存。如果您调用VirtualProtect 以使您分配给GetMem 的一些任意内存可执行,它实际上会以这种方式标记整个页面,因此您可能会不小心将某些数据 标记为可执行。如果该数据被泄露,它可能会被执行。这正是 DEP 旨在保护的内容,因此最好将数据和可执行代码保存在单独的受保护区域中。

    请记住,将文本代码转换为机器代码的任务是编译,因此如果您不想编写真正的编译器,您可能根本不想生成机器代码。

    【讨论】:

    • 谢谢。它是“编译”,但没有所有的 EXE 头文件、外部库的链接等。所以应该更容易。
    • 您仍然需要重新定位(修复)它。除非您不使用任何数据(或通过在启动时传入寄存器的指针间接寻址)并且仅在分支或 PIC 附近。
    【解决方案2】:
    const
       size = 32768;
    type
       TFuncInt = function(param: Integer): Integer; // EAX -> EAX
       TByteArray = array[0..size-1] of Byte;
       PByteArray = ^TByteArray;
    var
       arr: PByteArray;
       func_param: Integer;
       func_result: Integer;
    begin
       arr := VirtualAlloc(nil, size, $3000, $40);
       if arr <> nil then begin
         arr[0] := $40;  // inc EAX
         arr[1] := $C3;  // ret
         func_param := 77;
         func_result := TFuncInt(arr)(func_param);  // 78
         VirtualFree(arr, 0, $8000);
      end;
    end;
    

    【讨论】:

    • @RobKennedy - 您的代码版本无法编译。 Page_Execute_ReadWrite 在 Delphi7 中没有定义。您应该手动定义它。或者使用数值代替。
    • 那么定义它。我不在乎您的开发环境有多过时;不要使用裸数字。对于阅读代码的人来说,它们毫无意义。
    【解决方案3】:

    我认为具有数据执行保护 (DEP) 的现代处理器将不允许这样做。 请注意,有几个可用的 Pascal 脚本库可用于此类目的。

    【讨论】:

    • 我知道它们就像 RemObjects Pascal 脚本一样。但我不想用 Pascal 语言编写,我需要一些非常简单的东西。
    • DEP 不会阻止执行通过 VirtualAlloc() 或 VirtualProtect() 显式标记为执行的内存中的指令。有一些框架,如 VCL 和 ATL,动态分配可执行内存卡盘以用作回调 thunk,而 DEP 可以很好地解决这个问题。
    • 也有表达式求值器可以。但它们通常模仿堆栈机器,因此如果代码是 PIC,则只需要一个加载堆栈指针的寄存器
    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 2021-04-22
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 2012-01-28
    相关资源
    最近更新 更多