2016-04-28 79 views
2

是否可以修改C++中的調用棧? (我知道這是一個可怕的想法和我真的只是想知道----我不打算實際上這樣做)修改調用棧

例如:

void foo(){ 
    other(); 
    cout << "You never see this" << endl; //The other() function modifies the stack to 
          //point to what ever called this function...so this is not displayed 
} 
void other(){ 
    //modify the stack pointer here somehow to go down 2 levels 
} 

//Elsewhere 
foo(); 
+0

是的,你可以。但是你需要知道堆棧幀是什麼樣的。這是編譯器和平臺的依賴。你使用的是什麼操作系統和編譯器? –

+2

1.拋出一個異常,2'setjmp' /'longjmp' –

+0

@RichardHodges我真的只要求好奇的緣故(所以我實際上沒有一個需要解決的問題) – DarthRubik

回答

1

當一個函數調用另外一臺典型的C實現中,使用處理器堆棧並使用調用操作碼。這與將處理器堆棧上的下一個執行處理器指令指針一樣有效。除了返回地址之外,通常還會使用堆棧幀指針的值。 所以堆棧包含:
... free_space ... [local_variables] [framePtr] [returnAddr] PREVIOUS_STACK。

所以爲了改變返回地址(你應該知道它有多大 - 如果你通過-m64編譯它將有64位大小),你可以得到一個變量的地址並添加一些爲了到達返回指針的地址並改變它。 下面的代碼已經在m64模式下用g ++編譯。 如果它也適用於您,您可能會看到效果。

#include <stdio.h> 


void changeRetAddr(long* p){ 
    p-=2; 
    *p+=0x11; 
} 


void myTest(){ 
    long a=0x1122334455667788; 
    changeRetAddr(&a); 
    printf("hi my friend\n"); 
    printf("I didn't showed the salutation\n"); 
} 


int main(int argc, char **argv) 
{ 
    myTest(); 
    return 0; 
} 
+0

你從哪裏得到了神奇的數字? – DarthRubik

+0

通過彙編調試:-) –