assigning a value to the address - c

I tried the below program to make the pointer to point to a particular address and to store a value in that address.When i make the pointer to contain the value for the assigned address i'm getting a run time error asking me to close the program.
Is it not possible to assign a value to the address 0x6778.why is it so? In what situations does this needed? Please help me understand.
int *p=(int*)0x6778;
printf("The address is:%x",p);
When tried to do *p=1000 i am getting the error.

There are many reasons why this could give you an error:
The address 0x6778 might not be part of this process's virtual memory -- it might not really "exist". You could read more about virtual memory, but basically addresses don't refer directly to physical bytes -- they have to be translated in a table, and that table might not have an entry for your address.
If it is mapped, it might be on a read-only page
If it's mapped and writable, it might corrupt some other part of your program, causing a segfault soon after.
In general, you probably can't write to an arbitrary address in a user-level application. Of course, if you're running a kernel or embedded system, ignore this answer, as it totally does not apply ;-)

That address is likely not in your process's address space, so your program receives an exception from the operating system when you try to access it. You shouldn't be trying to use specific memory locations to store things... rather, use malloc for dynamic allocation, or put things on the stack.

int *p=(int*)0x6778;
To do this, the address location 0x6778 should be a valid address location in first place.
An Address space gets allocated to every process, Your program runs in an particular process, If an program tries to access an address location beyond its address space then it will crash. Seems that is happening in your case.
Unless, you are sure that an virtual address location is valid for use by your program DO NOT access the address locations explicitly, let the compiler put the types in address space allocated to your process and return it back to you. To do that, the simplest way is to just make use of local variables with automatic storage or use malloc for dynamic allocations.

Related

Address of environment variable changes on program call [duplicate]

int i=10;
printf("Address of i = %u",&i);
Output:
Address if i = 3220204848
Output on re-execution:
Address of i = 3216532594
I get a new address of i each time I execute the program. What does this signify?
It signifies that your program is being loaded a different (virtual) address each time you run it. This is a feature called Address Space Layout Randomization (ASLR) and is a feature of most modern operating systems.
That's how operating systems work. When you declare a variable, you're asking the underlying systems to allocate a memory block (address) to store that data (or a pointer to another block if you're dealing with pointers, but here you've got a primitive, so it's just data being stored). The program doesn't care where the memory is, just that it exists, because it knows how to keep track of whatever it's given.
As the programmer, this really isn't that big of a deal unless you're doing some incredibly low-level work. The hardest part of this to really grasp, for most people, is that when you work with pointers, you can't equate things the same way you can primitives, because pointers consider their values (when using == as an equator) to be their memory addresses.
Disable ASLR using:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
You will always see the same address.
At the time of c program execution another processes are running.While executing a code again you will allocate new address previously allocated address will be allocate for another process.

Access process memory directly

simple question:
Is it possible, and how is it possible, to acess the Virtual Memory of my program directly?
To be specific,
instead of typing
int someValue = 5;
can I do something like this:
VirtualMemory[0x0] = (int)5;
I'm just asking because I want the values to be stored next to each other to get a nice and small memory map.
When I look into assembler basics, the processor stores values directly after each other and I was wondering how to do so in c.
Thanks for all of your replies.
Cheers,
Lucky
Not exactly, because in the source code you don't know which memory address your program is going to be "loaded into". So all memory addresses in the program are encoded in an "offset from the start of program" type manner.
Part of the "process loader"'s responsibility in copying the program into memory is to add the "base offset pointer" to all the other offesets, so all the "names" describing memory addresses refer to actual memory addresses instead of "offsets from the beginning of the program".
That's generally a good thing, as if they were encoded directly, two programs that needed the same set of addresses couldn't be run at the same time without corrupting each other's shared memory. In addition, loading a program into a different starting address would not be possible, as walking outside of the memory of your program (nearly guaranteed if you relocate the program without rewriting the memory address references) is going to raise a segfault in the operating system's memory management monitors.
Also you need a name to start at, and this means that the offsets are bound to the variable names. Generally it is much easier to do fishing around in the heap based off of an alloc'd item than it is to truly find the start of the program loaded in memory (because the C programming language doesn't really capture that address into a in-language variable name, and the layout is somewhat system dependent).

Declare a pointer to an integer at address 0x200 in memory

I have a couple of doubts, I remember some where that it is not possible for me to manually put a variable in a particular location in memory, but then I came across this code
#include<stdio.h>
void main()
{
int *x;
x=0x200;
printf("Number is %lu",x); // Checkpoint1
scanf("%d",x);
printf("%d",*x);
}
Is it that we can not put it in a particular location, or we should not put it in a particular location since we will not know if it's a valid location or not?
Also, in this code, till the first checkopoint, I get output to be 512.
And then after that Seg Fault.
Can someone explain why? Is 0x200 not a valid memory location?
In the general case - the behavior you will get is undefined - everything can happen.
In linux for example, the first 1GB is reserved for kernel, so if you try to access it - you will get a seg fault because you are trying to access a kernel memory in user mode.
No idea how it works in windows.
Reference for linux claim:
Currently the 32 bit x86 architecture is the most popular type of
computer. In this architecture, traditionally the Linux kernel has
split the 4GB of virtual memory address space into 3GB for user
programs and 1GB for the kernel.
Adding to what #amit wrote:
In windows it is the same. In general it is the same for all protected-mode operating systems. Since DOS etc. are no longer around it is the same with all systems except kernel-mode (km-drivers) and embedded systems.
The operating system manages which memory-pages you are allowed to write to and places markers that will make the cpu automatically raise access-violations if some other page is written to.
Up until the "checkpoint", you haven't accessed memory location 0x200, so everything works fine.
There I'd a local variable x in the function main. It is of type "pointer to int". x is assigned the value 0x200, and then that value is printed. But the target of x hasn't been accessed, so up to this point it doesn't matter whether x holds a valid memory address or not.
Then scanf tries to write to the memory address you passed in, which is the 0x200 stored in x. Then you get a seg fault, which is certainly sac possible result of trying to write to an arbitrary memory address.
So what are your doubts? What makes you think that this might work, when you come across this code that clearly doesn't?
Writing to a particular memory address might work under certain conditions, but is extremely unlikely to in general. Under all modern OSes, normal programs do not have control over their memory layout. The OS decides where initial things like the program's code, stack, and globals go. The OS will probably also be using some memory space, and it is not required to tell you what it's using. Instead you ask for memory (either by making variables or by calling memory allocation routines), and you use that.
So writing to particular addresses is very very likely to get either memory that hasn't been allocated, or memory that is being used for some other purpose. Neither of those is good, even if you do manage to hit an address that is actually writable. What if you clobber sundry some piece of data used by one of your program's other variables? Or some other part of your program clobbers the value you just wrote?
You should never be choosing a particular hard-coded memory address, you should be using an address of something you know is a variable, or an address you got from something like malloc.

Is there a way to test for an invalid memory location?

In a language like C, for example, if a routine receives a pointer, is there any system call or other test that can be applied to the pointer to check that it is a valid memory location, other than catching SIGSEGV or equivalent?
No, you can't for sure check whether the address is invalid. Even if you used some operating system function to test if teh address is mapped into the address space you still can't be sure if the address is of some service data that you should not read or modify.
One good example. If your program uses Microsoft RPC to accept calls from another program you have to implement a set of callback functions to server the requests. Those callback functions will be run on separated threads started by RPC. You don't know when those thereads start and what their stack size is, so you can't detect whether a buffer overrun occurs if you write through an address that is meant to be of a stack variable but accidentially is to the stack of another thread.
Well, if you knew where the memory being pointed to was being stored (on the stack, for instance), you could check to see if it's in a certain 'range' that is the approximate address range of the stack. That could also work for something on the heap, if you have an idea of how big your heap "should" be. It's definitely not a fail-safe approach, but I'm unaware of any sure-fire methods for checking the 'validity' of a pointer.
If you mean purely within your own application you can establish a convention that any memory allocated by your code is initialized in a way you can recognize. E.g. in one project I saw they wrote an eyecatcher in the first few bytes. In some products I know they write a unique id at the start and end and each time it's accessed they check the 2 ids still match to show it's not been corrupted. E.g CICS on z/Series does the latter.

Why address of a variable change after each execution in C?

int i=10;
printf("Address of i = %u",&i);
Output:
Address if i = 3220204848
Output on re-execution:
Address of i = 3216532594
I get a new address of i each time I execute the program. What does this signify?
It signifies that your program is being loaded a different (virtual) address each time you run it. This is a feature called Address Space Layout Randomization (ASLR) and is a feature of most modern operating systems.
That's how operating systems work. When you declare a variable, you're asking the underlying systems to allocate a memory block (address) to store that data (or a pointer to another block if you're dealing with pointers, but here you've got a primitive, so it's just data being stored). The program doesn't care where the memory is, just that it exists, because it knows how to keep track of whatever it's given.
As the programmer, this really isn't that big of a deal unless you're doing some incredibly low-level work. The hardest part of this to really grasp, for most people, is that when you work with pointers, you can't equate things the same way you can primitives, because pointers consider their values (when using == as an equator) to be their memory addresses.
Disable ASLR using:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
You will always see the same address.
At the time of c program execution another processes are running.While executing a code again you will allocate new address previously allocated address will be allocate for another process.

Resources