8

I have edited 1.c as below.

#include<stdio.h>
int x=100;
int main(void)
{
    printf("%p",&x);
    while(1);
    return 0;
}

Then I opened Command Prompt and run this program and got Output 00402000 while program still running. Now I run 2.c

#include<stdio.h>
int main(void)
{
    int *p=(int *)0x00402000;
    printf("%d",*p);
    return 0;
}

in another instance of command prompt and got output -1, I expect 100 which is in location 00402000. please explain why is this behavior?

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
M Sharath Hegde
  • 485
  • 1
  • 6
  • 20
  • 3
    No modern multitasking operating system will allow you to access memory from other processes. You might want to read about [shared memory](http://en.wikipedia.org/wiki/Shared_memory) though. A reason you can't use another process memory is simply because both processes have their own memory map, and it's all [virtual memory](http://en.wikipedia.org/wiki/Virtual_memory) anyway. If you added a global variable to the second program and printed out its address, it might even be the same address as the first process. – Some programmer dude Aug 20 '13 at 13:10
  • That's not true. Kernel modules have kernel privileges – KrisSodroski Aug 20 '13 at 13:11
  • 1
    @Joachim: tell that to ReadProcessMemory API. Sure it does, how else would you debug? It's just a privileged operation. – Seva Alekseyev Aug 20 '13 at 13:11
  • what happens when am trying to int *p=(int *)0x00402000; – M Sharath Hegde Aug 20 '13 at 13:13
  • 1
    When you assign the pointer in the second process, nothing special happens, it's just assignment. When you try to dereference it in the `printf` call later, then it's undefined behavior since there's probably nothing sensible on that location. It might even crash the program. – Some programmer dude Aug 20 '13 at 13:15
  • @Magn3s1um I wouldn't call a kernel module a normal process. – Some programmer dude Aug 20 '13 at 13:17
  • @JoachimPileborg That should just plain be the answer to the question. I was going to just say 'use shared memory' but you beat me to the punch. – pattivacek Aug 20 '13 at 13:17
  • @MSharathHegde Which operating system are you using? – thejh Aug 20 '13 at 13:18
  • To All, this is NOT a duplicate, see my answer below. – JackCColeman Aug 21 '13 at 05:15

3 Answers3

14

First and foremost, let me say that in modern operating systems, the address values that your program sees (like that 0x00402000) are not physical addresses. They are virtual addresses, they're private to the owning process (i. e. make no sense or mean something else in other processes), and are mapped to physical addresses via a CPU-based mechanism ("the paging unit") that only OS has control over.

If you want to share a variable between different processes, there's a mechanism called shared memory. Read up on it. The relevant APIs are CreateFileMapping with the the first parameter being INVALID_HANDLE_VALUE, MapViewOfFile, OpenFileMapping. There are other ways of interprocess communication, too.

If you want to read process' memory without that process' explicit cooperation, you need to read up on debugging API. This is a much trickier job than using shared memory.

What you've coded, by the way, is a classic undefined behavior.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • so each process in memory will have there own virtual memory map? – M Sharath Hegde Aug 20 '13 at 13:20
  • 1
    @MSharathHegde YES Each time an application is run on an operating system (OS), the OS creates a new process and a new VAS for this process. – Dayal rai Aug 20 '13 at 13:23
  • 1
    @MSharathHegde Yes. At least, the "user" part thereof (on Windows, the "kernel" half of the virtual memory map is shared by all processes) – Medinoc Aug 20 '13 at 13:24
  • 1
    shmem calls on Linux. – Jiminion Aug 20 '13 at 14:34
  • I'm trying to do similar thing (reading the value in memory by address from another process) and i get `Segmentation fault (core dumped)`. When I run it with `sudo` it hangs for a second and it exits the process. – Stoyan Dimov Oct 18 '14 at 10:41
  • @Stoyan: ask a separate question, this one is about Windows. On Linux, both shared memory and debugging API exist, but they're different. – Seva Alekseyev Oct 18 '14 at 13:50
2

To demo the address space concept, modify your second example to:

#include<stdio.h>
int  y = 101;
int main(void)
{
    int *p=(int *)0x00402000;  // hope this works??
    printf("%d",*p);

    printf("%p", p);  // print value of p to ensure correct assignment
    return 0;
}

It probably/might print "101" !! This is because the OS treats each address space the same. So the, global var for an int regardless of its name probably gets allocated to location 0x004002000.

JackCColeman
  • 3,777
  • 1
  • 15
  • 21
1

Appears to be undefined behavior. Since a user's process is only allowed to access memory which has been assigned to it. So as you try to access the memory about the address, your assigning an invalid address, and you are running into undefined behavior.

dhein
  • 6,431
  • 4
  • 42
  • 74