Понять, что делает код сборки для <getbuf> - PullRequest
0 голосов
/ 17 апреля 2019

Вопросы 1: Я читаю об атаках переполнения буфера и видел несколько примеров, однако у меня возникают проблемы с пониманием того, что происходит на уровне кода сборки.Может кто-нибудь помочь мне разобраться в этом коде сборки?

Вопросы 2: В этой атаке мы сделали 24 дополнительных бита, а затем адрес назначения, который здесь перезаписывается новым адресом назначения.

Вопросы 3: я знаю, что первый столбец относится к адресу, но я запутался, что за второй столбец, например, в 1-й строке у нас есть 1 48 38 ec

Пустой код:

<getbuf>
4019a1   48 38 ec     sub $0x18, rsp    // 24 bit for buffer? but what's rsp?
4019a8   48 38 ec 18  mov %rsp, %rdi    // rdi == arg, but what's rsp?
4019ac   48 89 e7     call <gets>       // not sure what does <gets> do
4019af   e8 8c 02 00  add  $0x18, %rsp  // not sure what's going on.
4019b4   48 83 c4 18  retq              // return?
4019be   c3           xchg %ax %ax      // I thought we returned already

это не фактический код, а просто близкое представление.

1 Ответ

0 голосов
/ 17 апреля 2019

Может кто-нибудь помочь мне разобраться в этом коде сборки?

24 бит для буфера?но что такое rsp?

rsp - это указатель стека.Стек - это некоторая область в памяти, используемая для временного хранения данных функциями.На многих процессорах (включая x86) инструкция call также сохраняет адрес инструкции, которая должна быть выполнена в стеке после инструкции ret или retq.

На процессорах x86 *Регистр 1013 * (32-разрядный: esp) содержит адрес.Память перед этим адресом свободна, память по этому адресу и после того, как этот адрес используется.

Если вам требуется 100 байт временной памяти, вы вычитаете 100 из регистра rsp;тем самым вы указываете, что эти 100 байт памяти используются (вашим кодом).Как только вам больше не понадобится память, вы восстанавливаете старое значение rsp.

, поскольку retq предполагает, что rsp указывает на память, в которой call хранит адрес,Вы должны восстановить старое значение rsp, прежде чем выполнить retq.

, не уверенный в том, что gets do

gets является функциейпредназначен для программирования на С.Он читает в одной строке текста (например, с клавиатуры).В вашем случае строка записывается в стек.В отличие от fgets эта функция будет не проверять, достаточно ли места в памяти!

Если длина прочитанной строки превышает 24 байта, функция gets перезапишет данные впамять, которая «использовалась» до инструкции sub $0x18, %rsp.

И, как я уже писал, адрес, записанный call и прочитанный retq, хранится там!

InДругими словами: если строка, считанная с помощью gets, слишком длинная, адрес, записанный с помощью call, будет перезаписан, и инструкция retq не вернется к вызывающей функции, но перейдет к некоторому неправильному адресу в памяти.

(надеюсь, это ответит на вопрос 2.)

Я думал, что мы уже вернулись

xchg %ax %ax на самом деле не инструкция здесь, нопросто фиктивные данные.Он вставляется некоторыми компиляторами, потому что эти компиляторы всегда генерируют функции, кратные (например) двум байтам.

, но я запутался, что за второй столбец, например, в 1-й строке мы имеем1 48 38 ec

Это байты (в шестнадцатеричном формате) в ОЗУ, которые представляют инструкции ассемблера в 3-м столбце.

Пример: шестнадцатеричные байты 48 38 ec в ОЗУ будет интерпретироваться ЦП как sub $0x18, %rsp.

(Обратите также внимание на комментарий tum_: данные, показанные в вашем примере, явно неверны: 48 38 ec, очевидно, не байты, представляющие инструкцию sub $0x18, %rsp.)

...