Функция регистрации стека ECX в дампе ассемблерного кода - PullRequest
2 голосов
/ 03 мая 2020
#include<stdio.h>
#include<string.h>
int main(int argc, char ** argv)
{
    char buffer[500];
    strcpy(buffer, argv[1]);

    return 0;
}

Я могу скомпилировать эту программу, используя gcc -m32 -fno-stack-protector -z execstack -fno-pie -no-pie -g -o vuln vuln.c

При разборке основной функции с помощью отладчика я получаю следующее:

Dump of assembler code for function main:
   0x0804840b <+0>:     lea    0x4(%esp),%ecx
   0x0804840f <+4>:     and    $0xfffffff0,%esp
   0x08048412 <+7>:     pushl  -0x4(%ecx)
   0x08048415 <+10>:    push   %ebp
   0x08048416 <+11>:    mov    %esp,%ebp
   0x08048418 <+13>:    push   %ecx
   0x08048419 <+14>:    sub    $0x204,%esp
   0x0804841f <+20>:    mov    %ecx,%eax
   0x08048421 <+22>:    mov    0x4(%eax),%eax
   0x08048424 <+25>:    add    $0x4,%eax
   0x08048427 <+28>:    mov    (%eax),%eax
   0x08048429 <+30>:    sub    $0x8,%esp
   0x0804842c <+33>:    push   %eax
   0x0804842d <+34>:    lea    -0x1fc(%ebp),%eax
   0x08048433 <+40>:    push   %eax
   0x08048434 <+41>:    call   0x80482e0 <strcpy@plt>
   0x08048439 <+46>:    add    $0x10,%esp
   0x0804843c <+49>:    mov    $0x0,%eax
   0x08048441 <+54>:    mov    -0x4(%ebp),%ecx
   0x08048444 <+57>:    leave  
   0x08048445 <+58>:    lea    -0x4(%ecx),%esp
   0x08048448 <+61>:    ret
End of assembler dump.

G CC версия: 6.5.0 ОС: Ubuntu 16.04 Версия GDB: 7.11.1 Учебник, который я обновлял, показывал этот код сборки:

Dump of assembler code for function main:
   0x080483fb <+0>:     push   %ebp
   0x080483fc <+1>:     mov    %esp,%ebp
   0x080483fe <+3>:     sub    $0x1f4,%esp
   0x08048404 <+9>:     mov    0xc(%ebp),%eax
   0x08048407 <+12>:    add    $0x4,%eax
   0x0804840a <+15>:    mov    (%eax),%eax
   0x0804840c <+17>:    push   %eax
   0x0804840d <+18>:    lea    -0x1f4(%ebp),%eax
   0x08048413 <+24>:    push   %eax
   0x08048414 <+25>:    call   0x80482d0 <strcpy@plt>
   0x08048419 <+30>:    add    $0x8,%esp
   0x0804841c <+33>:    mov    $0x0,%eax
   0x08048421 <+38>:    leave
   0x08048422 <+39>:    ret
End of assembler dump.

У меня есть следующие вопросы: Как я могу получить точно такой же дамп ассемблерного кода, который указан в руководстве? Разница в выводе кажется из-за ecx регистра. Что делает этот регистр и почему он не является частью кода ассемблера учебника? В основной функции я построил буферный массив размером 500, равный 1f4 в шестнадцатеричном, поэтому ассемблерный код учебника вычитает 1f4 из регистра esp, а мой ассемблерный код вычитает 204, что 516 в десятичном виде. Я не могу этого понять.

Редактировать: Как отмечено в комментариях, если я добавлю -mpreferred-stack-boundary=2 к флагам компилятора, то получу тот же код сборки, что и в руководстве. Почему?

...