2009-06-06 28 views
22

继续我的反向工程教育我经常希望能够复制部分x86汇编代码,并从我选择的高级语言中调用它进行测试。是否可以在C#中执行x86汇编序列?

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

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

+1

存在的库可以比手动封送函数指针更容易:[http://www.edgeofnowhere.cc/viewtopic.php?t=429219](http://www.edgeofnowhere.cc/ viewtopic.php?t = 429219)[http://www.edgeofnowhere.cc/viewtopic.php?t=429220](http://www.edgeofnowhere.cc/viewtopic.php?t=429220) – Cthulhon 2009-06-06 20:21:48

回答

42

只是为了对抗Brian的要求,改写代码leppie的答案link

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()); 
     } 
    } 
} 
0

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

-1

不,但您可以用C++编写程序集并从C#调用它。见this example

+4

如果你可以编写一个非托管的C++程序集并从c#中调用它,你能不能从C++程序集中调用程序集? OMG我头痛... – 2009-06-06 06:20:55

+0

嗯,是不是我刚刚说的? – Brian 2009-06-06 13:00:20

0

是的。

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

WriteProcessMemory或找到指向缓冲区的指针。 启用页面上的执行位(不记得这个功能)。

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

2

是的,看到我的详细解答here
的主要部分是:(没有任何的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