【发布时间】:2013-05-13 16:09:39
【问题描述】:
在Demystifying the Execve Shellcode 中解释了一种编写 execve shellcode 的方法:
#include<stdio.h>
#include<string.h>
unsigned char code[] =
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
int (*ret)() = (int(*)())code; 行有什么作用?
【问题讨论】:
-
cdecl 说:将代码转换为指向返回 int 的函数的指针
-
我不明白 ret 之后的 () 和 code 之前的 int()()。
-
为了能够在头部解析这样的结构,通过顺时针/螺旋规则:c-faq.com/decl/spiral.anderson.html
-
顺便说一句:在 W^X 操作系统上默认禁用此方法。在现代处理器上的 64 位 OS X 上运行
nop (0x90),EXC_BAD_ACCESS因为内核不会从 .bss、.text 或堆中运行任何代码,因为这些区域引用了 o PAE/长模式页表条目位 63 设置 (NX)。它可能适用于非 PAE/非长模式操作系统,而无需像 DOS 这样古老的东西中的 PAX/ExecShield。写入代码区域也不起作用(在一堆 C 内联 asmnops 上自我变异)。最好制作一个为给定平台生成最小可执行文件并运行它的程序。