2009-12-23 43 views
1

我想的execve調用在C程序一個shell:的execve調用

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

main() 
{ 
     char* path = "/bin/sh"; 
     int err = execve(path, &path, NULL); 
     printf("%d\n", err); 
     printf("%s\n", strerror(errno)); 
     printf("%x, %x\n", path, &path); 
} 

但是輸出是:

-1 
Bad address 
80485c0, bf816f4c 

回答

10

因爲你是不是發送NULL結束的參數列表。 您需要:

char* path[2]; 
path[0] = "/bin/sh"; 
path[1] = NULL; 
int err = execve(path[0], path, NULL); 
0

試試這個:如果程序是一個腳本,而不是一個進程鏡像文件

execl(path, path, NULL) 

的功能exec類會自動執行shell。所以你可以用腳本的路徑名代替「path」。

5

execve的第二個參數被定義爲以NULL結尾的字符串列表,因此您不能簡單地傳遞path的地址。該公司預計像這樣的數組,最後進入被空:

arg[0] = "/bin/ls" 
arg[1] = "-l" 
arg[2] = "/usr/include/std*" 
arg[3] = NULL 

這是一個壞的指針失敗的原因是execve就一直在看每一個字下面path找到論據,並且把每個字作爲指針,直到它到達第一個0字。由於path獨自一人在堆棧上,它將試圖解釋堆棧後發生在內存中的任何垃圾,超出path作爲字符串指針。

解決方案很簡單:您需要構造一個參數數組並添加一個NULL終結符(因爲它的長度可變)。固定的例子如下(有幾個警告照顧):

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    char* path[] = { "/bin/sh", NULL }; 

    int err = execve(path[0], path, NULL); 

    printf("%d\n", err); 
    printf("%s\n", strerror(errno)); 
    printf("%p, %p\n", path, &path); 

    return 0; 
}