2012-08-05 79 views
1

我在x86_64上編寫了一個示例代碼,嘗試執行dynamiclly malloc代碼。 有一個執行dynamiclly 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; 
} 
+1

你試過調試器嗎? – 2012-08-05 06:13:02

+0

是的,我用gdb。 – hellolwq 2012-08-05 06:17:35

+0

它給你一個錯誤代碼? – ChiefTwoPencils 2012-08-05 06:19:13

回答

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; 
    } 
+1

如果有問題的區域穿過頁面邊界,則無法正確設置兩個頁面的保護。 – 2012-08-05 07:10:20

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). 

所以不要做,與malloc編輯緩衝區。

另外:

  • 緩衝區的大小僅僅是sizeof(code_str),沒有理由通過sizeof(char)分(這是保證爲1,但是這並不能使它正確)。
  • 沒有必要投下malloc(如果將其更改爲)的回報。
  • code_str的正確類型是unsigned char而不是char
+0

謝謝!這是一個很好的幫助。 – hellolwq 2012-08-05 06:58:20

+0

不客氣。但是考慮到這一點,正如人們在評論中所說的那樣,主要的錯誤可能與'&bin'有關。 '0x0000000000601010'看起來不像'malloc'ed地址。 – 2012-08-05 07:02:28