【发布时间】:2014-08-26 02:44:23
【问题描述】:
我有一个byte[],其中包含表示汇编中方法的字节。例如一个简单的mov eax,1 - retn 函数:
var method = new byte[] { 0xB8,0x01,0x00,0x00,0x00,0xC3 };
是否可以在运行时创建一个我可以在 C# 中使用字节数组调用的方法来创建它?
【问题讨论】:
-
您可以 pInvoke VirtualAlloc 分配一个指向您的字节数组的指针,然后使用 Marshal.Copy 将它从 VirtualAlloc 复制到分配内存。然后使用 Marshal.GetDelegateForFunctionPointer 获取 asm 代码的委托。然后您可以调用委托。 stackoverflow.com/questions/959087/…
-
您不需要将 ASM 转换为 IL。 .Net 是一种托管语言,但一旦它是一个正在运行的进程,它与本机进程之间的唯一区别就是它加载了 .net 框架。 .Net JIT 在运行时将 IL 编译为 X86,一旦完成,所有 x86 都在处理器上运行,而不是作为 IL 运行。这意味着在运行时,您可以在一个字节数组中运行一个委托到 asm 就好了。实际上,您可以将 .Net 框架注入本机进程,然后使用 .Net C++ CLR 标头将 .Net dll 加载到其中。
-
@Ryios,通过使用 Marshal.GetDelegateForFunctionPointer?
-
我贴的链接有一个例子,stackoverflow.com/questions/959087/…
-
虽然有一些问题。如果您的 asm 接受参数,您将不得不使用不同的委托签名,直到找到一个映射正确且有效的签名。在极少数情况下,这可能是不可能的,您需要调整您的 asm 才能玩得更好。例如。如果你的 asm 返回一个 ascii 字符串,你需要使用一个字节数组作为返回值。如果您的方法采用 8 字节整数,则使用 ulong 作为参数,等等。如果它返回一个结构,您需要在 c# 中编写该结构并使用 LayoutKind 和 Pack 属性来使其大小匹配。