So in our university assignment we were asked to change the output of two sequential printf("%s", s1); printf("%s", s2);
functions without touching the variables. The intent was for us to use the theoretical knowledge of the memory layout of the process on Linux based systems.
The expected output is for the first printf
call to output both s1 and s2 split by space(s), and for the output of the second to remain as intended by the original application. The values and sizes of s1
, and s2
are known.
My initial idea was to malloc(0)
and subtract the offset equal to the length of the string (+1 for the chunk size value) , and then cast that as a char *
. Since the 2 string values are very small (definitely less than 4KiB, which is the page size) I was hoping that there'd be just one region allocated for heap, and hence it is linear.
But from what it seems I get values of zero, which means I'm looking through an un-initialized memory, or something different then the strings I hoped to locate.
Below is the code in question:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void heap_attack() {
// alternatively it can have signature of
// void heap_attack(void * v);
// but the task is assumed to be solvable with the original signature
}
int main(int argc, char const *argv[])
{
char * s1 = malloc(9);
char * s2 = malloc(9);
if (s1 == NULL || s2 == NULL) return EXIT_FAILURE;
strcpy(s1, "s0000000");
strcpy(s2, "s1111111");
heap_attack();
printf("student 1: %s\n", s1);
printf("student 2: %s\n", s2);
free(s1);
free(s2);
return 0;
}
My implementation of the heap_attack
begins as follows:
void heap_attack() {
char * heap_end = malloc(0) - 1; // 1 for the size fragment preceding writable space
char * s1 = heap_end - 9;
printf("%s", s1); // here i expected to see the s1111111 string printed to stdout
}