Suppose for an embedded program, the hardware is designed such a way that it performs certain operation if the memory address 0x8729 is filled with 0xff.
Is there a way to access the memory address 0x8729 and write to it?
Try this:
uint8_t * p_memory = (uint8_t *) 0x8729;
const uint8_t value_from_memory = *p_memory;
*p_memory = 0xff; // Writing to memory.
You may not need the cast, but I put it there anyway.
Explanation:
Declare a uint8_t pointer and assign to your memory address.
To write, dereference the pointer and assign your value.
To read, dereference the pointer and assign the value to your variable.
I'd say that without more information about the specific Linux implementation we won't know if this is a problem with a "tiny" Linux implementation that doesn't support memory virtualization for userspace apps or if this is the normal behavior of a "standard" Linux implementation that does virtualize physical memory addresses from userspace.
I am inclined to believe this is userspace a virtualization issue, in which case you could use the techniques mentioned with this posting. It describes how to use devmem to access physical memory from the command line, and how to use the device file handle /dev/mem and memmap from within a C program.
Related
In C/C++, it is not allowed to access data at address 0.
However, the physical memory are numbered from 0. And, in DOS era, the interrupt vector table was located at physical address 0. The first interrupt vector was the handler of the division-by-zero exception.
My question is:
Under what cases is it allowed to access physical address 0?
To access physical address zero, it depends on which platform you are talking.
The language has no idea on the underlying addressing model, it depends on the OS.
On bare metal environment, you have total control on the page table if paging is enabled, or just de-reference zero if paging is not enabled.
On some Unix and Linux variation, you do mmap and perhaps also open /dev/mem to get a non-null pointer with logical address non-zero but physical address zero, it may require some access rights.
I'm not sure on Windows.
PS. Other answers seems make a confusion on language level pointer and physical address.
In C/C++, it is not allowed to access address 0.
Yes you can, as long as there's addressable memory there. On most platforms, there won't be.
Under what cases is it allowed to access physical address 0?
You can access any physical address if it's mapped into virtual memory. If there's anything sensitive there, then the OS probably won't allow that in user code. Within the kernel, it's just a case of setting up the page tables to include that address.
Generally, the address space in virtual memory is managed by the operating system.
A freestanding C (or C++) implementation could certainly allow you to dereference (void*)0 in an implementation specific way. But beware of undefined behavior.
The C and C++ standards are very careful about the NULL pointer (and C++11 added the nullptr keyword for several good reasons).
A C compiler (at least a hosted implementation) is allowed to suppose that after a successful dereference a pointer is not null. Some optimizations in GCC are doing that.
Most hosted C or C++ implementations have a null pointer which is an all-zero-bits word, but that is not required by the standard (however, it is very common; it helps the compiler and the libc).
However, pragmatically, a lot of software is supposing that NULL is represented by all-zero-bits (in theory it is a mistake).
I know no C implementation where NULL is not all-zero-bits, but that is not required. However, coding such a compiler would be a headache.
On some operating systems, an application can change its address space, e.g. with mmap(2) on POSIX or Linux.
If you really wanted, you could access address 0 in C, but you really should never want to do that.
There's no specification in either C or C++ that would allow you to assign a specific physical address to a pointer. So your question about "how one would access address 0" could be translated to "how one would assign 0 address to a pointer" formally has no answer. You simply can't assign a specific address to a pointer in C/C++.
But you can get that effect through integer-to-pointer conversion:-
uintptr_t null_address = 0;
void *ptr = (void *) null_address;
The C Standard does not require that platforms provide access to any particular physical memory location, zero or otherwise. While it would be common on many embedded platforms for (char*)0x1234 to access physical location 0x1234, nothing in the C Standard requires that.
The C Standard also does not require that platforms do anything in particular if an attempt is made to access a null pointer. Consequently, if a compiler writer wanted to treat a null pointer dereference as an access to physical location zero, such behavior would be conforming.
Compilers where an access to address zero would be meaningful and useful will typically interpret a null pointer access as an access to location zero. The only problem would be with platforms where accesses to location zero are useful but compiler writers don't know that. That situation can generally only be handled by checking the compiler's documentation for ways to force the compiler to treat a null pointer like any other address.
Your question is a bit confusing. You ask whether it is possible to "access physical address zero." In a modern paged operating system, applications cannot specify physical addresses at all. Physical addresses can only be accessed through kernel mode.
In virtual memory systems, it became common not to map the first page of virtual memory into the process address space. Thus, accessing virtual address zero would trigger an access violation.
In such systems, it is usually possible for the application to map the first page to the process access space through system services. Even if the page is not there by default, it can be added by the application.
The answer is that it is possible to access physical memory address zero in kernel mode and it is possible to access virtual address zero IF the application maps that page to memory (and the OS allows that).
When you run a program on windows, it is loaded into computer memory organized as:
Data Segment
Stack
Code segment
The data segment may contain data which is read only or has read and write access.
E.g:
char *c = "Hello World";
The string Hello World is said to be stored in read only section of memory. Is it stored in physical memory which is sometimes called RAM or is it stored in ROM which is read only? How can it be written if it is read only?
A PC has only one area of memory that really qualifies as ROM, and that is where the BIOS is stored. All of Windows and the programs loaded in Windows will be in RAM.
The x86 processor memory management is able to mark blocks of memory as read only, but the linker and OS have to work together to enable this. It happens after the program is loaded into memory.
It is stored in RAM. The Operating System, in cooperation with the processor itself, is able to protect regions of memory so that any attempt to write to them from user code causes an exception.
In many embedded systems, they have RAM and some type of Read Only Memory, often times called Flash (it can be programmed multiple times without being removed from the Printed Circuit Board).
Simple embedded applications place the executable and read-only data sections in Flash and execute out of Flash. The read/write variables are placed into RAM. Let us consider this model for your example code fragment:
char * c = "Hello World!";
In the above statement, the variable c lives in RAM because the default setting for variables is read & write access. If you specified that the variable was constant, it would live in ROM {Actually, it would represent a location in ROM.}: enter code here
char * const c = "Hello World!"; // A constant pointer that lives in ROM.
The compiler treats the literal text "Hello World!" a little more complex. The actual text lives in ROM, either in the executable area or in a data area; depends on the translator. Many compilers will allocate memory in RAM and copy the literal into RAM and make the variable c point to the copy in RAM. This is because the literal was not specified as constant.
To avoid the copying of the literal into RAM, declare the variable pointing to constant data:
const char * c = "Hello World"; // A pointer to constant data.
The definition above still allows the pointer to point to different things during execution. If you want to refer to one instance of a text literal throughout the program, declare a constant pointer to constant data:
const * char * const c = "Hello World!"; // A constant pointer to constant data
This technique allows executables to load into RAM (for faster execution) and still access read-only data from ROM (which frees up SRAM for true read/write variables).
On most PCs, everything lives either on Non-volatile memory (hard drive, BIOS, etc) or in RAM. Common method is to load programs from ROM (includes hard drive) and execute in RAM. When loading the executable into RAM, the OS usually loads the Read-Only data into RAM also. The read-only data may be guarded by the OS so an exception is generated when the application writes to this area.
It's stored in RAM.
Char pointers which are initialised with a string, like in your example are readonly.
You can cast a const variable so that you can "write" to it but the behaviour of your program will not be predictable.
Readonly regions of RAM are protected by the Operating system.
This probably varies depending on what kind of system you're on. The answer above would be for your standard PC. Embedded systems might actually write the constant data to some kind of non volatile memory.
If it helps, consider that there's two different ways in which memory can be read-only.
At the hardware level, you're referring to ROM. Once it's written to/created, the physical properties of it don't allow it's value to be changed.
At the software level, the OS (or other level higher than the user's program space) prevents the values stored in RAM from being modified.
When you're talking about read-only memory for program values, you're generally talking about the second type. The values are initialized when the program starts, and then the OS doesn't allow them to be modified.
Note: The above is an extremely simplistic explanation, but it does give the general idea.
It is stored int RAM memory. ]:>
What is serial copy? Is it different from deep-copy and shallow-copy?
According to the wiki entry under Duff's device, it is traditionally implemented as:
do { //count > 0 assumed
*to = *from++; //Note that the 'to' pointer is NOT incremented
} while(--count > 0);
And then it makes a note, saying
Note that to is not incremented because Duff was copying to a single memory-mapped output register.
I didn't really understand this note.
If to pointer is not incremented, then what is the point of the loop? Why then it is implemented as:
*to = from[count-1]; //does it not do the same thing?
I suspect that it has something to do with the definition of serial copy.
How can we allocate memory for to so that the loop would make some difference?
The point of such a copy is that it is not made to normal memory, but to a serial register.
So, each time a write is made to the address of the register (to), the hardware associated with the register will do something like send the bits over a serial link, or push them onto a queue for some other hardware to deal with.
Typically you cannot even read from register addresses like this, so they are very unlike normal memory, and best thought of as an interface to a particular piece of hardware that just happens to be located at a memory address.
http://en.wikipedia.org/wiki/Memory-mapped_I/O#Example
Some platforms have special addresses that when you read from / write to it, the system will perform some I/O. For example, the to could be an address that controls the speaker when written. In that case, the loop would, e.g. be able to play a sound, while the *to = from[count-1]; will not give any useful output.
The to pointer here is "special". On certain hardware you can access IO ports by writing to special memory regions. If you wanted to send a bit pattern over an IO port, where the pattern was already in memory this is the sort of thing you'd do.
Every write to to causes the output from the IO port to be changed typically. This is for iterating over the pattern and writing it to the "special" memory.
How you get access to such "special" memory is very platform and implementation specific. Sometimes it's just a question of always writing to a fixed address - normally some platform header provides a #define or similar then to make that information available to you at compile time. Sometimes there's a system call you need to make that tells you the address a particular device you're interested in is mapped at.
Or are those things are reserved for the operation system and things like that?
Thanks.
While it's unlikely that 0x00000001, etc. will be valid pointers (especially if you use odd numbers on many processors) using a pointer to store an integer value will be highly system dependent.
Are you really that strapped for space?
Edit:
You could make it portable like this:
char *base = malloc(NUM_MAGIC_VALUES);
#define MAGIC_VALUE_1 (base + 0)
#define MAGIC_VALUE_2 (base + 1)
...
Well the OS is going to give each program it's own virtual memory space, so when the application references memory spaces 0x0000001 or 0x0000002, it's actually referencing some other physical memory address. I would take a look at paging and virtual memory. So a program will never have access to memory the operating system is using. However I would stay away from manually assigning a memory address for a pointer rather than using malloc() because those memory addresses might be text or reserved space.
This depends on operating system layout. For User space applications running in general purpose operating systems, these are inaccessible addresses.
This problem is related to a architecture's virtual address space. Have a loot at this http://web.cs.wpi.edu/~cs3013/c07/lectures/Section09.1-Intel.pdf
Of course, you can do this:
int* myPointer1 = 0x000001;
int* myPointer2 = 0x000032;
But do not try to dereference addresses, cause it will end in an Access Violation.
The OS gives you the memory, by the way these addresses are just virtual
the OS hides the details and shows it like a big, continous stripe.
Maybe the 0x000000-0x211501 part is on a webserver and you read/write it through net,
and remaining is on your hard disk. Physical memory is just an illusion from your current viewpoint.
You tagged your question C++. I believe that in C++ the address at 0 is reserved and is normally referred to as NULL. Other than that you cannot assume anything. If you want to ask about a particular implementation on a particular OS then that would be a different question.
It depends on the compiler/platform, but many older compilers actually have something like the string "(null)" at address 0x00000000. This is a debug feature because that string will show up if a NULL pointer is ever used by accident. On newer systems like Windows, a pointer to this area will most likely cause a processor exception.
I can pretty much guarantee that address 1 and 2 will either be in use or will raise a processor exception if they're ever used. You can store any value you like in a pointer. But if you try and dereference a pointer with a random value, you're definitely asking for problems.
How about a nice integer instead?
Although the standard requires that NULL is 0, a pointer that is NULL does not have to consist of all zero bits, although it will do in many implementations. That is also something you have to beware of if you memset a POD struct that contains some pointers, and then rely on the pointers holding "NULL" as their value.
If you want to use the same space as a pointer you could use a union, but I guess what you really want is something that doubles up as a pointer and something else, and you know it is not a pointer to a real address if it contains low-numbered values. (With a union you still need to know which type you have).
I'd be interested to know what the magic other value is really being used for. Is this some lazy-evaluation issue where the pointer gives an indication of how to load the data when it is not yet loaded and a genuine pointer when it is?
Yes, on some platforms address 0x00000001 and 0x00000002 are valid addresses. On other platforms they are not.
In the embedded systems world, the validity depends on what resides at those locations. Some platforms may put interrupt or reset vectors at those addresses. Other embedded platforms may place Position Independent executable code there.
There is no standard specification for the layout of addresses. One cannot assume anything. If you want your code to be portable then forget about accessing specific addresses and leave that to the OS.
Also, the structure of a pointer is platform dependent. So is the conversion of the value in a pointer to a physical address. Some systems may only decode a portion of the pointer, others use the entire pointer value. Some may use indirection (a.k.a. virtual addressing) to access real objects. Still no standardization here either.
I'm trying to make a program that reads the value at a certain address.
I have this:
int _tmain(int argc, _TCHAR* argv[])
{
int *address;
address = (int*)0x00000021;
cout << *address;
return 0;
}
But this gives a read violation error. What am I doing wrong?
Thanks
That reads the value at that address within the process's own space. You'll need to use other methods if you want to read another process's space, or physical memory.
It's open to some question exactly what OlyDbg is showing you. 32-bit (and 64-bit) Windows uses virtual memory, which means the address you use in your program is not the same as the address actually sent over the bus to the memory chips. Instead, Windows (and I should add that other OSes such as Linux, MacOS, *bsd, etc., do roughly the same) sets up some tables that say (in essence) when the program uses an address in this range, use that range of physical addresses.
This mapping is done on a page-by-page basis (where each page is normally 4K bytes, though other sizes are possible). In that table, it can also mark a page as "not present" -- this is what supports paging memory to disk. When you try to read a page that's marked as not present, the CPU generates an exception. The OS then handles that exception by reading the data from the disk into a block of memory, and updating the table to say the data is present at physical address X. Along with not-present, the tables support a few other values, such as read-only, so you can read by not write some addresses.
Windows (again, like the other OSes) sets up the tables for the first part of the address space, but does NOT associate any memory with them. From the viewpoint of a user program, those addresses simply should never be used.
That gets us back to my uncertainty about what OlyDbg is giving you when you ask it to read from address 0x21. That address simply doesn't refer to any real data -- never has and never will.
What others have said is true as well: a debugger will usually use some OS functions (E.g. ReadProcessMemory and WriteProcessMemory, among others under Windows) to get access to things that you can't read or write directly. These will let you read and write memory in another process, which isn't directly accessible by a normal pointer. Neither of those would help in trying to read from address 0x21 though -- that address doesn't refer to any real memory in any process.
You can only use a pointer that points to an actual object.
If you don't have an object at address 0x00000021, this won't work.
If you want to create an object on the free store (the heap), you need to do so using new:
int* address = new int;
*address = 42;
cout << *address;
delete address;
When your program is running on an operating system that provides virtual memory (Windows, *nix, OS X) Not all addresses are backed by memory. CPU's that support virtual memory use something called Page Tables to control which address refer to memory. The size of an individual page is usually 4096 bytes, but that does vary and is likely to be larger in the future.
The API's that you use to query the page tables isn't part of the standard C/C++ runtime, so you will need to use operating system specific functions to know which adresses are OK to read from and which will cause you to fault. On Windows you would use VirtualQuery to find out if a given address can be read, written, executed, or any/none of the above.
You can't just read data from an arbitrary address in memory.