2015-05-11 63 views
0

我正在尝试编写一个C程序来演示写入堆栈的不同区域以在运行时更改程序的执行。在Fedora 21中启用堆栈碎片

我有这样的程序:

#include<stdio.h> 

int* useless_function (int x) { 
    int* somewhere_in_the_stack = &x; 
    int* another_place = &x + 5; 
    return (int*)((long int)(*another_place)) - 3; 
} 
int main() { 
    int step = 3; 
    int* q = useless_function(50); 
    printf("%d %d\n",&step,q); 
    //printf("%d %d\n",&step,*q); 
} 

试图做到这一点。基本上,useless_function返回堆栈主函数中局部变量'step'的地址。当我在我的机器上编译和执行程序时printf为'step'和'q'输出相同的确切内存地址,但是当我尝试遵守'q'时,在注释掉的行中出现了分段错误。但是,我可以*(&步)没有段错误。

我试着用这个选项'-fno-stack-protector'进行编译,但没有奏效。

+0

请详细说明您的问题。 –

+0

你应该查看C ABI,因为x将在一个寄存器中,而不是在堆栈上! –

+0

我的问题是我无法解引用指针q。在函数main&step中的第3行等于q。我可以解除引导和步骤,但不能q。 –

回答

0

这完全不正确,但可能在32位平台上工作。

#include<stdio.h> 

int* useless_function (int x) { 
    int* somewhere_in_the_stack = &x; 
    int* another_place = &x + 5; 

指向int的指针。

return (int*)((long int)(*another_place)) - 3; 

因此(* another_place)是一个int。然后你把它投给long int。如果地址不适合int(通常不会),那么你的就会丢失的一部分。然后结果是符号扩展。你会看到....

} 
int main() { 
    int step = 3; 
    int* q = useless_function(50); 
    printf("%d %d\n",&step,q); 

你会看到截断,如果你使用正确的格式说明符(%P)。有趣的是,gcc甚至在没有-Wall的情况下警告了这个问题,所以我更加困惑的是,为什么在解决报告问题之前提出这个问题。最后,一个有趣的事实是printf(“%p \ n”,指针);触发未定义的行为,除非指针的类型是char *或void *。