2017-02-10 84 views
1

我想在gcc中爲我在x86 linux上運行的系統構建一個系統啓用堆棧保護功能。有沒有辦法「超載」或重新實現__stack_chk_fail?

我想,如果它檢測到堆棧溢出會打電話給我自己的功能,將處理的情況下,否則會叫我自己實現的功能__stack_chk_fail的,是有辦法做到這一點?

到目前爲止,我試圖undef __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(即在啓動__stack_chk_guard值函數)不支持重載,它是一種不同的語言比C++。不要垃圾標籤。 – Olaf

+0

@Olaf我知道C不支持方法重載,但我不爲有更好的名字什麼,我試圖做 – omer12433

+0

因此,當你決定使用C,我仍然不知道爲什麼你使用的C++代碼了。無論如何,我的評論都適用。回答你的問題:你的意思是「undef ...」,你不能「取消」一個變量或函數。這不是一個宏觀。關於段錯誤:您調用未定義的行爲並且您的代碼行爲未定義。我會說一切按預期工作,任務完成,沒問題。 – Olaf

回答

2

經過一番研究後,我發現我可以使用鏈接器標記--wrap來包裝__stack_chk_fail並插入我自己的hanlding,就像我想要的那樣。

標誌更改爲__wrap___stack_chk_fail__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_failguard_setup你自己