C# 在C中通过UInt32访问内存#

C# 在C中通过UInt32访问内存#,c#,memory,C#,Memory,是否可以通过特定的UInt32变量访问内存 例如,如果我有一个UInt32变量,它的值是12345678 那么是否有任何方法可以访问内存位置0x12345678?显示了如何执行此操作,请注意,您需要使用选项/unsafe进行编译(您可以在项目设置中找到该选项) 显示了如何执行此操作,请注意,您需要使用选项/safe进行编译(您可以在项目设置中找到该选项) 除了使用指针,您还可以 IntPtr ptr = IntPtr.Zero; // here you need some address you

是否可以通过特定的UInt32变量访问内存

例如,如果我有一个UInt32变量,它的值是12345678

那么是否有任何方法可以访问内存位置0x12345678?

显示了如何执行此操作,请注意,您需要使用选项
/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
;(不
&
)这么做是大错特错的。。。你是肌酐