5

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

inc  ecx

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

00000035 41 

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

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

4

3 回答 3

14

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

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

于 2013-05-01T12:38:29.710 回答
7
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;
于 2013-05-01T13:30:37.773 回答
1

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

于 2013-05-01T12:36:03.370 回答