1

我想在汇编内联中调用系统调用(prctl)并检索系统调用的结果。但我不能让它工作。

这是我正在使用的代码:

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),我想将结果保存在res中。

你能帮助我吗?

4

1 回答 1

4

对于内联汇编,除非必须,否则不要使用这样的 mov,即使那样,您也必须进行丑陋的 shiffling。那是因为您不知道哪些寄存器参数到达。相反,您应该使用:

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

我还添加了__volatile__,您应该将其用于任何具有除输出以外的副作用的 asm 和一个memoryclobber(内存屏障),您应该将其用于任何对内存有副作用或对其重新排序的 asm 关于内存访问将是无效的。除非您知道不需要它们,否则始终将这两种方法都用于系统调用是一种很好的做法。

如果您仍然遇到问题,请使用strace观察系统调用尝试并查看发生了什么问题。

于 2013-06-23T13:15:07.513 回答