C#中VirtualAlloc分配内存后写入字节数组读取异常求助
C#虚拟内存操作:Marshal.Copy写入后读取数据不符问题
在C#中使用VirtualAlloc分配虚拟内存后,通过Marshal.Copy写入字节数组,但从同一地址读取时得到错误数据。原代码如下:
byte[] arr = {1,2,3,4,5,6,7,8,9,10}; Console.WriteLine("arr: "); for (int i = 0; i < arr.Length; i++){ Console.Write("0x{0:X2} , ", arr[i]); } Console.WriteLine(""); UInt32 codeAddr = VirtualAlloc(0, (UInt32)arr.Length, MEM_COMMIT, PAGE_READWRITE); Console.WriteLine("Code Address: 0x{0:X8}",codeAddr); Marshal.Copy(arr, 0, (IntPtr) (codeAddr), arr.Length); Console.WriteLine("arr at 0x{0:X8}: ",codeAddr); byte value=0; for (int i = 0; i < arr.Length; i++){ value = Marshal.ReadByte(codeAddr, i); Console.Write("0x{0:X2} , ", value); } Console.WriteLine("");
运行输出:
C:\Users\thm\Desktop>koko.exe arr: 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , Code Address: 0x00770000 arr at 0x00770000: 0x00 , 0x00 , 0x77 , 0x00 , 0x0A , 0xD5 , 0x0A , 0x00 , 0xB7 , 0x46 ,
问题原因
错误核心在Marshal.ReadByte(codeAddr, i)这一行:
Marshal.ReadByte有两个重载:ReadByte(IntPtr ptr, int offset)(读取指定非托管内存地址的字节)和ReadByte(Object obj, int offset)(读取托管对象内存中指定偏移的字节)。- 你传入的
codeAddr是UInt32类型,会被匹配到ReadByte(Object, int)重载,此时函数会把codeAddr当作一个托管值类型对象,读取的是该对象在托管堆中的内存数据,而非你通过VirtualAlloc分配的虚拟内存地址。
另外,用UInt32存储内存地址在64位系统下存在风险——64位地址长度超出UInt32的范围,会导致地址截断,引发更严重的错误。
修复方案
- 使用
IntPtr类型存储内存地址(IntPtr是专门适配32/64位系统的内存地址存储类型)。 - 调用
Marshal.ReadByte时,确保传入IntPtr类型的地址。
修复后的代码:
byte[] arr = {1,2,3,4,5,6,7,8,9,10}; Console.WriteLine("arr: "); for (int i = 0; i < arr.Length; i++){ Console.Write("0x{0:X2} , ", arr[i]); } Console.WriteLine(""); // 用IntPtr存储内存地址 IntPtr codeAddr = VirtualAlloc(IntPtr.Zero, (UInt32)arr.Length, MEM_COMMIT, PAGE_READWRITE); Console.WriteLine("Code Address: 0x{0:X8}",codeAddr); Marshal.Copy(arr, 0, codeAddr, arr.Length); Console.WriteLine("arr at 0x{0:X8}: ",codeAddr); byte value=0; for (int i = 0; i < arr.Length; i++){ // 传入IntPtr类型的地址 value = Marshal.ReadByte(codeAddr, i); Console.Write("0x{0:X2} , ", value); } Console.WriteLine("");
修复后运行,读取的字节序列会和写入的完全一致。
内容的提问来源于stack exchange,提问作者Amr Alasmer
相关产品推荐
相关产品推荐

