4

This is a small program written by me to print the value stored at memory location (0x7fffdf222fec).I am getting error as 4:20: error: invalid type argument of unary ‘*’ (have ‘long int’ printf("\n %p ",*(0x7fffdf222fec));

I am using gcc compiler in ubuntu 16.04.My ram is 4 GB. Cannot i access values at this location using this way?

#include<stdio.h>
void main(){
    printf("\n  %p   ",*(0x7ffeae3b3674));
}

The expected result is the junk value stored at the address

I wrote a program like this and got the address of a as

#include<stdio.h>
void main(){
    int a;
    printf("%p",&a);
}

0x7ffeae3b3674

Then i applied the above address to t he first program.

klutt
  • 25,535
  • 14
  • 43
  • 72
sobha
  • 155
  • 8
  • What value is stored in `0x7fffdf222fec` memory? Based on that you can typecast it to pointer of particular type. – kiran Biradar May 24 '19 at 07:47
  • what makes you think, that literal is a pointer? – ΦXocę 웃 Пepeúpa ツ May 24 '19 at 07:47
  • the value **of what type** stored at memory location? – n. 'pronouns' m. May 24 '19 at 07:51
  • 1
    You can only dereference values that have a pointer type. Either a variable of a pointer type or result of a cast to pointer type. – Gerhardh May 24 '19 at 07:52
  • What makes you think, the address of a would be the same when you run the program again? And even more interesting: What makes you think, there is some memory reserved at that same location if there is no more variable in your function? – Gerhardh May 24 '19 at 07:53
  • On a Linux box, `void main()` is unequivocally wrong. It should be `int main(void)` for preference, or `int main()` if you really insist. – Jonathan Leffler May 24 '19 at 07:54
  • https://www.youtube.com/watch?v=Rxvv9krECNw&t=12m0s – sobha May 24 '19 at 07:54
  • @Gerhardh i watched this video and wrote this program i didnt know that – sobha May 24 '19 at 07:55
  • Edit extra information into the question, please. Also explain what people can expect to see on the other end of your YouTube link. It would also be helpful/sensible if your code and commentary used a consistent address. You have at least two on display: `0x7fffdf222fec` and `0x7ffeae3b3674`. – Jonathan Leffler May 24 '19 at 07:56
  • `int a; void* vp = &a; printf("\n %p ",vp);` would be one way of doing this correctly. – P.W May 24 '19 at 07:57
  • @P.W cant i print the junk value at a specific location – sobha May 24 '19 at 08:00
  • @Jonathan Leffier .Sorry i shall change it to first address – sobha May 24 '19 at 08:01
  • @sobha no, you cannot read the contents of an arbitrary address on a modern memory managed platform. This will either result in a segfault (program crash) or if by chance the address is accessible from your program, you'll get whatever has been stored at that address. – Jabberwocky May 24 '19 at 08:35

3 Answers3

5

Change *(0x7fffdf222fec) to *(int*)0x7fffdf222fec.

0x7fffdf222fec is a constant with type long int. You cannot dereference non-pointer types, so you need to cast it to a pointer first. Which pointer you choose depends on how you want to interpret the data at that address. I chose int* for this example, but you can choose any pointer type except void*.

Note though that chances are that this will segfault. Don't do this unless you're sure that you have access to that location.

To clarify:

Cannot i access values at this location using this way?

Well, it depends on what you mean. It is the right way to read that specific location. The problem is that you might not have access to it.

The access control is in general out of your reach. A segmentation fault is basically the operating systems way of telling you that you did something naughty.

You can read more about segmentation faults here

Gaining access to an arbitrary part of the memory is pretty complex and also heavily system dependent. It's not done in the same way on a Unix machine as it is on a Windows machine.

Also remember that most modern operating systems utilizes virtual memory, so the address you're trying to read is not the physical address. The OS maps a virtual address to a physical address. Read more here

I wrote a program like this and got the address of a as

You're not guaranteed to get the same address each time you run the program. If you have declared a variable, you obviously have access to it. Try to run the program several times. Chances are high that you will get a different address each time.

Unless you have very specific needs, such as coding drivers, kernels or embedded systems, you should never worry about absolute addresses.

klutt
  • 25,535
  • 14
  • 43
  • 72
  • Sorry Broman i tried this #include int main(){ printf("\n %d ",*(int*)(0x7ffeae3b3674)); return 0; } ./a.out but i am getting Segmentation fault (core dumped) – sobha May 24 '19 at 08:34
  • 1
    @sobha read the other answers and comments, especially the last sentence of this answer. – Jabberwocky May 24 '19 at 08:37
2

You cannot have a value without having a type.

Quoting from ISO9899, 6.2.5 Types p1,

The meaning of a value stored in an object or returned by a function is determined by thetypeof the expression used to access it.

You try to dereference the address 0x7ffeae3b3674 but you do not tell it what type has the object from that address.

An object is a region of data storage whose contents contain values, but in order to get a value of an object you need to inform it what type the object has, such that the compiler to know how to decode the information from the given object.

At the given address when you know that there is an integer there, you need to inform it to dereference an object of int type, by first casting the address to pointer to integer, such that the * operator to dereference an integer (and also use %d to inform printf that the passed parameter is an object of type int):

printf("\n  %d   ",*((int*)0x7ffeae3b3674))

Other problem that can appear is that after you get the address from the first program you cannot know if after the second compilation the compiler will allocate the variable a the same address or that the memory segment is still valid. You need to check this using readelf.

alinsoar
  • 13,197
  • 4
  • 45
  • 63
1

I was tempted to search for a duplicate question about reading values from a given address.

This would simply require that you convert that plain address value into a pointer.

Something like that:

int *p = (int *)0x1000000;
printf("value=%d", *p);

But your question is a bit different.

Normally a given address is used to access some hardware registers or similar.

Your code has additional problems.

#include<stdio.h>
void main(){
  printf("\n  %p   ",*(0x7ffeae3b3674));
}

First of all, it must be int main(void) as proper prototype for main.

Second: You do not have a pointer type. While you could solve this with a cast as shown above, you also try to print it as a pointer using %p. But when you dereference a pointer you need the type of value where it points to. Probably an int in your case.

Third: The address you are using is useless. You cannot assume that a certain variable is located at a specific address. Your program can use different addresses each time it is loaded. Also the variable that used to be there in first test, it no longer present in your new test. The compiler will not reserve memory at this location. Whatever is stored there, it does not belong to you! Accessing it is UB.

Gerhardh
  • 7,440
  • 2
  • 11
  • 29
  • thanks Gerhardh for having patience to explain this much.now i think i got it .thank you – sobha May 24 '19 at 08:05
  • @Gerhardth i tried this but i am getting .. ./a.out Segmentation fault (core dumped) – sobha May 24 '19 at 08:11
  • can you please tell me why i am getting this error on trying like this – sobha May 24 '19 at 08:12
  • As I mentioned: The address is not yours and accessing it is undefined behaviour. If you are lucky, UB is resulting in a segfault. – Gerhardh May 24 '19 at 08:25
  • @Gerhardth is there any way i can know which address space is reserved for a particular program – sobha May 24 '19 at 08:28
  • Typically you define variables and take the address of them. Using plain addresses should be avoided. Converting integer values to pointers is implementation defined. – Gerhardh May 24 '19 at 08:35
  • There are mechanisms designed to avoid exactly this. A potential attacker should not know which addresses are used by a program. – Gerhardh May 24 '19 at 08:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/193874/discussion-between-sobha-and-gerhardh). – sobha May 24 '19 at 09:35