首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法执行Shellcode -> (Speicherzugriffsfehler (Speicherabzug geschrieben))

无法执行Shellcode -> (Speicherzugriffsfehler (Speicherabzug geschrieben))
EN

Stack Overflow用户
提问于 2013-11-03 02:24:10
回答 2查看 7.6K关注 0票数 1

我的职能是:

代码语言:javascript
复制
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)();
}

(此代码来自:外壳代码教程)

所以我编译并执行了它,但是我只得到了以下消息: Speicherzugriffsfehler (Speicherabzug geschrieben)。

为什么我没有得到什么,只有这条错误信息?

我的系统是一台ubuntu x86个人电脑。外壳代码应该与它一起工作。我用gcc和gcc-4.5编译了,两个错误都是一样的.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-03 03:25:38

默认情况下,gcc将将应用程序编译为具有不可执行堆栈。您所看到的是分段冲突,因为您的堆栈被标记为不可执行,但是您试图在堆栈上执行代码。您可以通过在gdb中运行应用程序并检查其死在何处进行验证,例如:

=> 0x601060 : jmp 0x60107b

这是你的外壳代码的入口点。要使其不发生分段错误,可以通过以下操作禁用exect堆栈:

gcc -z外挂栈源

票数 2
EN

Stack Overflow用户

发布于 2013-11-03 03:55:38

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

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

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

最好的解决方案是在运行时专门分配自己的可执行内存,并将外壳代码复制到其中。这完全避免了任何潜在的编译器/链接器问题,尽管它确实增加了一个较小的运行时代价。但有些OSes不允许内存同时具有可写性和可执行性;因此,首先必须使其可写,复制外壳代码,然后使其可执行。

您在运行时控制内存权限的方式是使用打电话。所以这里有个很好的方法

代码语言:javascript
复制
#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;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19749206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档