I want to simulate a downward growing call stack in C and push the following onto the stack:
This is test code I wrote, where I only tried to push the strings, word align and then push the addresses to the strings I that were just pushed:
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
int main(){
/*Initialize stack */
size_t stack_size = (size_t) pow(2,10);
uint8_t *esp; /*Use byte-addressable stack pointer */
esp = (uint8_t *) malloc(stack_size);
esp += stack_size - 1; /*Set esp to top of allocated memory,
since stack grows downwards */
/* Parse the string into its tokens */
char s[] = "/bin/ls -l foo bar";
char *tokens[4];
char *token = strtok(s, " ");
int num_tokens = 0;
while (token != NULL)
{
tokens[num_tokens++] = token;
token = strtok(NULL, " ");
}
size_t esp_iter = 0; /*number of bytes pushed,
needed for word alignment */
char *stack_pointers[num_tokens]; /* Array to store addresses of
strings that were pushed */
/* Push the char arrays on the stack */
for (int j = 0; j < num_tokens; j++)
{
esp_iter += strlen(tokens[j]) + 1; /* +1 because of ‘\0’, which is
included in strncpy */
/* Address to store next string into */
char *next_pointer = (char *) ((uint8_t *) ( esp - esp_iter));
/* Store address in stack to which token j was pushed */
stack_pointers[j] = strncpy(next_pointer, tokens[j],
strlen(tokens[num_tokens]) + 1);
}
/* word aligning */
size_t pad = 4 - esp_iter % 4;
for (int j = 0; j < (int) pad; j++)
{
esp_iter += 1;
}
/* Push pointers to previously pushed strings */
for (int j = 0; j < num_tokens; j++)
{
esp_iter -= sizeof(char *);
/* Address on stack to store address of previously
pushed token to */
char *stack_pointer = (char *) (esp - esp_iter);
stack_pointer = (char *) stack_pointers[j];
}
return 0;
}
I want to address the stack on byte-level, so I use (uint8_t *) for the stack pointer. Then I should be able to use the length of the string + 1 (for the '\0', which is included in strncpy) in the call to strncpy. But the strncpy yields a segmentation fault and I don't understand why. I malloced memory from 0x7fc4c5001000 to 0x7fc4c50013ff. Esp is set to 0x7fc4c50013ff, then I want to e.g push "bar" on the stack, so I decrement to the stack pointer (stack grows toward lower memory addresses) by 4 and call strncpy with destination address 0x7fc4c50013fb, which should be enough space to push those 4 characters. Why do I get a segfault here?