views:

185

answers:

6

There is probably a really simple answer to this but I just can't see it.

#include <stdio.h>

int main(void) {
int x = 0;
printf("\n%d\n%d\n",x,&x);
}

Okay, so the printf gives 0 (x) and 2293752 (&x). I am trying to figure out a way to look at any address (&) and see what is already stored there. This is just for experimentation. Any help?

+2  A: 

That would be pointer dereferencing, which is the * operator. However, you have no way of telling what the type of the stored data is for a random address.

#include <stdio.h>

int main(void) {
int x = 0;
printf("\n%d\n%d\n%d\n",x,&x,*(&x));
}

/* resulting output will be 0, some memory address, and 0 again */
Amber
Not what I meant. If 2293752 is the address of x, then I want to check what is at the address of 0000000..99999999.
akway
Amber
You could find that GCC aborts the program at runtime. It's very strict in these cases, so you better use the proper `%p` and cast to `void*` first.
Johannes Schaub - litb
Agreed - random fooling around with memory usually isn't very productive, regardless.
Amber
again assumption memory is an int.
groundhog
A: 

Assuming that you want to look at "raw" data and that you know an address inside the address space of your process, you would do this:

long x=<address>
printf("%x", *(int *)x);
Wilson
Could you explain this part: *(int *)x
akway
-1: integers and pointers really are different types in C: AFAIK there's no guarantee that `long` can hold an address, and I think it's much more explicit to use a pointer, anyway.
Bastien Léonard
Bastien: touché. Indeed that piece of code is very much hardware-dependent. There isn't really a portable (and safe/secure) way to do what the original poster wants.akway: *(int *)x casts the variable x to be seen as a pointer to an integer, and then retrieves the (integer) value stored at the location pointed to by that pointer. It effectively treats the value of x as a memory address pointing to an integer and reads that integer. It will fail (in an environment-dependent way) if that address is outside the address space of the process.
Wilson
+4  A: 
void* memAddr = (void*)0xAABBCCDD; //put your memory address here
printf("int value at memory address %p is %i", memAddr, *((int*)memAddr));

You'll probably find that examining arbitrary memory addresses will just cause a crash.

Tom Dalling
Tested it, and yeah, it just crashes. I didn't *really* need to know what was anywhere, I was just curious.
akway
You are making an assumption that memAddr contains an int, which is 4 bytes. You should at least use unsigned ints, since you are equally likely to make it appear negative. A char converted to some readable format such has hex is more reasonable.
groundhog
The address can contain anything and be cast to anything. For example: You are making an assumption that memAddr contains an unsigned char, which is one byte. You should at least use signed chars, since it may actually be a negative number. An int converted to some readable format such as decimal is more reasonable.
Tom Dalling
+1  A: 

If you want to explore memory, I would recommend using a low-level debugger such as OllyDbg.

Bastien Léonard
+2  A: 

There are many problems with attempting to do this, first and foremost that as mentioned by Wilson you really won't have any idea what is stored there.

Wilson is slightly off, though, you really should cast it to a char instead of an int, as with an int you will see 4 bytes not a single byte as you would with a char.

Additionally, unless you can read 8bit ASCII characters and map them to something meaningful in your head, you would probably want to convert it to some other form such as base2, base8, or base16.

You can do this in several ways - probably the best way to do this is with bitwise operators and binary shift operators, looking up into a dispatch table to map it into viewable ASCII.

However, you still won't know what it stored there, you will just be able to see some encoded form of the raw binary data. The reason is that C is typed only with regard to the variable pointing to that memory address. A naked view into that memory will just give you binary and no ability to look up what variables that memory is bound to or what type those variables are.

A second problem is that you need to be careful to only look into portions of the memory you have access to. Unless you are careful with how you access it, code segments of memory can't be looked into. You will be lucky if you poke around to avoid a segmentation fault.

Probably the most effective way, though, to look into memory of a process is to dump its segment to disk. In UNIX this is done through a core dump. You can then load it against a debugger and poke around to your hearts content, and even be able to map it to correct types with enough knowledge of the stack. You can also use a binary editor to examine it in an untyped way - often strings are recognizable.

Good luck!

groundhog
A: 

to see an address you can use %p

printf("%p",&x);

I recommend you start reading about pointers, a pointer is a variable that store a memory address

int x=10;
int *p; //this is a pointer to int
p=&x; //now p has the memory location of x
printf("%d\n",*p); //this will print 10
hiena