2011-12-17 83 views
8

大家好,将shellcode声明为char []数组和char *之间的区别

我想学习基本的shellcoding,我跑过好奇的东西,我希望有人能向我解释。我用两种方法编译了下面的代码:将shellcode声明为数组和char *。当我将shellcode声明为一个数组时,linux检测到我正在尝试执行数据,并且在第一条指令中出现了段错误。但是,当我将shellcode声明为char *时,所有的shellcode都会执行,并且我得到一个“Hello world!”。编译器如何以不同的方式处理这两个声明,以及为什么一个终结于不受保护的内存中的shellcode?提前致谢。

#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)(); 
} 

回答

8

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

您可以在Linux上使用mprotect来设置Windows上的内存区域或VirtualProtectEx的权限。这样你可以明确地设置内存的权限是可执行的。

3

在你第一种情况:

char shellcode[] = 

这使串堆栈作为本地阵列上的文字。堆栈和堆内存通常没有执行权限(出于显而易见的安全原因)。

在你的第二个案例:

char* shellcode = 

串住在静态存储器 - 通常在同一区域作为程序二进制文件的其余部分 - 这是可执行文件。

相关问题