I want to use a program to read a variable with a given address in another program using c. Here is my code:
#include<stdio.h>
#include<stdlib.h>
volatile unsigned int *a;
int main(){
scanf("%d",&a);//input the pointer to the variable I want to read
while(1){
printf("%d\n",*a);
system("pause");
}
}
To test this program, I used another program to change the variable. This is the code.
#include<stdio.h>
volatile unsigned int a;
int main(){
printf("%d\n",&a);//output the pointer to the variable
while(1)scanf("%d",&a);
}
I run the second program first and then type the output of the variable into the first program. It's wired that every time I run the second program, I get the same output. And when I run the first program, I get the same value every time, despite I changed the variable in the second program. Why doesn't it work? My computer is 32-bit.
It is operating system specific, and you generally should avoid doing that -even when possible-. Prefer other inter-process communication facilities (e.g. pipes, sockets, message passing)
On most OSes, each process has its own address space in virtual memory, so a process A cannot change any data in process B. BTW, two processes can run simultaneously (on different cores) or quasi-simultaneously (with their tasks scheduled by the kernel), so sharing without care a variable does not make any sense.
Some OSes provide shared memory facilities, but then you should care about synchronization (e.g. with semaphores).
For Linux, read Advanced Linux Programming and shm_overview(7) & sem_overview(7)
Generally, you need to design and adapt both programs to make them communicate. For security reasons you don't want (and your OS kernel forbids) arbitrary processes to be able to glance in other processes' address space.
For example, you don't want your game software to be able to access your banking data in your browser without your consent.
Alternatively, merge the two programs into a single multi-threaded application. You'll be concerned by synchronization and probably would need to use mutexes. Read e.g. some POSIX threads tutorial.
See also MPI. BTW, you might use some database to share the common data (look into PostGreSQL, MongoDB, etc...) or adapt a client-server model
Related
I know that 'volatile' keyword in C is used to tell the compiler to NOT load the variable from RAM memory into a register or into cache and to ALWAYS read the variable from the computer working memory.
However I also read that the use case is when another device is modifying the value at the memory address stored in the variable.
My question is:
Is there any possibility to modify the value of a memory address while a program is running on a Linux or a Windows machine that also has a MMU and uses virtual address space for its programs (like all modern machines)?
Is it possible to change a variable of a program from another program (running in a different process not only a different thread) ?
Is there any possibility to modify the value of a memory address while a program is running on a Linux or a Windows machine that also has a MMU and uses virtual address space for its programs (like all modern machines)?
Yes, of course!
The obvious example is threading: another thread could be updating the memory you're looking at, so you don't want to assume it never changes.
Other examples include:
Shared memory. Processes can agree to share a piece of memory for efficient IPC.
mmap. A program can map a file into memory. When the file changes, the corresponding memory also changes (on Linux, this is the basis of shared memory).
DMA. Other devices, like hard drives, can be asked to write data directly to RAM for efficient transfers.
Is it possible to change a variable of a program from another program (running in a different process not only a different thread) ?
Yes. If the processes agree, you can use shared memory.
If they don't, one can attach itself to another as a debugger and inspect/modify its memory.
There are a couple of questions here, so I'll tackle the first. "...test the use of volatile keyword..."
I suppose you could compile the module without the volatile keyword down to assembler (I believe it is the -S option). The method could be repeated for the same code modified with the volatile keyword, then a diff tool could put a spotlight on the changes. I would suspect the loading of the variable in question with the volatile keyword would always be directly from the location of it.
This could also be verified by looking at the .map listing to know in advance what the actual location of the volatile variable is so you have a basis for comparison.
I've written a program using dynamic memory allocation. I do not use the free function to free the memory, still at the address, the variable's value is present there.
Now I want to reuse this value and I want to see all the variables' values that are present in RAM from another process.
Is it possible?
#include<stdio.h>
#include<stdlib.h>
void main(){
int *fptr;
fptr=(int *)malloc(sizeof(int));
*fptr=4;
printf("%d\t%u",*fptr,fptr);
while(1){
//this is become infinite loop
}
}
and i want to another program to read the value of a because it is still in memory because main function is infinite. how can do this?
This question shows misconceptions on at least two topics.
The first is virtual address spaces and memory protection, as already addressed by RobertL in his answer. On a modern operating system, you just can't access memory belonging to another process (even if you knew the physical address, which you don't because all user space processes work on addresses in their private virtual address space). The result of trying to access something not mapped into your address space will be a segmentation fault. Read more on Wikipedia.
The second is the scope of the C standard. It doesn't know about processes. C is defined in terms of an abstract machine executing your program (and only this program). Scopes and lifetimes of variables are defined and the respective maximum is the global scope and a static storage duration. So yes, your variable will continue to live as long as your program runs, but it's scope will be this program.
When you understand that, you see: even on a platform using a single global address space and no memory protection at all, you could never access the variable of another program in terms of the C standard. You could probably pass a pointer value somehow to your other program and use that, maybe it would work, but it would be undefined behavior.
That's why operating systems provide means for inter process communication like shared memory (which comes close to what you seem to want) and pipes.
When you return from main(), the process frees all acquired resources, so you can't. Have a look on this.
First of all, when you close your process the memory you allocated with it will be freed entirely. You can circumvent this by having 1 process of you write to a file (like a .dat file) and the other read from it. There are other ways, too.
But generally speaking in normal cases, when your process terminates the existing memory will be freed.
If you try accessing memory from another process from within your process, you will most likely get a segmentation fault, as most operating systems protect processes from messing with each other's memory.
It depends on the operating system. Most modern multi-tasking operating systems protect processes from each other. Hardware is setup to disallow processes from seeing other processes memory. On Linux and Unix for example, to communicate between programs in memory you will need to use operating system services for "inter-process" communication, such as shared memory, semaphores, or pipes.
Is it possible to launch two completely independent programs into one scope of memory area?
For example, I have skype.exe and opera.exe and I want to launch them on a way that will allows them to share common memory. Sounds like threading to me.
These are quite some questions at the same time, let me try to dissect:
It is the definition of a process on a modern OS to have its own virtual address space. So running two processes in the same address space can't happen without a modification to the OS to allow exactly that.
Even if such a modification were available, it would be a less than perfect idea: Access to memory shared between threads is governed by synchronisation primitives explicitly built into them. There is no such mechanism to manage memory access between two processes, that have not explicitly been designed so
Sharing memory if so designed between processes does not at all need them to run in the same virtual address space in their totality: Shared memory segments exist in virtually all modern OS to facilitate exactly that. Again, those processes have to be explicitly designed to use this feature.
If they are two independent programs running then you have to ensure that the data is passed in an independent way between them. Let's say the two programs are running, the first program compute some data that the second program needs. The simplest thing to do is print the data from the first program into a file with some status at the end of the file (to indicate that it is safe for the other program to start reading it). From the other program you have a while loop that checks the status of the last line in that file every period of time.
The other option is to use some library like MPI which has protocols for message passing implemented.
I have simple program:
#include <stdio.h>
int a = 5;
int
main(void)
{
while(1)
{
int i;
sleep(1);
printf("%p %i\n", &a, a);
}
return 0;
}
Output (Ubuntu x64):
0x601048 5
0x601048 5
0x601048 5
0x601048 5
I was learning about pointers in C and I already know that you can use memcpy to write data wherever (almost) you want within virtual memory of process. But, is it possible to modify value of int a, placed at 0x601048 address, by using another application(which is of course using its own virtual memory)? How to do this? I'm interested in solutions only for C.
It is not easily possible (to share virtual memory between two different processes on Linux). As a first approximation, code as it if was not possible.
And even if you did share such memory, you'll get into synchronization issues.
You really should read books like Advanced Linux Programming. They have several chapters on that issue (which is complex).
Usually, if you really want to share memory, you won't share some memory on the call stack, but you would "reserve" some memory zone to be later shared.
You could read a lot more about
pthread-s (e.g. read this pthread tutprial)
shared memory segments set up with mmap(2) using MAP_SHARED
low level debugging facilities using ptrace(2) notably PTRACE_PEEKDATA
old SysV shared memory using shmat(2)
Posix shared memory (see shm_overview(7)...) using shm_open(2)
/proc/ file system proc(5) e.g. /proc/$PID/mem ; I strongly suggest to look at file:///proc/self/maps at first in your browser and to read more till you understand what that is showing you. (you could mmap some other's process /proc/$PID/mem ....)
/dev/mem (the physical RAM) see mem(4)
loading a kernel module doing insane tricks.
I strongly advise against playing such dirty memory tricks for a beginner. If you insist, be prepared to break your system and backup it often. Don't play such tricks while a Linux novice.
Often you'll need root privileges. See capabilities(7)
Can I write and run a program that creates an integer, say a and can I write ANOTHER program to modify this integer while both are running?
Yes, but you're going to have to involve some kind of inter-process communication. On most modern operating systems, memory is virtual and raw pointers cannot be directly shared.