C# 在C中通过UInt32访问内存#
是否可以通过特定的UInt32变量访问内存 例如,如果我有一个UInt32变量,它的值是12345678 那么是否有任何方法可以访问内存位置0x12345678?显示了如何执行此操作,请注意,您需要使用选项C# 在C中通过UInt32访问内存#,c#,memory,C#,Memory,是否可以通过特定的UInt32变量访问内存 例如,如果我有一个UInt32变量,它的值是12345678 那么是否有任何方法可以访问内存位置0x12345678?显示了如何执行此操作,请注意,您需要使用选项/unsafe进行编译(您可以在项目设置中找到该选项) 显示了如何执行此操作,请注意,您需要使用选项/safe进行编译(您可以在项目设置中找到该选项) 除了使用指针,您还可以 IntPtr ptr = IntPtr.Zero; // here you need some address you
/unsafe
进行编译(您可以在项目设置中找到该选项)
显示了如何执行此操作,请注意,您需要使用选项/safe
进行编译(您可以在项目设置中找到该选项)
除了使用指针,您还可以
IntPtr ptr = IntPtr.Zero; // here you need some address you can read
// For example IntPtr ptr = (IntPtr)0x12345678
// IntPtr is 32 bits or 64 bits depending on how the program is running
byte b = Marshal.ReadByte(ptr); // Or all the other Read* methods.
请注意,Marshal.Read*
/Marshal.Write*
不需要不安全的模式(但可能更慢)(在英语中仍然是不安全的,比如用剪刀跑:-)
显然,您需要一个可以读取的地址(例如通过C互操作调用接收)
请注意,通常您无法读取内存的任何一个地址,并且您使用的ptr
不是指向内存的绝对指针(IntPtr.Zero
不是RAM的内存单元0,因为Windows/任何现代操作系统都会将内存映射到所有进程)
通常,禁止非驱动程序从Windows Server 2003 SP1“原始”访问内存(直接访问未映射到进程的内存):。显然,您仍然可以读取映射到进程的所有内存
通常,不要将指针放入
Int32
/UInt32
。在32位sizeof(Int32)==sizeof(void*)
时,当您转到64位时,这将不再起作用。使用指针类型(int*
,byte*
,…)或IntPtr
/UIntPtr
(保证为指针长度)。如果您需要进行指针计算,但通常不使用.NET 4.0,请使用long
/ulong
(或Int64
/UInt64
,同样)(64位,在32位和64位时都很安全)除了使用指针之外,您可以
IntPtr ptr = IntPtr.Zero; // here you need some address you can read
// For example IntPtr ptr = (IntPtr)0x12345678
// IntPtr is 32 bits or 64 bits depending on how the program is running
byte b = Marshal.ReadByte(ptr); // Or all the other Read* methods.
请注意,Marshal.Read*
/Marshal.Write*
不需要不安全的模式(但可能更慢)(在英语中仍然是不安全的,比如用剪刀跑:-)
显然,您需要一个可以读取的地址(例如通过C互操作调用接收)
请注意,通常您无法读取内存的任何一个地址,并且您使用的ptr
不是指向内存的绝对指针(IntPtr.Zero
不是RAM的内存单元0,因为Windows/任何现代操作系统都会将内存映射到所有进程)
通常,禁止非驱动程序从Windows Server 2003 SP1“原始”访问内存(直接访问未映射到进程的内存):。显然,您仍然可以读取映射到进程的所有内存
通常,不要将指针放入
Int32
/UInt32
。在32位sizeof(Int32)==sizeof(void*)
时,当您转到64位时,这将不再起作用。使用指针类型(int*
,byte*
,…)或IntPtr
/UIntPtr
(保证为指针长度)。如果您需要进行指针数学运算,但通常不使用.NET 4.0,请使用long
/ulong
(或Int64
/UInt64
,同样的事情)(64位,在32位和64位时都非常安全)您可以对指针强制转换数字。例如:
int address = 0x12345678;
unsafe {
byte* ptr = (byte*)address;
Console.WriteLine(*ptr);
}
请注意,您只能访问自己的应用程序的虚拟名称空间,而不能访问实际的物理内存。如果您试图读取为应用程序分配的内存区域之外的内容,则会出现异常。另外,请记住,数据不能保证保存在内存中,垃圾收集器可以随时移动任何对象。您可以将数字转换为指针。例如:
int address = 0x12345678;
unsafe {
byte* ptr = (byte*)address;
Console.WriteLine(*ptr);
}
请注意,您只能访问自己的应用程序的虚拟名称空间,而不能访问实际的物理内存。如果您试图读取为应用程序分配的内存区域之外的内容,则会出现异常。另外,请记住,数据不能保证保存在内存中,垃圾收集器可以随时移动任何对象。不太确定您想要实现什么,但您所说的是
IntPtr
和非托管代码。也就是说,C++和类似语言中的指针不能在64位的Box绝对内存或虚拟地址上工作?如果指向受保护的地址,将出现页面错误;字节值=*ptr代码>在不安全的块中。这就是您想要做的吗?不太确定您想要实现什么,但您谈论的是IntPtr
和非托管代码。也就是说,C++和类似语言中的指针不能在64位的Box绝对内存或虚拟地址上工作?如果指向受保护的地址,将出现页面错误;字节值=*ptr代码>在不安全的块中。这就是你想做的吗?这并不能回答问题。该示例显示如何获取指向变量的指针并访问该变量,而不是如何访问由数字指定的地址。将地址强制转换为所需类型的指针(在本例中,我使用int):var p=(int*)&0x12345678
然后修改:p[0]=0xCAFEBABE代码>我会说它是int*p=(int*)0x12345678
;(否&
)这并不能回答问题。该示例显示如何获取指向变量的指针并访问该变量,而不是如何访问由数字指定的地址。将地址强制转换为所需类型的指针(在本例中,我使用int):var p=(int*)&0x12345678
然后修改:p[0]=0xCAFEBABE代码>我会说它是int*p=(int*)0x12345678
;(不
&
)这么做是大错特错的。。。你是肌酐