Я пытаюсь играть с переполнением буфера. Я не понимаю, что здесь происходит со значением eip.
Вот код C:
void copy(char *arg) {
char msg[256];
strcpy(msg,arg);
}
Сборка для него:
0x804847d <copy+25>: call 0x8048368 <strcpy@plt>
0x8048482 <copy+30>: leave
0x8048483 <copy+31>: ret
Я ввожу в качестве аргумента строку типа "_\xAA\xBB\xCC\xDD" с размером, рассчитанным таким образом, что последние 4 байта будут 4 байта после $ebp (чтобы перезаписать реальный обратный адрес). И это, кажется, работает.
в ГДБ:
(break before strcpy)
x/2wx $ebp
0xbffffb38: 0xbffffb58 0x080484d2
n
(just after strcpy execution)
x/2wx $ebp
0xbffffb38: 0x80cdd189 0x080484b6
...
n
...
x/2wx $ebp
0xbffffb38: 0x80cdd189 0x080484b6
Таким образом, обратный адрес был 0x080484d2
, а после моего переполнения он стал 0x080484b6
, чего я и хочу. но программа завершается: "Не удается получить доступ к памяти по адресу 0x80cdd18d".
Я не знаю, почему $eip не был установлен на мой адрес, и из-за адреса кода в 0x08048... Я вполне уверен, что $ebp+4 был местом, содержащим обратный адрес
Я попробовал еще раз со строкой на 4 байта меньше, и на этот раз она перезаписала $ebp, а не $ebp+4, и после возврата $eip было установлено значение, содержащееся в $ebp+4.
Любые объяснения?
stepi
вместоnext
для одношаговых инструкций после strcpy, и вы сможете лучше понять, что происходит. - person   schedule 03.11.2013display/i $pc
(и, возможно, некоторые другие интересные регистры) иstepi
через последовательность возврата. - person gsg   schedule 04.11.2013