Post

exec 계열 함수

1
2
3
4
5
6
7
#include <unistd.h>
int execl(const char \*path, const char \*arg1, arg2, ..., NULL);
int execlp(const char \*file, const char \*arg, arg2, ..., NULL);
int execle(const char \*path, const char \*arg, arg2, ..., char \* const envp[]);
int execv(const char \*path, char \*const argv[]);
int execvp(const char \*file, char \*const argv[]);
int execve(const char \*file, char \*const argv[], char \*const envp[]);

모든 exec* 함수는 execve 의 wrapper다. 이차원 배열로 넘기든, string을 나열해서 넘기든 마지막에는 반드시 NULL이 들어가야 한다.

exec*

char * arg / char * argv[] 와 char * envp[] 에 잘못된 값이 들어가는 경우 오류없이 실행 안될 수 있다. exec 계열을 실행 해도 fd는 유지된다. 단, close-on-exec flag가 지정되어 있는 경우는 close한다.

exec 한 다음 exit를 호출해 주는 코드가 있던데, 어차피 exec하고 나면 해당 파일을 자신의 메모리에 덮어쓰기 때문에 실행되다 알아서 종료된다. exec 이후에 적은 코드는 실행 안되니까, exec 오류일 경우만 exit등으로 예외처리만 해주면 된다.

인자에 char * path 라고 적혀있는 함수는 현재 디렉토리만 탐색 한다. 따라서 현재 디렉토리에 없는 파일은 절대 경로를 적어줘야 한다. 인자에 char * file 이라고 적혀있는 함수는 인자에 “/”가 포함되지 않은 경우 쉘이 파일을 탐색하는 방법과 동일한 방법으로 탐색 한다. “/”가 포함되어 있는 경우 명시된 path가 실행된다.

1
2
3
4
5
execl("test", NULL);    //된다
execlp("test", NULL);   //현재 path가 환경 변수에 있으면 된다
execlp("./test", NULL); //된다
execl("ps", NULL);      //안된다
execlp("ps", NULL);     //된다
execl* :

char * arg

  • char * arg 에 들어갈 수 있는 값은 NULL 또는 parameter 두 가지다. ( NULL pointer나 자기 자신이 아니다. )
  • OS에 따라 중간에 ebp를 lea 0x20(esp) ebp 하는 코드가 있는 경우가 있다. 이 경우 ebp값은 esp 주소 + 0x20이 될 수 밖에 없다.
execv* :

char * argv[]

  • char * argv[] 에는 기본적으로 앞에서 넘긴 * path || * file 과 동일한 값parameter가 들어있는 이차원 배열 을 넘겨야 하지만 parameter없이 실행할 경우 NULL 또는 NULL pointer 를 넣어도 돌아간다. 또한, 마지막에는 반드시 NULL이 있어야 한다.
  • char ** 이므로, \x00 하나만 있으면 앞의 \x00을 포함한 4byte 주소로 인식한다. 때문에 0을 넣으려면, 0x00000000 이어야 한다.
1
2
3
4
5
6
7
8
char \*cmd[3];
cmd[0] = "ls";
cmd[1] = "-l";
cmd[2] = NULL;

  

execve(cmd[0], cmd, env);
This post is licensed under CC BY 4.0 by the author.