execve won't run executable assembly file

801 views Asked by At

I'm trying to create a c program that takes an executable and its arguments and runs them using execve, and then does some other stuff that shouldn't matter. The problem I'm having is that execve won't work when calling it on an exectuable assembly file. I think the problem is with my path because I can get the unix shell commands to work, but I can't get executables in the current directory (using ./spy ./executableName where spy is the name of my c program) to run. Here's the code:

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

There are 1 answers

2
alk On

From the source you posted it looks as if you were always prefixing the name passed as parameter with /bin/. So if the file isn't in /bin/ it can not be found, nor run.

Just change these two lines:

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

to be:

strcpy(filename,argv[1]);

Note that having applied this modification the program to be run needs to be specified with its full path.

So to run ls you need to do specfify /bin/ls as parameter to the program.


Some other comments:

So avoid buffer a overflow for long path/file names change:

char filename[50];

to be:

char filename[PATH_MAX];

To get more detailed information on why an execve() might have failed change:

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

to be:

if(execve(filename, arglist, (char*) 0) < 0)
  perror("execve() failed");

To detect a possible failure of forking do change:

pid = fork();

to become:

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