How do I read a value from a given memory address (e.g. 0xfed8213) using the C programming language?
Each process has its own virtual address space, so, address 0x12345678 in one program will not be the same as address 0x12345678 in another.
You can access what is at the address simply by doing:
#include <stdio.h>
int main(int argc, char *argv[]){
char *ptr = (char *)0x12345678; //the addr you wish to access the contents of
printf("%c\n", *ptr); //this will give you the first byte, you can add any more bytes you need to the ptr itself, like so: *(ptr + nbyte).
return 0;
}
You'll likely get a segmentation fault though, unless you really know what you're doing. My guess is that you think this is the way to solve some other problem, whereas this isn't the actual solution. This does answer your question in the OP, though.
Here is Another Virtual Memory learning resource.
Related
The following program results in segmentation fault [I have used gcc as compiler], How to print str in the character pointer and why segmentation fault?
#include <stdio.h>
#define LOW 0x40000000
#define HIGH 0x0
int main()
{
volatile char* str = (char*) (HIGH + LOW);
printf ( "Character Str:%s",str);
}
You are assigning the pointer str to point to an absolute memory address, memory address 0x40000000. The (char*) cast is why your compiler isn't complaining. There is almost certainly nothing useful at that address because you haven't declared anything besides that pointer. Don't use absolute memory addressing unless you're writing an operating system or are coding for a legacy system without virtual memory for each program. Even then it's a bad idea if you don't know what you're doing.
printf is failing because you're telling it look for a valid string starting at the memory pointed to by ptr and print it out to stdout (e.g. your console). In the highly unlikely event that address 0x40000000 is readable by your process at the time of execution and it contains a valid, null-terminated string, it would print something out without the segfault. It would still be gibberish.
Based on the number you chose for HIGH, it looks like you were trying to null-terminate a string. If you wanted to create a string that printf could print you might try something like this:
char str[12] = "Hello World";
printf ( "Character Str:%s",str);
Once that was properly allocated, you could could create a pointer and work with that if you so desired.
char *strptr = str;
printf ( "Character StrPtr:%s",strptr);
I may be way off base on what you were actually trying to do. But what you are doing is not valid, and what you are trying to do is not obvious.
I have to display the content of n bytes starting in a specific memory address, i.e: an output for 25 bytes since 0x00004000 (segment text in virtual space) would be #include <stdio.h> #inclu (25 letters)
My idea was to assign to a char *c the address given, like: *c=address; and then printf("%s",c);. For me, conceptually makes sense and I know that in some cases it would cause a segmentation fault if the address is not valid.
However I have implemented it and it always causes a segmentation fault. I use pmap <pid> to know what areas can be displayed (low areas) of that process. When I say "areas that can be displayed" I mean text areas (code).
So, what I am doing wrong? is stupid the assignment *c=address; ?
char *c = address;
for (int i = 0; i < n; i++) {
putchar(c[i]);
}
Errors in your code
having something like
char *c;
*c = address;
Is invalid, because c is a dangling pointer (you have never initialized it). You want to set the address which c points to to address: c = address
printf("%s",c);
You don't know if c is a proper string, it may contain garbage or may not be n bytes length. That's why I used putchar
*c = address puts the value of address into the memory c currently points to. That is what the * is doing. To change where c points, use c = address.
But still, this sounds like a rather, ahem, suboptimal programming exercise.
After doing lot of research in Google, I found this program:
#include <stdio.h>
int main()
{
int val;
char *a = (char*) 0x1000;
*a = 20;
val = *a;
printf("%d", val);
}
But it is throwing a run time error, at *a = 20.
So how can I write and read a specific memory location?
You are doing it except on your system you cannot write to this memory causing a segmentation fault.
A segmentation fault (often shortened to segfault), bus error or access violation is generally an attempt to access memory that the CPU cannot physically address. It occurs when the hardware notifies an operating system about a memory access violation. The OS kernel then sends a signal to the process which caused the exception. By default, the process receiving the signal dumps core and terminates. The default signal handler can also be overridden to customize how the signal is handled.
If you are interested in knowing more look up MMU on wikipedia.
Here is how to legally request memory from the heap. The malloc() function takes a number of bytes to allocate as a parameter. Please note that every malloc() should be matched by a free() call to that same memory after you are done using it. The free() call should normally be in the same function as where you called malloc().
#include <stdio.h>
int main()
{
int val;
char *a;
a = (char*)malloc(sizeof(char) * 1);
*a = 20;
val = (int)*a;
printf("%d", val);
free(a);
return 0;
}
You can also allocate memory on the stack in a very simple way like so:
#include <stdio.h>
int main()
{
int val;
char *a;
char b;
a = &b;
*a = 20;
val = (int)*a;
printf("%d", val);
return 0;
}
This is throwing a segment violation (SEGFAULT), as it should, as you don't know what is put in that address. Most likely, that is kernel space, and the hosting environment doesn't want you willy-nilly writing to another application's memory. You should only ever write to memory that you KNOW your program has access to, or you will have inexplicable crashes at runtime.
If you are running your code in user space(which you are), then all the addresses you get are virtual addresses and not physical addresses. You cannot just assume and write to any virtual address.
In fact with virtual memory model you cannot just assume any address to be a valid address.It is up to the memory manager to return valid addresses to the compiler implementation which the handles it to your user program and not the other way round.
In order that your program be able to write to an address:
It should be a valid virtual address
It should accessible to the address space of your program
You can't just write at any random address. You can only modify the contents of memory where your program can write.
If you need to modify contents of some variable, thats why pointers are for.
char a = 'x';
char* ptr = &a; // stored at some 0x....
*ptr = 'b'; // you just wrote at 0x....
Issue of permission, the OS will protect memory space from random access.
You didn't specify the exact error, but my guess is you are getting a "segmentation fault" which would clearly indicate a memory access violation.
You can write to a specific memory location.
But only when you have the rights to write to that location.
What you are getting, is the operating system forbidding you to write to 0x1000.
That is the correct way to write data to memory location 0x1000. But in this day and age of virtual memory, you almost never know the actual memory location you want to write to in advance, so this type of thing is never used.
If you can tell us the actual problem you're trying to solve with this, maybe we can help.
You cannot randomly pick a memory location and write to. The memory location must be allocated to you and must be writable.
Generally speaking, you can get the reference/address of a variable with & and write data on it. Or you can use malloc() to ask for space on heap to write data to.
This answer only covers how to write and read data on memory. But I don't cover how to do it in the correct way, so that the program functions normally. Other answer probably covers this better than mine.
First you need to be sure about memory location where you want to write into.
Then, check if you have enough permission to write or not.
I have two programs,
Program A is like this,
int main(int argc, char** argv) {
char* s = "hello";
printf(s);
return (EXIT_SUCCESS);
}
The base address of s is 0x80484e0 "hello", Now I have Program B, as below
int main(int argc, char** argv) {
void* p = (void*)0x80484e0;
char* c = (char*)p;
while(*c)
{
printf("%c",*c);
c++;
}
return (EXIT_SUCCESS);
}
In program B 'p' is pointing to the same base address as 's' in Program B but the contents are not same.
Even though 'p' and 's' are having same base address their contents are not same, is it because they are running as different programs in different address space?
In program B 'p' is pointing to the same base address as 's' in
Program B but the contents are not same.
That's the magic of virtual addresses and separate address spaces. You need to look into "shared memory" for your platform.
Addresses used by a program are virtual. They're not the same as the physical address in RAM. The kernel does some nice (nasty) stuff with the help of the MMU and a page table and hides this from the process.
So for example on a 32b system a process thinks it's the sole user of the memory - it can use addresses from 0 to 0xffffffff - with certain restrictions.
If you happen to be on a POSIX system, you can look into mmap and shm_open.
If you're using pretty much any operating system, there'll be the concept of virtual memory. So a certain memory address in one process is not necessarily the same in the other process. Even if it did map to the same physical address by some sheer chance, then by trying to read it you would, hopefully, get a segmentation fault because you're accessing memory that the process doesn't "own".
I believe that this will never work.
In program A, "hello" is a string that comes with the executable, and loads into memory when you call that program.
I am learning how to use pointers, so i wrote the below program to assign integer values in the interval [1,100] to some random locations in the memory.
When i read those memory locations, printf displays all the values and then gives me a segmentation fault. This seems an odd behavior, because i was hoping to see either all the values OR a seg fault, but not both at the same time.
Can someone please explain why i got to see both?
Thanks. Here is the code
#include <stdio.h>
#include <stdlib.h>
int main()
{
char first = 'f';
char *ptr_first = &first;
int i=1;
for(i=1;i<101;i++)
*(ptr_first+i) = i;
for(i=1;i<101;i++)
printf("%d\n", *(ptr_first+i));
return EXIT_SUCCESS;
}
Not odd at all. You are using your variable first, which is on the stack. What you essentially do is happily overwriting the stack (otherwise known from buffer overflows on the stack) and thus probably destroying any return address and so on.
Since main is called by the libc, the return to libc would cause the crash.
You're accessing memory past beyond that assigned to first. It is just one character, and, through the ptr_first pointer, you're accessing 100 positions past this character to unreserved memory. This may lead to segfaults.
You have to ensure the original variable has enough memory reserved for the pointer accesses. For example:
char first[100];
This will convert first in an array of 100 chars (basically a memory space of 100 bytes that you can access via pointer).
Note also that you're inserting int into the char pointer. This will work, but the value of the int will be truncated. You should be using char as the type of i.
since ptr_first pointer is pointing to a char variable first. Now when you are incrementing ptr_first, so incremented memory address location can be out of process memory address space, thats why kernel is sending segmentation fault to this process.