为什么将“extern puts”转换为函数指针“(void(*)(char *))& puts”?

时间:2011-02-19 16:30:43

标签: c casting function-pointers void shellcode

我正在查看来自abo3.c的示例Insecure Programming,而我并未在下面的示例中讨论转换。有人可以启发我吗?

int main(int argv,char **argc)   
{  
    extern system,puts;  
    void (*fn)(char*)=(void(*)(char*))&system;  
    char buf[256];  

    fn=(void(*)(char*))&puts;  
    strcpy(buf,argc[1]);  
    fn(argc[2]);  
    exit(1);  
}

那么 - 系统投射和投注是什么?他们都返回int所以为什么要把它变成无效?

我非常感谢对整个计划的解释,以便对其进行透视。

[编辑]
谢谢你们的投入!

Jonathan Leffler,实际上代码有“坏”的原因。它应该是可利用的,溢出缓冲区和函数指针等。mishou.org有一篇关于如何利用上述代码的博客文章。其中很多仍然在我头上。

bta,我从上面的博客文章中得知,转换系统会以某种方式阻止链接器删除它。

  

有一点不能立即明确的是系统和放置地址都写在同一个位置,我想这可能是gera所说的“因此链接器不会删除它”。

虽然我们讨论的是函数指针的主题,但现在我想问一个后续问题,即语法更清晰。我正在使用函数指针查看一些更高级的示例,并偶然发现这个可憎的东西,取自托管shellcode的站点。

#include <stdio.h>

char shellcode[] = "some shellcode";

int main(void)
{
    fprintf(stdout,"Length: %d\n",strlen(shellcode));
    (*(void(*)()) shellcode)();
}

所以数组被强制转换为返回void的函数,被引用和调用?这看起来很讨厌 - 那么上面代码的目的是什么?

[/编辑]

2 个答案:

答案 0 :(得分:10)

答案 1 :(得分:4)

systemputs通常都会返回int。代码将它们转换为返回void的指针,可能是因为他们想要忽略返回的任何值。这应该相当于使用(void)fn(argc[2]);作为倒数第二行,如果强制转换没有改变返回类型。有时会为回调函数抛弃返回类型,而这段代码片段似乎是回调的一个简单示例。

为什么system的演员如果永远不会被使用超出我的范围。我假设这里没有显示更多的代码。