Click to See Complete Forum and Search --> : Reading data from a memory location of my choice


ArtVandelay
01-02-2003, 05:39 PM
I was wondering how one would go about
viewing whatever is in a specific memory location.

my first thought was to do this:


static volatile int *ptr = (int *)0x0060;

....

printf("the pointer's value is %d\n", *ptr);


Theoretically, that would print out an int/decimal representation of whatever starts at that memory location, but when I run the program, it runs up until the printf statement, and gives me the error:
Segmentation fault

I'm guessing this is due to some form of protection against writing over memory that shouldn't be written over, but how can I merely READ what is there?

Oh yeah, this printf statement works:

printf("the pointer's address is %p\n", ptr);

but of course all that does is print out the address, which I already know, since I assigned it!

Tiomera
01-02-2003, 05:47 PM
cant you just make a pointer point to the specific memory location and then check what it is pointing at??:D Maybe I am wrong, ehehe

ArtVandelay
01-02-2003, 06:13 PM
>cant you just make a pointer point to the specific
>memory location and then check what it is pointing
>at??


Thats exactly what I'm doing in the code above, but gcc and g++ won't allow it. Actually, thats not true. They allow it, and it compiles,

but the segentation fault occurs at runtime.

Tiomera
01-02-2003, 06:41 PM
I think the adress is a real number right, so it should be float...and what contains can be anything...I have done this in pascal, but I am not good enough in C yet

In pascal, I looked at the format of the adress, and just gave it to a pointer( but I knew it pointed to a integer) than I looked at what the pointer was looking at.

Stuka
01-02-2003, 06:59 PM
The problem here is that you CAN'T, due to the nature of the OS and hardware platform (Linux on an x86, I presume), access arbitrary memory locations. A given process has an address space, all of which is (generally) private to that address. mmap and other functions will allow you to create portions of your process's address space that are accessible by other processes for IPC purposes. However, if you try to access memory outside your address space, you get a segfault, because you have gone outside the segment allotted to your process. That's what's happening here.

bastard23
01-02-2003, 10:17 PM
ArtVandelay,
Stuka is quite right. You are running in a virtual address space, all the addresses are translated into physical address. Even if 0x00000060 was in your programs address space, it might not be the physical memory.

If you really want to, read up on the kernel (some links at <kernel src>/Documentation/kernel-docs.txt, www.tldp.org, www.kernelnewbies.org and your friend google.

Remember that this is filled with archane knowledge and can quickly get you into a lot of trouble (i.e. rebooting your machine, overwriting data, and possibly making it unbootable.) But look into /dev/mem (man 4 kmem) and /proc/kcore. Please read up on what you are trying to do.

Here is a little program to show some pointers and where they are in your program:

#include <stdio.h>
int global_int;
int main(){
int local_int;
printf("Location of main: 0x%x\n",main);
printf("Location of global_int: 0x%x\n",&global_int);
printf("\tValue of global_int: 0x%x\n",global_int);
printf("Location of local_int: 0x%x\n",&local_int);
printf("\tValue of local_int: 0x%x\n",local_int);

}


Have fun,
chris

P.S. What are you trying to do?

ArtVandelay
01-05-2003, 07:49 AM
>P.S. What are you trying to do?


I wanted to be able to view memory that
was being used by other programs (other programs made by me for the time being, so I'd be able to know what the addresses being used are).

0x00000060 was just an example for the post
because I was too lazy to actually type in a typical higher address.

The gyst of what I'm doing is messing around and learning what C can and can't do for me!

Energon
01-05-2003, 08:34 PM
You could always catch the segfault and run through all memory addresses trying for ones that are open to you... probably not worth anything, but you can do it.

bastard23
01-06-2003, 02:49 AM
Stuka,

You can't, by design read another processes memory without working for it. No pointer you create "should" be able to go after another process.

Check out the /proc/<pid> directories. Look at <kernel src>/filesystems/proc.txt for info. Basically you have to parse out the maps file, mmap mem, and then look at the memory.

Look into the ptrace syscall (man 2 ptrace). This is how gdb debugs programs.

GDB is the easiest way for a user to read a programs memory.

Good luck,
chris

Stuka
01-06-2003, 10:41 AM
ummm, ok - but I think I said the same thing....(well, except the stuff about /proc, etc.)

bastard23
01-06-2003, 11:30 AM
Stuka,
Yeah, pretty much. I was just trying to give more slightly appropiate info than my first post. Your post was the most accurate description of what was happening. Sometimes I try to give out too much info.

Energon,
You mean catch SEGSEGV? Sounds like you would generate a lot of signals. I'm just pondering how long that would take :).

ArtVandelay,
None of the info I gave is very newbish. Definately something to look in to after you've wrapped you head around C/UNIX programming. I haven't found any comprehensive sources online for programming Linux/UNIX, so you might consider getting a book. Have fun.

Thanks,
chris

Stuka
01-06-2003, 11:59 AM
Ok, just making sure I wasn't truly lost here. I actually have a book on the x86 processor family, and it goes into great detail about how the hardware protects the various process's memory segments and such - it's REALLY neat stuff if you're in to serious system-level programming.

bwkaz
01-06-2003, 01:56 PM
Originally posted by ArtVandelay
I wanted to be able to view memory that
was being used by other programs (other programs made by me for the time being, so I'd be able to know what the addresses being used are). You can't do that. As was posted, it's not a limitation of C per se, but it's a feature of the way Linux on i386 works. Every program has its own address space from 0x00000000 to 0xBFFFFFFF (0xC0000000 and higher are kernel addresses, and you have not much access to those anyway), and these cannot (unless you set up shared memory or something similar) overlap. The addresses from 0 to 0xBFFFFFFF are all mapped to different physical addresses (different places in RAM).

You can do this kind of thing in DOS and Win 3.1, but that's because those OS'es are braindamaged.

Since you made the other programs, print that info there. Or, gdb or one of its frontends might have something useful for what you're doing.