简体   繁体   English

将shellcode声明为char []数组和char *之间的区别?

[英]Difference between declaring shellcode as a char[] array and char*?

Hi all, 大家好,

I'm trying to learn basic shellcoding and I've run across something curious that I hope someone can explain to me. 我正在尝试学习基本的shell编码,我遇到了一些奇怪的事情,我希望有人可以向我解释。 I've compiled the following code two ways: declaring the shellcode as an array and as a char*. 我已经用两种方式编译了以下代码:将shellcode声明为数组并将其声明为char *。 When I declare shellcode as an array, linux detects that I am trying to execute data and I get a segfault on the first instruction. 当我将shellcode声明为数组时,linux检测到我正在尝试执行数据,并且我在第一条指令上遇到了段错误。 However, when I declare shellcode as a char* all of the shellcode executes and I get a "Hello world!". 但是,当我将shellcode声明为char *时,所有shellcode都会执行,并且我得到一个“Hello world!”。 How does the compiler treat these two declarations differently and why does one end in shellcode that lives in memory that is unprotected? 编译器如何以不同的方式处理这两个声明,为什么一个以shellcode结尾,它存在于不受保护的内存中? Thanks in advance. 提前致谢。

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

When you declare it as a char[] , the memory is on the stack. 当您将其声明为char[] ,内存位于堆栈中。 When you declare it as a char* and assign it a string literal, the memory is in the executable image itself. 当您将其声明为char*并为其指定字符串文字时,内存位于可执行映像本身中。 Linux doesn't like you executing code on the stack, but is fine with you executing memory in that part of the executable image. Linux不喜欢你在堆栈上执行代码,但是你可以在可执行映像的那部分执行内存。 That is because it is trying to avoid a certain type of stack overflow attack where people can overflow the stack with some arbitrary instructions and then execute them. 这是因为它试图避免某种类型的堆栈溢出攻击,其中人们可以使用一些任意指令溢出堆栈然后执行它们。

You can use mprotect on Linux to set the permissions for a region of memory or VirtualProtectEx on Windows. 您可以在Linux上使用mprotect在Windows上设置内存区域或VirtualProtectEx的权限。 That way you can explicitly set the permissions of the memory to be executable. 这样,您可以显式设置内存的权限以使其可执行。

In your first case: 在你的第一个案例中:

char shellcode[] =

This puts the string literal on the stack as a local array. 这会将字符串文字放在堆栈上作为本地数组。 The stack and heap memory usually does not have execute permissions (for obvious reasons of security). 堆栈和堆内存通常没有执行权限(出于明显的安全原因)。

In your second case: 在你的第二种情况:

char* shellcode = 

The string lives in static memory - typically in the same region as the rest of the program binary - which is executable. 该字符串存在于静态内存中 - 通常与程序二进制文件的其余部分位于同一区域 - 这是可执行的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM