2017-01-19 5 views
0

Я написал эту программу в C (только для отладки):Не удается найти адрес возврата в GDB

void return_input(void) 
{ 
    char array[10]; 

    gets(array); 
    printf("%s\n", array); 
} 

main() 
{ 
    return_input(); 

    return 0; 

}

Я экспериментировал с переполнением стека, и с тех пор я работаю с 64 битных машины я скомпилировал с

gcc -m32 -mpreferred-stack-boundary=2 -ggdb overflow.c -o overflow 

Я тогда отлажена программой с помощью GDB, и разобрал функцию return_input, я получил:

0x0804841b <+0>: push %ebp 
    0x0804841c <+1>: mov %esp,%ebp 
    0x0804841e <+3>: sub $0xc,%esp 
    0x08048421 <+6>: lea -0xa(%ebp),%eax 
    0x08048424 <+9>: push %eax 
    0x08048425 <+10>: call 0x80482e0 <[email protected]> 
    0x0804842a <+15>: add $0x4,%esp 
    0x0804842d <+18>: lea -0xa(%ebp),%eax 
    0x08048430 <+21>: push %eax 
    0x08048431 <+22>: call 0x80482f0 <[email protected]> 
    0x08048436 <+27>: add $0x4,%esp 
    0x08048439 <+30>: nop 
    0x0804843a <+31>: leave 
    0x0804843b <+32>: ret 

Это отмечает, что обратный адрес должен быть 0x0804843b (или нет?) Тем не менее, при рассмотрении ЭСП (помните, что это 32-битный компилируется программа на 64-битной машине) с x/20x $esp (после установки точки останова на получает функцию и ret), я не могу найти обратный адрес:

0xffffd400: 0xffffd406 0x080481ec 0x08048459 0x00000000 
    0xffffd410: 0xffffd418 0x08048444 0x00000000 0xf7e195f7 
    0xffffd420: 0x00000001 0xffffd4b4 0xffffd4bc 0x00000000 
    0xffffd430: 0x00000000 0x00000000 0xf7fb0000 0xf7ffdc04 
    0xffffd440: 0xf7ffd000 0x00000000 0xf7fb0000 0xf7fb0000 

Почему я не могу увидеть обратный адрес? Извините за длинный вопрос. Заранее спасибо

+0

Как долго длилась строка, которую вы получили? Перезапись обратного адреса - это именно то, как переполнение буфера может использоваться для запуска вредоносного кода ... – StoryTeller

+0

@StoryTeller, как я уже упоминал в вопросе. Я установил перерыв в получении и, следовательно, ничего не добавил. Проблема в том, что я не вижу обратного адреса –

+0

@StoryTeller Я никогда не слышал о том, что стек растет вниз. Можете ли вы рассказать об этом? –

ответ

2

0x0804843b is 'ret'. Кажется, вы путаете это с «обратным адресом». Адрес возврата - это адрес следующей команды для выполнения в вызывающей функции. В частности, для этого кода:

0x08048425 <+10>: call 0x80482e0 <[email protected]> 
    0x0804842a <+15>: add $0x4,%esp 

Обратный адрес: 0x0804842a.

Теперь неясно, что именно вы делали. Компиляция, как вы указали, делает «break gets» + «run» работает отлично для меня. Вы уверены, что вы сбрасываете рег из «внутри»?

(gdb) disassemble return_input 
Dump of assembler code for function return_input: 
    0x0804843b <+0>: push %ebp 
    0x0804843c <+1>: mov %esp,%ebp 
    0x0804843e <+3>: sub $0xc,%esp 
    0x08048441 <+6>: lea -0xa(%ebp),%eax 
    0x08048444 <+9>: push %eax 
    0x08048445 <+10>: call 0x8048300 <[email protected]> 
    0x0804844a <+15>: add $0x4,%esp 

Настоящая инструкция должна вернуться к.

0x0804844d <+18>: lea -0xa(%ebp),%eax 
    0x08048450 <+21>: push %eax 
    0x08048451 <+22>: call 0x8048310 <[email protected]> 
    0x08048456 <+27>: add $0x4,%esp 
    0x08048459 <+30>: nop 
    0x0804845a <+31>: leave 
    0x0804845b <+32>: ret  
End of assembler dump. 

(gdb) break gets 
Breakpoint 1 at 0x8048300 
(gdb) run 
[..] 
Breakpoint 1, 0xf7e3a005 in gets() from /lib/libc.so.6 
(gdb) x/20x $esp 
0xffffd160: 0x00000001 0xf7fa3000 0xffffd180 0x0804844a 

И вот он находится на 4-м месте.

0xffffd170: 0xffffd176 0x0804820c 0x08048479 0x00000000 
0xffffd180: 0xffffd188 0x08048464 0x00000000 0xf7df15a6 
0xffffd190: 0x00000001 0xffffd224 0xffffd22c 0x00000000 
0xffffd1a0: 0x00000000 0x00000000 0xf7fa3000 0xf7ffdbe4 
(gdb) 
+0

У меня здесь три вопроса: 1) Если обратный адрес не является адресом следующей инструкции, которая должна быть выполнена после возврата из функции, что это такое?2) какой адрес я должен переполнить, чтобы получить ошибку сегментации? 3) почему я не могу найти адрес 'ret' в команде' x/20x $ esp'? –

+0

1. Какое состояние штабеля вы демпируете в первую очередь? 2. вам нужно перезаписать место, где сохраняется адрес возврата, что еще. 3. Почему вы ищете адрес «ret» и где вы взяли bt. В общем, я могу только рекомендовать вам прочитать классику по этому вопросу: http://phrack.org/issues/49/14.html –

Смежные вопросы