Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将外壳代码声明为char[]数组和char*?_C_Arrays_Pointers_Shellcode - Fatal编程技术网

将外壳代码声明为char[]数组和char*?

将外壳代码声明为char[]数组和char*?,c,arrays,pointers,shellcode,C,Arrays,Pointers,Shellcode,大家好 我正在努力学习基本的外壳编码,我遇到了一些奇怪的事情,希望有人能给我解释一下。我以两种方式编译了以下代码:将外壳代码声明为数组和char*。当我将外壳代码声明为数组时,linux检测到我正在尝试执行数据,并且在第一条指令上得到一个segfault。然而,当我将外壳代码声明为char*时,所有外壳代码都会执行,我会得到一个“helloworld!”。编译器如何以不同的方式处理这两个声明,为什么其中一个声明以外壳代码结束,而外壳代码位于不受保护的内存中?提前谢谢 #include <s

大家好

我正在努力学习基本的外壳编码,我遇到了一些奇怪的事情,希望有人能给我解释一下。我以两种方式编译了以下代码:将外壳代码声明为数组和char*。当我将外壳代码声明为数组时,linux检测到我正在尝试执行数据,并且在第一条指令上得到一个segfault。然而,当我将外壳代码声明为char*时,所有外壳代码都会执行,我会得到一个“helloworld!”。编译器如何以不同的方式处理这两个声明,为什么其中一个声明以外壳代码结束,而外壳代码位于不受保护的内存中?提前谢谢

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* This declaration ends in a segfault */
//char shellcode[] =

/* This declaration ends in successful execution */
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */    
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21";

int main()
{
    void (*f)();
    f = (void (*)())shellcode;
    (void)(*f)();
}
#包括
#包括
#包括
/*此声明以segfault结尾*/
//字符外壳代码[]=
/*此声明以成功执行结束*/
字符*外壳代码=
/*外壳代码打印“Hello world!”并退出*/
“\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\xc\xcd\x80\x48\x31\x48\x31\xdb\xcd\x80\x88\xdc\xfc\xf4\xfc\x45\x6c\x6c\x6f\x20\x62\x64\x61”;
int main()
{
无效(*f)();
f=(void(*)()外壳代码;
(无效)(*f)();
}

当您将其声明为
字符[]
时,内存位于堆栈上。当您将其声明为
char*
并为其分配字符串文字时,内存位于可执行映像本身中。Linux不喜欢在堆栈上执行代码,但可以在可执行映像的该部分执行内存。这是因为它试图避免某种类型的堆栈溢出攻击,人们可以使用一些任意指令使堆栈溢出,然后执行它们

您可以在Linux上使用设置内存区域或Windows上的权限。这样,您就可以显式地将内存的权限设置为可执行的。

在第一种情况下:

char shellcode[] =
这会将字符串文本作为本地数组放在堆栈上。堆栈和堆内存通常没有执行权限(出于明显的安全原因)

在第二种情况下:

char* shellcode = 
该字符串存在于静态内存中,通常与程序二进制文件的其余部分位于同一区域,该内存是可执行的