Reputation: 361
It it possible to access memory through a specific UInt32 variable?
For example, if I had an UInt32 variable, and its value is 12345678,
then is there any method to access the memory location 0x12345678?
Upvotes: 1
Views: 1418
Reputation: 700372
You can cast a number to a pointer. Example:
int address = 0x12345678;
unsafe {
byte* ptr = (byte*)address;
Console.WriteLine(*ptr);
}
Note that you can only access the virtual namespace of your own application, not the actual physical memory, and you get an exception if you try to read outside the memory area allocated for your application. Also, remember that data is not guaranteed to stay put in memory, the garbage collector can move any object at any time.
Upvotes: 1
Reputation: 111870
Other than using pointers, you can
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.
Note that Marshal.Read*
/Marshal.Write*
don't require unsafe mode (but are probably slower) (and are still unsafe in the english meaning of the word, like running with scissors :-) )
Clearly you need an address you can read (for example received by a C interop call)
Note that in general you can't read any one address of the memory, and that the ptr
you are using isn't an absolute pointer to the memory (IntPtr.Zero
isn't the memory cell 0 of your RAM, because Windows/any modern OS maps the memory to all the processes)
In general from Windows Server 2003 SP1 "raw" access to memory (direct access to memory not mapped to your process) is forbidden to non-drivers: Read physical memory under Windows 8 . Clearly you can still read all the memory that is mapped to your process.
As a rule don't put pointers in Int32
/UInt32
. While at 32 bits sizeof(Int32) == sizeof(void*)
, when you go to 64 bits this doesn't work anymore. Use the pointer types (int*
, byte*
, ...) or IntPtr
/UIntPtr
(that are guaranteed to be of the length of a pointer). If you need to do pointer math and you aren't using .NET 4.0 in general use the long
/ulong
(or Int64
/UInt64
, same thing) (that are 64 bits, so safe both at 32 and 64 bits)
Upvotes: 2
Reputation: 3048
The MSDN shows how to do this, note that you will need to compile with the option /unsafe
(you find it in the project settings)
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());
}
Upvotes: 3