Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Exeve赢得';t运行可执行程序集文件_C_Exec_Execve - Fatal编程技术网

C Exeve赢得';t运行可执行程序集文件

C Exeve赢得';t运行可执行程序集文件,c,exec,execve,C,Exec,Execve,我正在尝试创建一个c程序,它接受一个可执行文件及其参数,并使用execve运行它们,然后执行一些其他不重要的事情。我遇到的问题是,在可执行程序集文件上调用execve时,execve将无法工作。我认为问题出在我的路径上,因为我可以让unixshell命令工作,但我无法让当前目录中的可执行文件(使用./spy./executableName,其中spy是我的c程序名)运行。代码如下: #include <stdio.h> #include <stdlib.h> #inclu

我正在尝试创建一个c程序,它接受一个可执行文件及其参数,并使用execve运行它们,然后执行一些其他不重要的事情。我遇到的问题是,在可执行程序集文件上调用execve时,execve将无法工作。我认为问题出在我的路径上,因为我可以让unixshell命令工作,但我无法让当前目录中的可执行文件(使用./spy./executableName,其中spy是我的c程序名)运行。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

extern char **environ;

int main(int argc, char* const argv[]) {
    pid_t pid;
    char filename[50];
    char* arglist[argc];
    int i = 1,count = 0;
    int status;

    strcpy(filename, "/bin/");
    strcat(filename,argv[1]);
    for(i = 1; i< argc; i++)
        arglist[i-1] = argv[i];
    arglist[argc-1] = 0;
    arglist[0] = filename;
    if (argc == 1) {
        fprintf(stderr,"usage : %s <prog> ...\n",argv[0]);
        return -1;
    }
    pid = fork();
    if(pid == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        if(execve(filename, arglist, 0) < 0)
            fprintf(stdout,"Invalid file.");
    }
    else {
        while(1) {
            waitpid(pid,&status,0);
            if (WIFEXITED(status))
                break;
            ptrace(PTRACE_SINGLESTEP, pid,NULL, NULL);
            count++;
        }
    }
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
外部字符**环境;
int main(int argc,char*const argv[]{
pid_t pid;
字符文件名[50];
字符*arglist[argc];
整数i=1,计数=0;
智力状态;
strcpy(文件名“/bin/”);
strcat(文件名,argv[1]);
对于(i=1;i
从您发布的源代码看,似乎总是在作为参数传递的名称前面加上
/bin/
。因此,如果文件不在
/bin/
中,则无法找到它,也无法运行它

只需更改这两行:

strcpy(filename, "/bin/");
strcat(filename,argv[1]);
将是:

strcpy(filename,argv[1]);
char filename[PATH_MAX];
if(execve(filename, arglist, (char*) 0) < 0)
  perror("execve() failed");
注意应用此修改后,需要指定要运行的程序的完整路径

因此,要运行
ls
,您需要将specfify
/bin/ls
作为程序的参数


其他一些评论:

因此,避免长路径/文件名更改导致缓冲区溢出:

char filename[50];
将是:

strcpy(filename,argv[1]);
char filename[PATH_MAX];
if(execve(filename, arglist, (char*) 0) < 0)
  perror("execve() failed");
要获取有关
execve()
更改失败原因的详细信息,请执行以下操作:

if(execve(filename, arglist, 0) < 0)
  fprintf(stdout,"Invalid file.");
成为:

if (-1 == (pid = fork())) then
{
  perror("fork() failed");
}
else

欢迎来到堆栈溢出。请尽快阅读这一页。可以从shell运行可执行程序集文件吗?如果不是,则问题出在可执行程序集文件中。如果是这样,您还应该能够从代码中执行它。您可以从您的程序运行其他程序(如
ls
)吗?归根结底,每个程序(shell,
ls
,由您命名)都是由汇编代码生成的。从您发布的源代码来看,似乎您总是在作为参数传递的名称前面加上
/bin/
。因此,如果文件不在
/bin/
中,则无法找到它,也无法运行。感谢您的欢迎!我已经能够运行可执行程序集文件,并且可以从我的程序中运行ls和其他程序,如cd和grep。我认为问题完全是关于我的文件路径或环境变量,但我已经把头撞在墙上有一段时间了,我想不出来。还有@alk,我试着不在它前面加/bin/。当我这样做时,两个文件都不会运行。我知道这不是正确的方法,但我只是对如何使用Exeve处理文件系统中的程序位置感到困惑。您认为我应该怎么做?我做了您列出的所有更改(除了PATHMAX,我应该导入什么来获取该变量),但仍然失败。这与我之前的版本类似,但我喜欢更具描述性的错误消息。我现在从perror得到一个错误(“execve()失败”);表示execve()失败的行:没有这样的文件或目录。而且,我的代码现在在ls、cd和grep上失败了(预期)。我没有在/bin/前缀中进行硬编码,这样才有意义。@user2756569:Sry,这是一个输入错误,它是
PATH\u MAX
。您需要指定要运行的程序,包括其路径。请看我回答中关于这一点的注释。