Поскольку мы уже знакомы с кадрами стека (если нет, то обратитесь к фрейму стека и созданию фрейма стека). Здесь мы поговорим о возможной проблеме концепции стековых фреймов.
Рассмотрим следующий фрагмент кода.
void vulnerable_function(int x) { int z; char str[8]; z=x+4; scanf("%s", str); if(z == 10){ do_something(str); }else{ never_to_be_called(); } } void main(){ ... vulnerable_function(6); ... }
Вы видите проблему? Нет? Давайте продолжим.
Фрейм стека для vulnerable_function(6)
будет выглядеть примерно так
$sp --> 0066 z [local variable] 0058 str [local variable] 0054 x [function parameter] 0050 0x0004 [return address] $bp --> 0050 0xabcd [$bp of older frame]
Теперь вы видите проблему? все еще нет? продолжать.
Когда будет выполнено scanf("%s", str)
, что, если пользователь введет в качестве ввода строку, которая больше 8. Предположим, что ввод abcdefghij
Карта памяти будет похожа на
0x0058 a 0x0059 b 0x0060 c 0x0061 d 0x0062 e 0x0063 f 0x0064 g 0x0065 h 0x0066 i 0x0067 j
вы можете увидеть адрес 0x0058
, где хранилась локальная переменная z
, теперь это грязно. Его значение не больше 10, что должно было быть. Таким образом, условие if
ложно, и будет вызвана функция never_to_be_called()
.
Итак, ребята, это был простой случай переполнения буфера. Но мы ничего не могли сделать сами, поэтому мы обсудим это в следующем блоге.