Выравнивание стека и аргумент доступа в разборке?Linux

Ответить
Anonymous
 Выравнивание стека и аргумент доступа в разборке?

Сообщение Anonymous »

Весное примечание: Этот вопрос не относится к сборке ARM. Я использовал тег Android, и я добавляю это для ясности. Указатель EBP (указатель кадров) или стека используется для доступа к локальным переменным в сборке, поскольку он не изменяется и остается статичным во время выполнения кадры стека функции. Напротив, ESP уменьшается во время выполнения кадра стека. Поскольку EBP остается статичным, легче добавить статические смещения для доступа к аргументам, передаваемым функциям. Я получил эту информацию:

Я использую android termux .


Я установил proot-distro для linux (ubuntu) для запуска файлов Linux ELF.


Я использовал кросс-компилятор i686-linux-gnu-gcc для компиляции x86 32-битный Файлы ELF. < /P>
< /blockquote>

Я использовал x86_64-linux-gnu-objdump < /strong> для разборки. /p>
< /blockquote>
В дампе разборки я заметил эти строки: < /p>

Код: Выделить всё

endbr32
LEA  ECX, [ESP+ 0x4]
AND  ESP, 0xfffffff0
PUSH DWORD PTR [ECX- 0x4]

< /code>
Я понимаю эту инструкцию: < /p>

AND ESP, 0xFFFFFFF0

Здесь, ESP и с маской 0xfffffff0 [/b], чтобы обнулить Nibble ESP, выравнивая стек до 16- байт граница. Это связано с тем, что инструкции SSE, такие как Movaps, которые перемещают упакованные типы данных в xmm регистры, требуют 16-байтового выравнивания. В то время как невыполненные движения (движения) существуют, они разрушают производительность. Точно так же avx-2 требуется 256-битный (32-байт) выравнивание для регистров YMM, и AVX-512 требует 512- Бит (64-байт) выравнивание для zmm регистров. Инструкция, я уже искал любые другие вопросы, задаваемые в переполнении стека, связанные с этими инструкциями, но я не могу найти какие -либо вопросы, реализованные для этих строк, однако есть вопросы для и esp, 0xfffffff0 :

Код: Выделить всё

LEA  ECX, [esp + 0x4]
PUSH DWORD PTR [ECX- 0x4]

< /code>
Я проанализировал эти инструкции и попытался понять, что они делают и почему они там. Вот моя интерпретация - пожалуйста, поправьте меня, если я ошибаюсь. . < /p>
< /blockquote>

Инструкция push dword ptr [ecx - 0x4] нажимает обратный адрес вызывающего абонента в стек после его выравнивания , гарантируя, что кадр стека правильно выровнен перед инструкцией вызовов. Тем не менее, я заметил, что выравнивание осуществляется, и адрес возврата копируется после выравнивания. Вопрос в том, что аргументы, передаваемые функции, теперь разделены этим выравниванием. Это означает, что выравнивание вставлено между адресом возврата и аргументами функции. Смещения < /p>
Из -за этого разделения аргумент сметается с указателя кадров (EBP) больше не статична. Например, в «нормальной» сборке можно получить доступ к аргументам, используя статические смещения, такие как EBP + 8. Следовательно, аргументы больше не могут быть доступны со статическими смещениями. выравнивания DWORD.
[b] Программа 1: [/b] 

#include 
int main(int argc, char **argv) {
printf("Count: %d\n", argc);
return 0;
}

< /code>
Разборка основной функции в разделе .Text: < /p>

0000118d :
118d:       f3 0f 1e fb             endbr32
1191:       8d 4c 24 04             lea    ecx, [esp + 0x4]
1195:       83 e4 f0                and    esp, 0xfffffff0
1198:       ff 71 fc                push   DWORD PTR [ecx - 0x4]
119b:       55                      push   ebp
119c:       89 e5                   mov    ebp, esp
119e:       53                      push   ebx
119f:       51                      push   ecx
11a0:       e8 2c 00 00 00          call   11d1 
11a5:       05 33 2e 00 00          add    eax, 0x2e33
11aa:       89 ca                   mov    edx, ecx
11ac:       83 ec 08                sub    esp, 0x8
11af:       ff 32                   push   DWORD PTR [edx]
11b1:       8d 90 30 e0 ff ff       lea    edx, [eax - 0x1fd0]
11b7:       52                      push   edx
11b8:       89 c3                   mov    ebx, eax
11ba:       e8 81 fe ff ff          call   1040 
11bf:       83 c4 10                add    esp, 0x10
11c2:       b8 00 00 00 00          mov    eax, 0x0
11c7:       8d 65 f8                lea    esp, [ebp - 0x8]
11ca:       59                      pop    ecx
11cb:       5b                      pop    ebx
11cc:       5d                      pop    ebp
11cd:       8d 61 fc                lea    esp, [ecx - 0x4]
11d0:       c3                      ret

макет стека после выполнения каждой инструкции:
Начальный макет стека:

Код: Выделить всё

Argument 2 (Top): [ESP + 8] (0xbfff1230)
Argument 1:       [ESP + 4] (0xbfff122c)
Return Address:   [ESP]     (0xbfff1228)

макет стека после lea ecx, [esp + 4] :

Код: Выделить всё

Argument 2 (Top): [ESP + 8] (0xbfff1230)
Argument 1:       [ESP + 4] (0xbfff122c)
Return Address:   [ESP]     (0xbfff1228)

ecx -> Адрес аргумента 1
макет стека после и esp, 0xfffffff0 : < /p>

Код: Выделить всё


Argument 2 (Top):  [OLD ESP + 8]  (0xbfff1230)
Argument 1:        [OLD ESP + 4]  (0xbfff122c)
Return Address:    [OLD ESP]      (0xbfff1228)
Alignment DWORD 1: (0xbfff1224)
Alignment DWORD 2: (0xbfff1220)  0xbfff1220 [/b] 
макет стека после [b] push dword ptr [ecx - 4] : < /p>
[code]
Argument 2 (Top):  [OLD ESP + 8]  (0xbfff1230)
Argument 1:        [OLD ESP + 4]  (0xbfff122c)
Return Address:    [OLD ESP]      (0xbfff1228)
Alignment DWORD 1: (0xbfff1224)
Alignment DWORD 2: (0xbfff1220)
Return Address:     0xbfff121c [/b] 
После этих макетов стека я понимаю, что ECX загружается с адресом [ESP + 4], который является адресом первого аргумента. Поскольку аргументы не могут быть доступны с использованием EBP из -за выравнивания на основе наблюдения [b] [/b], ECX используется для хранения начального адреса аргументов функции.  Я прав?[code]
#include 
int main(int argc, char **argv) {
printf("Count: %d\n", argc);
printf("Filename: %s\n", *argv);
return 0;
}

< /code>

0000118d :
118d:       f3 0f 1e fb             endbr32
1191:       8d 4c 24 04             lea    ecx, [esp + 0x4]
1195:       83 e4 f0                and    esp, 0xfffffff0
1198:       ff 71 fc                push   DWORD PTR [ecx - 0x4]
119b:       55                      push   ebp
119c:       89 e5                   mov    ebp, esp
119e:       56                      push   esi
119f:       53                      push   ebx
11a0:       51                      push   ecx
11a1:       83 ec 0c                sub    esp, 0xc
11a4:       e8 e7 fe ff ff          call   1090 
11a9:       81 c3 2f 2e 00 00       add    ebx, 0x2e2f
11af:       89 ce                   mov    esi, ecx
11b1:       83 ec 08                sub    esp, 0x8
11b4:       ff 36                   push   DWORD PTR [esi]
11b6:       8d 83 30 e0 ff ff       lea    eax, [ebx - 0x1fd0]
11bc:       50                      push   eax
11bd:       e8 7e fe ff ff          call   1040 
11c2:       83 c4 10                add    esp, 0x10
11c5:       8b 46 04                mov    eax, DWORD PTR [esi + 0x4]
11c8:       8b 00                   mov    eax, DWORD PTR [eax]
11ca:       83 ec 08                sub    esp, 0x8
11cd:       50                      push   eax
11ce:       8d 83 41 e0 ff ff       lea    eax, [ebx - 0x1fbf]
11d4:       50                      push   eax
11d5:       e8 66 fe ff ff          call   1040 
11da:       83 c4 10                add    esp, 0x10
11dd:       b8 00 00 00 00          mov    eax, 0x0
11e2:       8d 65 f4                lea    esp, [ebp - 0xc]
11e5:       59                      pop    ecx
11e6:       5b                      pop    ebx
11e7:       5e                      pop    esi
11e8:       5d                      pop    ebp
11e9:       8d 61 fc                lea    esp, [ecx - 0x4]
11ec:       c3                      ret

из разборки:
Смещение для второго аргумента рассчитывается относительно базового адреса, указанного ECX .
Здесь используется esi + 4 , но перед этим ecx перемещается в esi Полем Значение esi + 4 затем перемещается в eax , который нажимается в стек. ECX, [ESP + 0x4] используется для сохранения начального адреса аргументов функции (или адреса первого аргумента) для доступа к ним внутри функции. Если эта интерпретация неверна, пожалуйста, не стесняйтесь меня поправить.

Подробнее здесь: https://stackoverflow.com/questions/793 ... isassembly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»