C代码解释

3

请问有人能帮我解释下面这些代码吗?

char code[] = "paste your shellcode here";

int main(int argc, char **argv)
{
   int (*func)();
   func = (int (*)()) code;
   (int)(*func)();
}

注意:1. 在 C99 下它无法编译;2. 在最后一行中,将其转换为 int 是多余的,(*func)(); 就足够了。 - SomeWittyUsername
2个回答

5

在这里提供的代码是创建一个函数指针来调用任意数据片段的示例。

简单来说,我们会分配一个字节数组(char []),并将二进制shellcode负载粘贴到其中,通常是转义后的十六进制值。

这行代码:int (*func)();声明了一个函数指针,该指针将返回一个整数。这很典型,因为大多数代码都会返回基于整数的退出代码EAX。

这行代码:func = (int (*)()) code;将字节数组code强制转换为函数指针,并将其赋值给之前定义的函数指针“func”。

这行代码:(int)(*func)();实际上调用了shellcode,将执行转移到字节数组中的第一个内存位置。

这段代码非常有用。您不会期望它被用于攻击系统;相反,此代码用于测试、调试和实验开发中的shellcode。使用它,您可以简单地粘贴要测试的shellcode,然后执行它。这使您可以保持shellcode非常简单,不需要完整的独立可执行文件所需的所有典型要求,但仍能让您在不需要识别漏洞以利用的情况下测试它。通过这种方式,您就能知道代码是否有效,而不会被试图利用实际代码时出现的各种干扰所分散注意力。


谢谢David,但是为什么所有东西都被声明为指针?首先我们声明了函数指针而不是普通函数。其次,将数组作为另一个函数指针,然后将其分配给第一个函数指针!我只是对所有这些指针感到困惑 :) - Ahmed Taher
必须将其声明为函数指针的原因是因为我们不允许C创建函数前导/后导。相反,我们将(函数指针)指向内存中的任意位置(字节数组),并告诉编译器:“相信我,如果你跳转到那里,那里会有可执行代码。” - David Hoelzer
@DavidHoelzer 为什么我们不允许 C 创建新的 pro/epilog? - Volatile
请记住,此C代码旨在让您测试shellcode。我希望它能完全按照原样运行,不添加或更改任何内容。另外,即使我创建了一个实际的函数,我该如何将这个二进制有效载荷嵌入到该函数的主体中呢?最终,函数指针是必要的。使用内联汇编将一系列定义的字节链接在一起会感觉非常混乱。 - David Hoelzer
@DavidHoelzer 我本来想建议使用内联汇编,哈哈。不过我同意你的观点,但是为了讨论的目的,是否壳代码是否带有前/后奏真的很重要吗?除了明显的负载大小不必要增加之外。 - Volatile
显示剩余2条评论

1

实际上,我已经在从这篇文章中学习shell编码,并且需要理解它!所以我只是从那里复制过来的。 - Ahmed Taher
好的,我会在下一篇帖子中翻译! - Ahmed Taher
确实,这是一种逐行讨论的方式,但感觉有点模糊不清,介于几个群体之间。这似乎可以适用于这里、Stack Overflow或者逆向工程...只是我的个人意见。:) - David Hoelzer
很有道理。 :) 我知道当很难找到完美的发布问题的地方时,被拒绝提问是多么令人沮丧。 :) - David Hoelzer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接