Я пытаюсь изменить адрес возврата в стеке в обработчике ошибок сегмента, чтобы он пропускал инструкцию по ошибке. Однако я получаю ошибку сегмента всякий раз, когда пытаюсь изменить адрес возврата, если я не вызываю обработчик сигнала напрямую.
gdb не подходит для отладки, когда программа делает segfault, но когда я делаю info frame
, я вижу, что после segfault есть «уровень кадра 2», а не «уровень кадра 0»? Я не знаю, откуда GDB получает эту информацию, потому что, когда я пытаюсь ввести x/12xw $ebp
или сколько угодно слов, я не вижу обратного адреса для main()
...
Скомпилировано с -m32 -z execstack -fno-stack-protector в CentOS linux
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
void segment_fault_handler(int signum)
{
char* ret = (char*)(&signum)-4;
*(ret) += 8;
}
int main()
{
int phail = 0;
signal(SIGSEGV, segment_fault_handler);
segment_fault_handler(7); //Only by using this can I skip the next instruction
phail = *( (int *) 0);
printf("Win!\n");
return 0;
}
Причина, по которой я увеличиваю на 8, заключается в том, что инструкция phail в main()
составляет 8 байтов:
0x080484e2 <+37>: movl $0x7,(%esp)
0x080484e9 <+44>: call 0x8048480 <segment_fault_handler>
0x080484ee <+49>: mov $0x0,%eax
0x080484f3 <+54>: mov (%eax),%eax
0x080484f5 <+56>: mov %eax,0x1c(%esp)
0x080484f9 <+60>: movl $0x80485b4,(%esp)
0x08048500 <+67>: call 0x8048350 <puts@plt>
Нужно ли немного увеличить смещение? Нужно ли менять мой метод доступа к стеку (который, как мне кажется, соответствует EBP+4) при работе с ситуацией отказа сегмента?
ucontext_t
, переданной обработчику, не непосредственный адрес возврата функции обработки сигнала. (И не вызывайте его напрямую.) Пример программы по адресу stackoverflow.com/questions/5119288/ показывает, как получить доступ к структуреucontext_t
. - person zwol   schedule 28.01.2017