Изменение потока выполнения программы по сигналу и адресу возврата

Я пытаюсь изменить поток выполнения программы, изменив адрес возврата функций в этом коде:

void s(int signum) {
    int b = 1;
    *(&b+3) = *(&b+3) + 4;
}

void f() {
    while(true);
    printf("f exit\n");
}

int main() {
    signal( SIGCONT, s );

    f();

    printf("end of prog");

    return 0;
}

Для этого я призываю f функция. Так что застревает на while(true), Тогда я отправляю SIGCONT сигнал для программирования с помощью kill -SIGCONT <PID> команда. Теперь программа должна прервать выполнение while(true) в f и выполнить s функция. В s функция, которую я определил b найти обратный адрес s функция в стеке выполнения, который *(&b+3), Я пытаюсь изменить это значение с *(&b+3) = *(&b+3) + 4 так что когда он вернется к fПропустить исполнение while(true) и выполнить printf("f exit\n"), но он застревает while и я понятия не имею, как заставить это работать.

ПРИМЕЧАНИЕ. Я проверил *(&b+3) в качестве адреса возврата, сравнив его со значением, возвращенным __builtin_return_address(0) ранее.

Совокупность функций main а также f должен быть неизменным.

Благодарю.

1 ответ

Решение состоит в том, чтобы сказать циклу while, что что-то изменилось. Например

volatile int flag = 0 ;

void s(int signum) {
    int b = 1;
    __sync_fetch_and_add( &flag, 1 ) ;
}

void f() {
    while(__sync_fetch_and_add( &flag, 0 ) == 0);
    printf("f exit\n");
}

Добавлена ​​атомарная функция (функция __sync_fetch_and_add), чтобы избежать оптимизации цикла. Я не уверен, что простого летучего достаточно. Жду комментариев сам по этому....

Другие вопросы по тегам