Я провел много исследований, пытаясь понять эту тему, но все еще имею некоторую путаницу. В настоящее время я исследую переполнение буфера. Вот пример функции, на которую я смотрю:
int testFunction(char* sourceBuffer)
{
unsigned char result = 0;
char destinationBuffer[512];
//do some insecure stuff with strcpy()
}
Я компилирую с этими настройками:
gcc -g -z execstack -fno-stack-protector -o test test.c
Из того, что я могу сказать, ASLR, защита стека, канареечные значения и защита компилятора должны быть отключены с этими настройками. Однако при проверке памяти в GDB мой стек выглядит так:
HIGH
sourceBuffer...temp...etc...
RET address [4 bytes]
EBP address [4 bytes]
(8 bytes of mystery memory)
result [1 byte]
destinationBuffer[512 bytes]
LOW
Я пробовал читать о выравнивании/заполнении стека, эта статья была особенно полезной: Распределение стека, заполнение, и выравнивание
Выравнивание по умолчанию — 16 байт. Согласно этому ответу, если я изменю n = 2, похоже, это сработает. result
находится всего за 1 байт до того места, где начинается указатель EBP
. Это позволит мне использовать переполнение буфера в адресе возврата, как я хочу.
Мне действительно трудно, как это работает. Если по умолчанию это 16, стек изначально настроен на 16 байтов, тогда указатели RET и EBP занимают по 4 байта каждый, поэтому осталось всего 8 байтов? Я просто довольно потерял понимание этого.