2013-11-03 20 views
1

我有这样的功能:无法执行的Shellcode - >(Speicherzugriffsfehler(Speicherabzug geschrieben))

char code[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f"; 

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

(此代码是:shellcode tutorial

,所以我编译并执行它,但我只收到这条消息:Speicherzugriffsfehler(Speicherabzug geschrieben)。

为什么我不收回东西,只有这个错误信息?

p.s .:我的系统是一个Ubuntu x86电脑。 shellcode应该与它一起工作。我编译它与海湾合作委员会和gcc-4.5,两个相同的错误...

+0

根据谷歌翻译,该消息指出,一个核心被倾销。如果你能找到它,你可以使用GDB来查看出了什么问题。 ('gdb yourprogram some.core') – icktoofay

+1

您是否正在运行德语系统?否则会出现德国的错误是意想不到的,但大概你应该理解它......无论如何,这似乎不是一个真正的问题。 – Potatoswatter

+0

您是否已阅读教程主页上的FAQ#7和#10,并确保它们不会导致您的问题。 –

回答

2

默认情况下,gcc将编译应用程序具有不可执行的堆栈。你看到的是分段违规,因为你的堆栈被标记为不可执行,但你试图在堆栈上执行代码。您可以通过运行在gdb你的应用程序和检查验证它死了,例如:

=> 0x601060:JMP 0x60107b

这是你的shellcode的入口点。为了它,所以它不会出现段错误,您可以通过禁用exectstack如下:

GCC -z execstack由source.c

+1

这不是被跳转到的*堆栈,它是初始化数据段的一部分,与堆栈一样,它也是不可执行的。 –

+0

我的错误,你在这里是正确的。 :) – user12321

3

code变量是一个数组那是你的程序的初始化数据的一部分(.data )段。当您的程序被操作系统加载时,加载程序会从您的可执行文件中读取并执行加载命令。其中一个命令是“将以下数据(名为.data的段)加载到内存中”。

通常,.data段作为不可执行段加载,这意味着那里的内存不能执行。因此,如果您尝试通过跳转到其中执行代码(就像您那样执行代码),那么它会因分段错误而崩溃。

有几种方法可以解决这个问题。你可以告诉链接器使.data段可执行(不是一个好主意)。您可以告诉编译器将code变量放在.text段中(用于所有程序常规代码的段)。您可以告诉编译器和链接器创建一个新的可执行文件段,并将code添加到该文件中。所有这些都很棘手。

最好的解决方案是在运行时专门分配您自己的可执行内存并将shellcode复制到该代码中。这完全避免了任何潜在的编译器/链接器问题,尽管它确实增加了一个小的运行时间损失。但有些操作系统不允许内存同时可写和可执行;所以你首先必须使它可写,复制shellcode,然后使其可执行。

您在运行时控制内存权限的方式是mprotect(2) call。因此,这是一个很好的方法:

#include <string.h> 
#include <sys/mman.h> 

char shellcode[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f"; 

// Error checking omitted for expository purposes 
int main(int argc, char **argv) 
{ 
    // Allocate some read-write memory 
    void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 

    // Copy the shellcode into the new memory 
    memcpy(mem, shellcode, sizeof(shellcode)); 

    // Make the memory read-execute 
    mprotect(mem, sizeof(shellcode), PROT_READ|PROT_EXEC); 

    // Call the shellcode 
    int (*func)(); 
    func = (int (*)())mem; 
    (int)(*func)(); 

    // Now, if we managed to return here, it would be prudent to clean up the memory: 
    munmap(mem, sizeof(shellcode)); 

    return 0; 
}