2017-02-10 9 views
1

Я хочу включить функцию защиты стека в gcc для системы, которую я создаю для x86 linux.Есть ли способ «перегрузить» или переопределить __stack_chk_fail?

Я хочу, чтобы, если он обнаруживает разбиение стека, он будет вызывать функцию моего собственного, которая будет обрабатывать случай, или она вызовет мою собственную реализацию функции __stack_chk_fail, есть ли способ сделать это?

До сих пор я пытался отключить __stack_chk_fail и __stack_chk_guard, а затем сам определил их, но он не сработал и привел к ошибке сегментации при попытке использования переполнения буфера. Вот пример того, что я сделал:

#undef __stack_chk_guard 
    #undef __stack_chk_fail 
    uintptr_t __stack_chk_guard = 0xdeadbeef; 

    void __stack_chk_fail(void) 
    { 
     printf("Stack smashing detected"); 
    } 

    void foo(void) 
    { 
    char buffer[2]; 
    strcpy(buffer, "hello, I am smashing your stack!"); 
    } 

Я также попытался с помощью LD_PRELOAD но в результате ошибки сегментации при битье стека, но это также приводит к ошибке сегментации.

+0

C не поддерживает перегрузку, это язык, отличный от C++. Не используйте спам-теги. – Olaf

+0

@ Олаф, я знаю, c не поддерживает перегрузку метода, но у меня нет лучшего имени для того, что я пытаюсь сделать. – omer12433

+0

Итак, поскольку вы решили использовать C, мне все равно интересно, почему вы использовали тег C++. Так или иначе, мой комментарий применим. На ваш вопрос: что вы имеете в виду под «undef ...», вы не можете «undef» переменную или функцию. Это не макрос. Что касается segfault: вы вызываете неопределенное поведение и ваш код ведет себя неопределенным. Я бы сказал, что все работает как ожидалось, миссия выполнена, без проблем. – Olaf

ответ

2

После некоторого исследования я узнал, что могу использовать флаг компоновщика --wrap для обертывания __stack_chk_fail и вставить мой собственный hanlding так, как я хотел.

Флаг изменить каждый вызов __stack_chk_fail к __wrap___stack_chk_fail и каждый вызов __real___stack_chk_fail к __stack_chk_fail

Я даже могу пропустить вызова реальной __stack_chk_fail, если я хотел

Ниже приведен пример кода в файле с именем test.c :

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
void __real___stack_chk_fail(void); 

void __wrap___stack_chk_fail(void) 
{ 
    printf("our test"); 
    __real___stack_chk_fail(); 
} 
void func() 
{ 
    char buffer[2]; 
    strcpy(buffer, "smashhhhhhhhhhhhhhhh"); 
} 
int main(void) 
{ 
    func(); 
    return 0; 
} 

Чтобы скомпилировать его выполнить:

gcc -fstack-protector-strong -c test.c 
gcc -Wl,--wrap=__stack_chk_fail test.o 

вывод будет «наш тестом», а затем регулярное поведение __stack_chk_fail

UPDATE:

Другим способом сделать это, чтобы исключить libssp из процесса сцепления с флагом --exclude-libs,libssp и осуществлять __stack_chk_fail и guard_setup (функция, которая инициирует значение __stack_chk_guard) самостоятельно