Change pointer to point to stack address instead of heap address - c

In a c program I am trying to change the pointer address i.e. heap address to stack address so that I can reach return address from the stack. I am able to pass the desired address through the input.
The code is using a pointer for memory allocation in heap using malloc.
char* bufferPtr;
bufferPtr= (char*)malloc(strlen(arg2)+4);
In GDB values related to above code are 0x0804000a 0x0804b008
0xbfffcf80: 0x41414141 0x0804000a 0x0804b008 0x4ef9dd66
What these two addresses correspond to because I need to change this pointer to point to some address(say 0xbfffcfd0) on stack. So which of these two values I have to touch.
I tried many possibilities but then I get the following error:
Program received signal SIGSEGV, Segmentation fault.
__strcpy_sse2 () at ../sysdeps/i386/i686/multiarch/strcpy-sse2.S:2211

if you just want to point to stack location, you don't need to allocate memory for it. For example
int myfunction(void)
{
char buf_on_stack[32];
char *ptr_to_buf_on_stack;
ptr_to_buf_on_stack = buf_on_stack;
myotherfunction(buf_on_stack);
}
char *global_ptr;
void myotherfunction(char *buf_on_caller_stack)
{
global_ptr = buf_on_caller_stack;
}
will have both global_ptr and ptr_to_buf_on_stack pointing to a stack allocated variable (buf_on_stack in this example)
Now if you want the caller's address, where that resides on the stack is architecture dependent. But gcc provides for some builtins that allow you to access it in case you're using gcc as the compiler. See here for details: https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html

Memory allocated with malloc() is typically allocated on the heap. There isn't really a way to make a pointer you get from malloc() point to the stack. You could add a sufficiently large offset to reach the stack though.

Related

C Language and Datastructures

I have a doubt in dynamic memory allocation (malloc)
Say
ivar=(int*)malloc(1*sizeof(int));
What the above code will do?
Will it create address for allocations?
Also which is the standard way to get values in malloc? (Say i as loop variable)
scanf("%d",&ivar[i]);
OR
scanf("%d",ivar+i);
int main()
{
int *ivar;
ivar=(int*)malloc(1*sizeof(int));
printf("%u",ivar); // outputs 2510
printf("%u",&ivar);// outputs 65524
} // please explain why it is…
Thanks in advance.
The memory allocated using malloc is created in heap section of RAM.
ivar=(int*)malloc(1*sizeof(int));
The syntax for malloc is
void *malloc(size_t size);
(1*sizeof(int)) gives 4 bytes, so 4 bytes is allocated in Heap.
You cannot directly access memory of heap, so ivar pointer is used to access it.
When you write
printf("%p",ivar); // outputs 2510
printf("%p",&ivar);// outputs 65524
Both of these gives address, first one gives address of the location pointer is pointing at, second one gives address of the pointer
scanf("%d",&ivar[i]);
and
scanf("%d",ivar+i);
both are equal, so you can use either one of them.

Segmentation Fault For Struct When All Values Are Non-Null

char *s = sbrk(some_num);
if (s != (char *)-1) {
some_struct = (SomeStruct *)s;
some_struct->num = 8; //num is an int [*SEG FAULT OCCURS ON THIS LINE*]
}
Debugging using gdb:
p some_struct => (SomeStruct *) 0xef7100
p some_struct->num => 0
From a previous q/a, I understand that seg faults occur when something is NULL, but in this example, some_struct, some_struct->num, and 8 are all non-NULL.
Why does the segmentation fault occur? How can I set some_struct->num to some int value?
The pointer some_struct needs to point to some valid memory. If the function some_function returns the pointer to some local volatile variable that variable will be lost when some_function exits.
To avoid segfault you could declare the local variable in some_function as static, or you could allocate the memory from heap by letting some_function call malloc. If some_function allocates the memory with malloc it will be the responsibility of the caller to make sure that the memory is later freed.
Another way to avoid segfault would be to not return the pointer to a local variable but a global variable. However, most people agree that global variables should be avoided.
It's worthwhile to become familiar with the concept of virtual memory which underlies most of modern OS's today.
Under an OS with virtual memory, every memory address (actually virtual address) is similar to telephone number in that you cannot call someone at every combination of some 10 digits.
You are supopsed to call at only those numbers listed in the telephone book.
Otherwise you'll hear "Sorry, this number is currently out of service".
Likewise, only those virtual addresses listed in the "page table" of each process (always automatically and transparently maintained by OS) are valid for the process to access.
SEGV is OS's way of saying "Sorry, this virtual address is currently out of service."
malloc (and sbrk) can basically ask OS to allocate a memory chunk of the specified size for you and to register its address to the page table.

Trying to use free() to understand how it works

To understand the usage of free in the C programming language I tried running this code on Ubuntu, but on running the EXE file I am receiving a SIGABRT error. Why is the program not exiting normally?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int ret;
int *ptr;
ptr = (int *)malloc(sizeof(int)*10);
free(ptr);
ptr = &ret;
free(ptr);
return 0;
}
Attempting to free a pointer you didn't get from malloc (or one of its friends) causes undefined behaviour. Your second free(ptr) call attempts just that.
From the C spec, §7.22.3.3 The free function, paragraph 2:
The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
While all the the undefined behavior answers are correct, seeing an implementation might be more helpful.
I think a very good reference to this is K&R C malloc. An explanation of how it works is in "The C Programming Langugage", Chapter 8.7.
Remember when looking at code from standard library functions in C that they have an implementation and a specification, where the implementation might have reproducible behavior that is not required by its specification.
Essentially almost all malloc implementations have a free list where they manage free memory regions in a list (or multiple lists). The free list is often handled in a way, that calling free on a memory region multiple times will put this list in an incorrect state.
Also malicious behavior can be invoked when data structures are purposefully crafted. Phrack has a dated article on how to invoke code execution when passing invalid memory to free while corrupting the freelist.
Other malloc implementations might also be worth looking at (this is an incomplete list of allocation libraries).
ptr = &ret;
free(ptr);
is the same as:
free(&ret);
ret resides on the stack, not on the heap. Attempting to free() memory that was not allocated (with malloc(), etc.) on the heap will cause undefined behavior.
The function free() only works for the memory that has been allocated on heap by malloc(). Not for the static allocation, because static allocations are automatically handled. Here is the mistake:
int ret;
ptr = &ret;
free(ptr);
You can't do this because the memory for ret is not allocated on the heap. It's in the stack and only the memory of the heap should be freed.
Your second free(ptr) is causing undefined behavior as you are attempting to free a pointer which you didn't allocate. Also note that static allocations are automatically reclaimed, so you don't require them to free it.
ptr = &ret;
free(ptr);
Here you are trying to free the local storage stack variable's memory. As per rule you should not free it. When the main() exits all local storage memory on stack always get free.
Free only works with Heap allocation memory.
There are three areas where variables may be created in a c or c++ program.
global or static variables are at fixed locations in the executable binary file.
automatic variables outside of static scope are on the stack
malloc'ed or calloc'ed variables are on the heap.
free() is the function that releases previously allocated memory on the heap. A pointer to memory on the heap is returned by malloc or similar functions. The only way to read or write that memory is via the pointer. A pointer is an address, and a pointer* is the content pointed to at that address.
In the example shown, there are two variables, defined in Main, and effectively static, and the returned value from Main, which is on the stack. Using the miniumum int, 16 bits, here's a possible memory map. In this map, the instructions start at 0, the stack starts at some non-zero value, (beginning of stack - bos) and grows by incrementing, and a heap starts at the maximum address (...FFFF, aka -1) and grows by decrememeting:
(Remember, MIN_INT is -32768, MAX_INT is 32767... the spec guarantees only 16 bits, signed)
Each byte has an address which is 'n' bits wide - 16, 32 or 64 bits, typically
-1. (start of heap, for example, 16 bit addr: 0xFFFF, 32 bit addr: 0xFFFFFFFF or 64 bit addr: 0xFFFFFFFFFFFFFFFF)
-2. (1st location down from beginning of heap. 0x...FFFE) ptr[ 9 ], at one time
-3. (2nd location down from beginning of heap. 0x...FFFD)
-4. (3rd location down from beginning of heap. 0x...FFFC) ptr[ 8 ], at one time
[snip]
-17. (16th location down from beginning of heap. 0x...FFEF)
-18. (17th location down from beginning of heap. 0x...FFEE) ptr[ 1 ], at one time
-19. (18th location down from beginning of heap. 0x...FFED)
-20 (19th location down from beginning of heap. 0x...FFEC) ptr[ 0 ], at one time
-21. (top of heap, 10 X 16 bit ints down from beginning of heap. 0x...FFEB), at one time
:
A very large range of address on 32 or 64 bit machines...
:
tos: ( Top of stack 0x...tos )
bos + ( sizeof( int ) - 1) End of int returned from Main()
bos: (beginning of stack: above static data ) Start of int returned from Mail()
togs: (top of global/static) End of "ptr"
: (size of a pointer is width of address bus... whatever it takes)
togs-(n-1): (top of global/static - (sizeof( int* ) - 1)) start of "ptr"
(togs-n) : End of "ret"
(togs-n)-1: start of "ret"
(any global stuff the compiler adds for itself, the debugger, etc.)
(end of program code)
(start of program code)
(top of non-program code)
0 (start of non-program code, 0x...0000 )
At run-time, "ptr" and "ret" are probably both start at '0', since they're fixed, static, values, read out of the file the executable binary comes from.
As the program runs, the value of "ptr" changes, first, to point into the heap, at the malloc'ed array of 10 ints: "0x...FFEC"
The call to free() doesn't change the value of ptr, its still "0x...FFEC"
Free'ing "0x...FFEC" is legit and runs without anything funny.
The assignment "ptr = &ret" sets a new value into "ptr", "(togs-n)-1", the start of "ret".
Free'ing "(togs-n)-1" causes an immediate crash because "free" checks the value of "(togs-n)-1" and it is NOT in the valid range for a heap address.
"ret" remains blank, its never set, but since its global/static, it remains at whatever it was when the linker wrote it to disk.

malloc preventing garbage from being printed?

Program was programmed in C and compiled with GCC.
I was trying to help a friend who was trying to use trying to (shallow) copy a value that was passed into a function. His the value was a struct that held primitives and pointers (no arrays or buffers). Unsure of how malloc works, he used it similar to how the following was done:
void some_function(int rand_params, SOME_STRUCT_TYPEDEF *ptr){
SOME_STRUCT_TYPEDEF *cpy;
cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));// this line makes a difference?!?!?
cpy = ptr;// overwrites cpy anyway, right?
//prints a value in the struct documented to be a char*,
//sorry couldn't find the documentation right now
}
I told him that the malloc shouldn't affect the program, so told him to comment it out. To my surprise, the malloc caused a different output (with some intended strings) from the implementation with the malloc commented out (prints our garbage values). The pointer that's passed into the this function is from some other library function which I don't have documentation for at the moment. The best I can assume it that the pointer was for a value that was actually a buffer (that was on the stack). But I still don't see how the malloc can cause such a difference. Could someone explain how that malloc may cause a difference?
I would say that the evident lack of understanding of pointers is responsible for ptr actually pointing to memory that has not been correctly allocated (if at all), and you are experiencing undefined behaviour. The issue is elsewhere in the program, prior to the call to some_function.
As an aside, the correct way to allocate and copy the data is this:
SOME_STRUCT_TYPEDEF *cpy = malloc(sizeof(SOME_STRUCT_TYPEDEF));
if (cpy) {
*cpy = *ptr;
// Don't forget to clean up later
free(cpy);
}
However, unless the structure is giant, it's a bit silly to do it on the heap when you can do it on the stack like this:
SOME_STRUCT_TYPEDEF cpy = *ptr;
I can't see why there difference in the print.
can you show the print code?
anyway the malloc causes memory leak. you're not supposed to allocate memory for 'cpy' because pointer assignment is not shallow-copy, you simply make 'cpy' point to same memory 'ptr' point by storing the address of the start of that memory in 'cpy' (cpy is mostly a 32/64 bit value that store address, in case of malloc, it will store the address of the memory section you allocated)

Allocated memory address clash

i don't understand how this happen. This is portion of my code..
int isGoal(Node *node, int startNode){
int i;
.
.
}
When i debug this using gdb i found out that 'i' was allocated at the memory address that have been previously allocated.
(gdb)print &node->path->next
$26 = (struct intNode **) 0xffbff2f0
(gdb) print &i
$22 = (int *) 0xffbff2f0
node->path->next has been already defined outside this function. But as u can see they share the same address which at some point make the pointer point to another place when the i counter is changed.
I compiled it using gcc on solaris platform
Any helps would be really appreciated..
The memory for i is taken from the stack, or what in C is sometimes called "automatic storage."
The contents of memory allocated from the stack are no longer valid after the function declaring that storage has returned. For example, your isGoal() function allocates stack storage for the variable i and the storage exists only until the point in time when isGoal() returns.
The reason you see the address of i, &i has already existed during your program is that the stack memory area is continually reused. Prior to what you see in gdb, you have stored the address of a stack variable in node->path->next.
To obtain memory which remains valid after the allocating function has returned, you must use malloc() and free() to obtain what is called "dynamic memory" or, sometimes, memory from the "heap."
Two possibilities:
You have compiled with optimizations and this is confusing gdb (for example i could be optimized away, so that it actually hasn't any address)
node->path doesn't point to correctly allocated memory. For example that pointer could have been set to point to an object on the stack that subsequently went out of scope.

Resources