[...] добавление четырех [32-разрядных] (или, возможно, восьми [64-разрядных]) байтов к указателю стека по существу удалит предыдущее значение из стека, не помещая его в регистр, такой как pop.
Стек представляет собой структуру данных LIFO, поэтому последнее значение, помещенное в стек, будет удалено первым.Добавление значения 4 (8) байтов в стек просто пропускает текущее самое верхнее значение без передачи его в регистр.POP
также передаст значение в регистр.
Означает ли это, что вы на самом деле не стираете значение, а просто стираете позицию указателя, чтобы он действовал так, как если бы он был пустым?
Вы просто указываете Указатель вершины стека ESP (RSP) на предыдущую запись.Текущая запись не стирается, но пропускается (больше не указывается).
Означает ли это, что вы также можете ПОДПИСАТЬ ESP 4 и получить данные даже после их «стирания»?
По сути, да.Если стек не был изменен другой процедурой, обработчиком прерываний, асинхронным вызовом или другим влиянием, которое использовало стек, вы можете извлечь предыдущее значение стека.Это особенно важно с точки зрения безопасности.Поэтому для безопасного удаления данных в стеке они должны быть перезаписаны нулями вручную.
Вдохновленный комментарием @PeterCordes Я написал простой пример в 32-разрядной сборке Linux, иллюстрирующий это:
.intel_syntax noprefix
.global _start
.text
_start:
call subroutine
mov ebx, [esp-12] /* Get data from subroutine */
mov eax, 1
int 0x80
/* echo $? outputs '66' */
subroutine:
push ebp
mov ebp, esp
push 66 /* local variable to be leaked */
mov esp, ebp
pop ebp
ret
Назовите его stack.s
и соберите его с
as -32 stack.s
ld -m elf_i386 -elf -o a a.out
./a
echo $?
Вывод будет 66
, значение локальной переменной из подпрограммы.Так что утечка данных из стека возможна.Насколько это серьезно?Я не уверен.Но это возможно.
Если вы обнуляете важные данные, вы должны позаботиться о том, чтобы компилятор не оптимизировал эти инструкции.Вы можете найти лекцию продолжительностью в один час под названием "35C3 - Memsad" об этом на YouTube (это недавний доклад немецкого CCC ).