繼續我的反向工程教育我經常希望能夠複製部分x86彙編代碼,並從我選擇的高級語言中調用它進行測試。是否可以在C#中執行x86彙編序列?
有誰知道從C#方法中調用一系列x86指令的方法嗎?我知道這可以使用C++完成,但我很好奇它是否可以在C#中完成?
注意:我不是在說執行MSIL指令。我正在談論執行一系列原始x86彙編指令。
繼續我的反向工程教育我經常希望能夠複製部分x86彙編代碼,並從我選擇的高級語言中調用它進行測試。是否可以在C#中執行x86彙編序列?
有誰知道從C#方法中調用一系列x86指令的方法嗎?我知道這可以使用C++完成,但我很好奇它是否可以在C#中完成?
注意:我不是在說執行MSIL指令。我正在談論執行一系列原始x86彙編指令。
只是爲了對抗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());
}
}
}
我相信,你可以添加一個託管的C++項目到你的解決方案,並公開使用asm指令的方法。您可以從任何.Net項目(而不僅僅是C#)引用該項目,因此您可以從那裏調用該方法。
不,但您可以用C++編寫程序集並從C#調用它。見this example。
如果你可以編寫一個非託管的C++程序集並從c#中調用它,你能不能從C++程序集中調用程序集? OMG我頭痛... – 2009-06-06 06:20:55
嗯,是不是我剛剛說的? – Brian 2009-06-06 13:00:20
是的。
只需在winapi函數上使用P/Invoke。
WriteProcessMemory或找到指向緩衝區的指針。 啓用頁面上的執行位(不記得這個功能)。
指針上的CreateThread。 WaitForObject(如果你想它是單線程)。
是的,看到我的詳細解答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
存在的庫可以比手動封送函數指針更容易:[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