簡體   English   中英

通過UInt32在C#中訪問內存

[英]Access memory by UInt32 in C#

是否可以通過特定的UInt32變量訪問內存?

例如,如果我有一個UInt32變量,其值為12345678,

那么有什么方法可以訪問內存位置0x12345678?

MSDN顯示了如何執行此操作,請注意,您將需要使用選項/unsafe進行編譯(您可以在項目設置中找到它)

        unsafe 
        {
            // Assign the address of number to a pointer:
            int* p = &number;

            // Commenting the following statement will remove the
            // initialization of number.
            *p = 0xffff;

            // Print the value of *p:
            System.Console.WriteLine("Value at the location pointed to by p: {0:X}", *p);

            // Print the address stored in p:
            System.Console.WriteLine("The address stored in p: {0}", p->ToString());
        }

除了使用指針,您還可以

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開始,非驅動程序禁止“原始”訪問內存(直接訪問未映射到進程的內存): 在Windows 8下讀取物理內存 顯然,您仍然可以讀取映射到您的進程的所有內存。

通常不要將指針放在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);
}

請注意,您只能訪問自己應用程序的虛擬名稱空間,而不能訪問實際的物理內存,並且如果嘗試在為應用程序分配的內存區域之外進行讀取,則會出現異常。 另外,請記住,不能保證數據會保留在內存中,垃圾收集器可以隨時移動任何對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM