Стековые сюрпризы gcc 3.4.6

Тема в разделе "WASM.UNIX", создана пользователем lcat, 6 май 2007.

  1. lcat

    lcat New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    9
    Добрый день, все наверно читал статью Smashing The Stack For Fun And Profit.
    Возник вопрос в одом из примеров который у меня не работает.
    http://doc.bughunter.net/buffer-overflow/smash-stack.html#buffer_overflow, чтоб не искали.
    Я немного изменил функцию но суть не изменилась.
    Вот моя программа.
    Код (Text):
    1. void function(int a, int b, int c) {
    2.    char buffer1[5]="AAAAA";
    3.    char buffer2[10]="BBBBBBBBBB";
    4.    int *ret;
    5.  
    6.    ret = buffer1 + 12;
    7.    (*ret) += 8;
    8. }
    9. void main() {
    10.   int x;
    11.  
    12.   x = 0;
    13.   function(1,2,3);
    14.   x = 1;
    15.   printf("%d\n",x);
    16. }
    gcc -ggdb -mpreferred-stack-boundary=2 -o example3 example3.c
    gdb example3
    (gdb) b 6
    Breakpoint 1 at 0x80483d4: file example3.c, line 6.
    (gdb) r
    Starting program: /home/lcat/fotos/program/source/c/testing/buffer_overflow/example3

    Breakpoint 1, function (a=1, b=2, c=3) at example3.c:6
    warning: Source file is more recent than executable.
    6 ret = buffer1 + 20;
    (gdb) disassemble main
    Dump of assembler code for function main:
    0x080483ec <main+0>: push %ebp
    0x080483ed <main+1>: mov %esp,%ebp
    0x080483ef <main+3>: sub $0x4,%esp
    0x080483f2 <main+6>: movl $0x0,0xfffffffc(%ebp)
    0x080483f9 <main+13>: push $0x3
    0x080483fb <main+15>: push $0x2
    0x080483fd <main+17>: push $0x1
    0x080483ff <main+19>: call 0x80483a4 <function>
    0x08048404 <main+24>: add $0xc,%esp <<< 0x08048404 Адресс возврата
    0x08048407 <main+27>: movl $0x1,0xfffffffc(%ebp)
    0x0804840e <main+34>: pushl 0xfffffffc(%ebp)
    0x08048411 <main+37>: push $0x8048535
    0x08048416 <main+42>: call 0x80482b8 <printf@plt>
    0x0804841b <main+47>: add $0x8,%esp
    0x0804841e <main+50>: leave
    0x0804841f <main+51>: ret
    End of assembler dump.
    (gdb) i r
    eax 0x42424242 1111638594
    ecx 0x0 0
    esp 0xbffff37c 0xbffff37c
    ebp 0xbffff3a0 0xbffff3a0
    eip 0x80483d4 0x80483d4 <function+48>
    (gdb) x/20 $ebp-40
    0xbffff378: 0xbffff398 0x0804830c 0x42424242 0x42424242
    0xbffff388: 0xbfff4242 0x08048295 0x41414141 0x40017e41
    0xbffff398: 0xbffff3b8 0x0804843b 0xbffff3b8 0x08048404
    0xbffff3a8: 0x00000001 0x00000002 0x00000003 0x00000000
    0xbffff3b8: 0xbffff3d8 0x4004528b 0x00000001 0xbffff404

    (gdb) disassemble function
    Dump of assembler code for function function:
    0x080483a4 <function+0>: push %ebp
    0x080483a5 <function+1>: mov %esp,%ebp
    0x080483a7 <function+3>: sub $0x24,%esp Отводим 36 байт
    0x080483aa <function+6>: mov 0x8048524,%eax

    Видно что по адресу 0xbffff3a4 (Зеленый цвет) адрес возврата из функции <function> за ним и переменны которые мы push перед этим, потом идет сохраненный ebp (Красный цвет) потом не понимаю что и опять сохраненный ebp (Красный цвет) , потом только идут переменные buffer1 buffer2 *ret, и еще интересно то что между buffer1 buffer2 залезли 4байты (Синий цвет) еще чего то там :)
    Из-за чего компилятор это делает, если можно прокоментировать все, зачем компилятор повторил сохраненный ebp.
    Это мешает узнать точное смещение до адреса возврата.
    Хотя то что он отвел 36байт полностью заполняются. Частичто понятным кодом и частично непонятным.
    gcc 3.4.6 Может это особенность компилятора, если ставлю -O3, -O2
    Он вообще удаляет все из функции:
    (gdb) disassemble function
    Dump of assembler code for function function:
    0x080483b0 <function+0>: push %ebp
    0x080483b1 <function+1>: mov %esp,%ebp
    0x080483b3 <function+3>: sub $0x28,%esp
    0x080483b6 <function+6>: mov %ebp,%esp
    0x080483b8 <function+8>: pop %ebp
    0x080483b9 <function+9>: ret
    End of assembler dump.
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Выравнивание на границу параграфа (16 байт). Зачем? - А х.з. Он и не такое может :) И разные версии GCC генерируют совершенно разный код на зло писателям эксплоитов.

    А Вы уверены что это именно ebp? Покажите код инициализации массивов (ААААА и ББББББББ) - там должно стать понятнее откуда взялся ещё один "ebp".

    Поэтому без отладчика или дизассемблера (сам gcc ключём -S выдаёт ассемблерный код) тут не обойтись.
     
  3. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    В режиме без оптимизации предъявлять компилятору претензии "зачем", "что мешает" не имеет смысла.
     
  4. lcat

    lcat New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    9
    Quantum
    Возможно что это случайность :), Я выведу в intеловском виде.
    (gdb) disassemble function
    Dump of assembler code for function function:
    0x080483a4 <function+0>: push ebp
    0x080483a5 <function+1>: mov ebp,esp
    0x080483a7 <function+3>: sub esp,0x24
    0x080483aa <function+6>: mov eax,ds:0x8048524 | 0x41414141
    0x080483af <function+11>: mov DWORD PTR [ebp-16],eax тут инициализируем buffer1
    0x080483b2 <function+14>: mov al,ds:0x8048528 | 0x42420041
    0x080483b7 <function+19>: mov BYTE PTR [ebp-12],al
    0x080483ba <function+22>: mov eax,ds:0x804852a | 0x42424242
    0x080483bf <function+27>: mov DWORD PTR [ebp-32],eax тут инициализируем buffer2
    0x080483c2 <function+30>: mov eax,ds:0x804852e | 0x42424242
    0x080483c7 <function+35>: mov DWORD PTR [ebp-28],eax
    0x080483ca <function+38>: mov ax,ds:0x8048532 | 0x25004242
    0x080483d0 <function+44>: mov WORD PTR [ebp-24],ax
    0x080483d4 <function+48>: lea eax,[ebp-16]
    0x080483d7 <function+51>: add eax,0xc
    0x080483da <function+54>: mov DWORD PTR [ebp-36],eax | тут инициализируем *ret
    0x080483dd <function+57>: mov edx,DWORD PTR [ebp-36]
    0x080483e0 <function+60>: mov eax,DWORD PTR [ebp-36]
    0x080483e3 <function+63>: mov eax,DWORD PTR [eax]
    0x080483e5 <function+65>: add eax,0x8
    0x080483e8 <function+68>: mov DWORD PTR [edx],eax
    0x080483ea <function+70>: leave
    0x080483eb <function+71>: ret
    End of assembler dump.
    Видимо это особый мусор, так как ничто его не создает.