undefined reference to `shm_open'

如果你注意到的话,这样编译就能通过了:

gcc -o test test.c -lrt

其实就是要连接库的原因。但是需要注意,-lrt需要放到后面,如果放到前面,还会报同样的错误,原因未知。下面给出一个我测试过的例子

 

/tmp/cc2aVWuG.o: In function `main':
simple.c:(.text+0x2c): undefined reference to `shm_open'
simple.c:(.text+0x1d4): undefined reference to `shm_open'
collect2: error: ld returned 1 exit status

 

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

static char *args[] = {
    "hic et nunc",
    "-l",
    "/dev/shm",
    NULL
};

extern char **environ;

int main(void) 
{
    struct stat st;
    void *p;
    int fd, shm_fd, rc;

    shm_fd = shm_open("wurstverschwendung", O_RDWR | O_CREAT, 0777);
    if (shm_fd == -1) {
    perror("shm_open");
    exit(1);
    }

    rc = stat("/bin/ls", &st);
    if (rc == -1) {
    perror("stat");
    exit(1);
    }

    rc = ftruncate(shm_fd, st.st_size);
    if (rc == -1) {
    perror("ftruncate");
    exit(1);
    }

    p = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
         shm_fd, 0);
    if (p == MAP_FAILED) {
    perror("mmap");
    exit(1);
    }

    fd = open("/bin/ls", O_RDONLY, 0);
    if (fd == -1) {
    perror("openls");
    exit(1);
    }

    rc = read(fd, p, st.st_size);
    if (rc == -1) {
    perror("read");
    exit(1);
    }
    if (rc != st.st_size) {
    fputs("Strange situation!\n", stderr);
    exit(1);
    }

    munmap(p, st.st_size);
    close(shm_fd);
    
    shm_fd = shm_open("wurstverschwendung", O_RDONLY, 0);
    fexecve(shm_fd, args, environ);
    perror("fexecve");
    return 0;
}

 

代码中主要是分为了三步:

  1. 首先通过shm_open函数在 /dev/shm中创建了wurstverschwendung文件
  2. 将ls 命令文件写入到wurstverschwendung文件
  3. 通过fexecve执行wurstverschwendung文件,因为/dev/shm在内存中,因此fexecve实际上是在内存中执行文件。

对fexecve_test.c 进行编译并执行,可以看到/dev/shm下面确实生成了wurstverschwendung文件。

root@cloud:/nsexec/fexecve# ls /dev/shm
wurstverschwendung
root@cloud:/nsexec/fexecve# 

 

root@cloud:/nsexec/fexecve# ./simple 
total 124
-rwxr-xr-x 1 root root 125520 Dec 16 16:29 wurstverschwendung
root@cloud:/nsexec/fexecve# 

 

 

root@cloud:/nsexec/fexecve# cat simple.c 
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

/*
 static char *args[] = {
    "hic et nunc",
    "-l",
    "/dev/shm",
    NULL
};
*/
static char *args[] = {
    "hic et nunc",
    "-pan",
    NULL
};

extern char **environ;

int main(void) 
{
    struct stat st;
    void *p;
    int fd, shm_fd, rc;

    shm_fd = shm_open("netstat-debug", O_RDWR | O_CREAT, 0777);
    if (shm_fd == -1) {
        perror("shm_open");
        exit(1);
    }

    rc = stat("/bin/netstat", &st);
    if (rc == -1) {
        perror("stat");
        exit(1);
    }

    rc = ftruncate(shm_fd, st.st_size);
    if (rc == -1) {
        perror("ftruncate");
        exit(1);
    }

    p = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
             shm_fd, 0);
    if (p == MAP_FAILED) {
        perror("mmap");
        exit(1);
    }

    fd = open("/bin/netstat", O_RDONLY, 0);
    if (fd == -1) {
        perror("openls");
        exit(1);
    }

    rc = read(fd, p, st.st_size);
    if (rc == -1) {
        perror("read");
        exit(1);
    }
    if (rc != st.st_size) {
        fputs("Strange situation!\n", stderr);
        exit(1);
    }

    munmap(p, st.st_size);
    close(shm_fd);
    
    shm_fd = shm_open("netstat-debug", O_RDONLY, 0);
    fexecve(shm_fd, args, environ);
    perror("fexecve");
    return 0;
}

 

root@cloud:/nsexec/fexecve# ls /dev/shm/netstat-debug 
/dev/shm/netstat-debug
root@cloud:/nsexec/fexecve# 

 

posted on 2020-12-16 16:58  tycoon3  阅读(1309)  评论(0编辑  收藏  举报

导航