是否有可能在C#中执行x86汇编序列?

继续我的反向工程教育,我经常希望能够复制部分x86汇编代码,并从我select的高级语言中调用它进行testing。

有谁知道从C#方法调用一系列x86指令的方法吗? 我知道这可以使用C ++来完成,但我很好奇,如果它可以在C#中完成?

注意:我不是在说执行MSIL指令。 我正在谈论执行一系列原始x86汇编指令。

为了对抗Brian的说法,重写了来自leppie的回答链接的代码:

using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace DynamicX86 { class Program { const uint PAGE_EXECUTE_READWRITE = 0x40; const uint MEM_COMMIT = 0x1000; [DllImport("kernel32.dll", SetLastError = true)] static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); private delegate int IntReturner(); static void Main(string[] args) { List<byte> bodyBuilder = new List<byte>(); bodyBuilder.Add(0xb8); bodyBuilder.AddRange(BitConverter.GetBytes(42)); bodyBuilder.Add(0xc3); byte[] body = bodyBuilder.ToArray(); IntPtr buf = VirtualAlloc(IntPtr.Zero, (uint)body.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE); Marshal.Copy(body, 0, buf, body.Length); IntReturner ptr = (IntReturner)Marshal.GetDelegateForFunctionPointer(buf, typeof(IntReturner)); Console.WriteLine(ptr()); } } } 

是的, 在这里看到我的详细答案
主要部分是:( 没有任何P / Invoke或外部参考)

 public static unsafe int? InjectAndRunX86ASM(this Func<int> del, byte[] asm) { if (del != null) fixed (byte* ptr = &asm[0]) { FieldInfo _methodPtr = typeof(Delegate).GetField("_methodPtr", BindingFlags.NonPublic | BindingFlags.Instance); FieldInfo _methodPtrAux = typeof(Delegate).GetField("_methodPtrAux", BindingFlags.NonPublic | BindingFlags.Instance); _methodPtr.SetValue(del, ptr); _methodPtrAux.SetValue(del, ptr); return del(); } else return null; } 

其中可以使用如下:

 Func<int> del = () => 0; byte[] asm_bytes = new byte[] { 0xb8, 0x15, 0x03, 0x00, 0x00, 0xbb, 0x42, 0x00, 0x00, 0x00, 0x03, 0xc3 }; // mov eax, 315h // mov ebx, 42h // add eax, ebx // ret int? res = del.InjectAndRunX86ASM(asm_bytes); // should be 789 + 66 = 855 

我相信,你可以添加一个托pipe的C ++项目到你的解决scheme,并使用asm指令公开方法。 您可以从任何.Net项目(而不仅仅是C#)引用该项目,因此您可以从那里调用该方法。

是。

只需在winapi函数上使用P / Invoke。

WriteProcessMemory或find指向你的缓冲区的指针。 启用页面上的执行位(不记得这个function)。

指针上的CreateThread。 WaitForObject(如果你希望它是单线程)。

不,但是你可以用C ++编写程序集,并从C#中调用它。 看到这个例子 。