2013-06-23 3 views
1

Я хочу вызвать системный вызов (prctl) в сборке inline и получить результат системного вызова. Но я не могу заставить его работать.встроенный ассемблер для вызова системного вызова и получения его результата

Это код, я использую:

int install_filter(void) 
{ 

    long int res =-1; 
    void *prg_ptr = NULL; 

    struct sock_filter filter[] = { 
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP), 
     /* If a trap is not generate, the application is killed */ 
     BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL), 
    }; 
    struct sock_fprog prog = { 
     .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), 
     .filter = filter, 
    }; 

    prg_ptr = &prog; 

    no_permis(); 

    __asm__ (
     "mov %1, %%rdx\n" 
     "mov $0x2, %%rsi \n" 
     "mov $0x16, %%rdi \n" 
     "mov $0x9d, %%rax\n" 
     "syscall\n" 
     "mov %%rax, %0\n" 
     : "=r"(res) 
     : "r"(prg_ptr)  
     : "%rdx", "%rsi", "%rdi", "%rax" 
     ); 

    if (res < 0){ 
    perror("prctl"); 
    exit(EXIT_FAILURE); 
    } 

    return 0; 
} 

Адрес фильтра должен быть вход (prg_ptr), и я хочу, чтобы сохранить результат в разрешении.

Вы можете мне помочь?

ответ

3

Для встроенной сборки вы не используете movs, как это, если вам не нужно, и даже тогда вам нужно сделать уродливое шиферование. . Это потому, что вы понятия не имеете, что регистрирующие аргументы прибывают в Вместо этого, вы должны использовать:

__asm__ __volatile__ ("syscall" : "=a"(res) : "d"(prg_ptr), "S"(0x2), "D"(0x16), "a"(0x9d) : "memory"); 

Я также добавил __volatile__, который вы должны использовать для любого ассемблера с другими побочными эффектами, чем его выход, и memory колошматить (барьер памяти), который вы должны использовать для любого asm с побочными эффектами в памяти или для которых переупорядочение по отношению к обращениям к памяти было бы недействительным. Хорошая практика всегда использовать оба эти параметра для системных вызовов, если вы не знаете, что они вам не нужны.

Если у вас по-прежнему возникают проблемы, используйте strace, чтобы увидеть попытку сбоя системы и посмотреть, что происходит.