На языках ассемблера в стиле AT & T символ процента обычно указывает регистр.В процессорах семейства x86 с 386 года GS является одним из так называемых сегментных регистров .Однако в защищенном режиме регистры сегментов работают как регистры селектора .
. Селектор виртуальной памяти представляет свое собственное отображение виртуального адресного пространства вместе со своим собственным режимом доступа.С практической точки зрения, %gs:0x14
можно рассматривать как ссылку на массив, источник которого хранится в% gs (хотя ЦП и немного разыменовывает).В современных системах GNU / Linux %gs
обычно используется для указания на область локального хранилища потока.Однако в коде, о котором вы спрашиваете, важен только один элемент TLS - канарейка стека.
Идея состоит в том, чтобы попытаться обнаружить ошибку переполнения буфера, поместив случайное, но постоянное значение - оно называетсяканарейка стека в памяти канареек, которые шахтеры использовали, чтобы сигнализировать об увеличении уровней ядовитых газов, умирая - в стек до вызова gets()
над его рамкой стека и проверяя, является ли онвсе еще там после gets()
вернется.gets()
не имеет смысла перезаписывать эту часть стека - она находится за пределами своего собственного стекового фрейма, и ей не дается указатель на нее - поэтому, если канарейка стека умерла, что-то пошло не так опасным образом.(C как среда программирования оказывается особенно склонной к такого рода ошибкам, и исследователи безопасности научились использовать многие из них за последние двадцать лет или около того. Кроме того, gets()
оказывается функцией, которая по своей природерискует переполнить целевой буфер.) Вы не предлагали адреса с вашим кодом, но 0x80484ac, вероятно, является адресом leave
, а call 0x8048394
, который выполняется в случае несовпадения (то есть перепрыгивается на je 0x80484ac
в случае совпадения), вероятно, является вызовом __stack_chk_fail()
, предоставленным libc для обработки повреждения стека, спасаясь от метафорической ядовитой шахты.
Причина, по которой каноническое значение канарейки стека сохраняется вЛокальное хранилище потоков таково, что каждый поток может иметь свой собственный канареечный стек.Сами стеки обычно не разделяются между потоками, поэтому естественно также не использовать канареечное значение.