1

我在 x86_64 上写了一个示例代码,尝试动态执行 malloc 代码。有一个

程序收到信号 SIGSEGV,分段错误。0x0000000000601010 在?? ()

0x0000000000601010 是bin的位置,有人能说出为什么吗?谢谢!!

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/mman.h>
volatile int sum(int a,int b)
{
    return a+b;
}

int main(int argc, char **argv)
{
   char* bin = NULL;    
   unsigned int len = 0;
   int ret = 0;
   /*code_str is the compiled code for function sum.*/
   char code_str[] ={0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x89,
          0x75,0xf8,0x8b,0x45,0xf8,0x03,0x45,0xfc,0xc9,0xc3};
   len = sizeof(code_str)/sizeof(char);
   bin = (char*)malloc(len);
   memcpy(bin,code_str,len);
   mprotect(bin,len , PROT_EXEC | PROT_READ | PROT_WRITE);
   asm volatile ("mov $0x2,%%esi \n\t"
        "mov $0x8,%%edi \n\t"
        "mov %1,%%rbx \n\t"
        "call *%%rbx "
        :"=a"(ret)
        :"g"(bin)
        :"%rbx","%esi","%edi");

   printf("sum:%d\n",ret);
   return 0;
}
4

2 回答 2

2

千万不要在不检查系统函数返回的情况下做这样的伎俩。我的手册页mprotect特别说:

   POSIX  says  that  the  behavior of mprotect() is unspecified if it
   is applied to a region of memory that was not obtained via mmap(2).

所以不要对malloced 缓冲区这样做。

还:

  • 缓冲区大小只是sizeof(code_str),没有理由除以sizeof(char)(保证为 1,但这并不能使其正确)。
  • 没有必要强制返回malloc(或者mmap如果你改变它)。
  • code_strisunsigned char和 not的正确类型char
于 2012-08-05T06:51:15.020 回答
0

问题是 bin 地址应该与多个 PAGESIZE 对齐,否则 mprotect 将返回 -1,参数无效。

   bin = (char *)(((int) bin + PAGESIZE-1) & ~(PAGESIZE-1));//added....
   memcpy(bin,code_str,len);
   if(mprotect(bin, len , PROT_EXEC |PROT_READ | PROT_WRITE) == -1)
   {
     printf("mprotect error:%d\n",errno);
     return 0;
   }
于 2012-08-05T06:48:05.223 回答