Linux kernel 3.2 syscalls [fechado]

1

Apenas tentando obter as instruções do assembler para < __ execve > do código abaixo, porque eu quero construir a lista de opcode spawn:

#include <stdio.h>
int main()
{
     char *happy[2];
     happy[0] = "/bin/sh";
     happy[1] = NULL;
     execve (happy[0], happy, NULL);
}

Objdump me dá isso:

8053a20:    53                      push   %ebx
8053a21:    8b 54 24 10             mov    0x10(%esp),%edx
8053a25:    8b 4c 24 0c             mov    0xc(%esp),%ecx
8053a29:    8b 5c 24 08             mov    0x8(%esp),%ebx
8053a2d:    b8 0b 00 00 00          mov    $0xb,%eax
8053a32:    ff 15 a4 d5 0e 08       call   *0x80ed5a4
8053a38:    3d 00 f0 ff ff          cmp    $0xfffff000,%eax
8053a3d:    77 02                   ja     8053a41 <__execve+0x21>
8053a3f:    5b                      pop    %ebx
8053a40:    c3                      ret    
8053a41:    c7 c2 e8 ff ff ff       mov    $0xffffffe8,%edx
8053a47:    f7 d8                   neg    %eax
8053a49:    65 8b 0d 00 00 00 00    mov    %gs:0x0,%ecx
8053a50:    89 04 11                mov    %eax,(%ecx,%edx,1)
8053a53:    83 c8 ff                or     $0xffffffff,%eax
8053a56:    5b                      pop    %ebx
8053a57:    c3                      ret    
8053a58:    90                      nop
8053a59:    90                      nop
8053a5a:    90                      nop

De vários textos que li, era suposto ser um int 0x80 em algum lugar na saída acima. Por que não há um?

Há alguma mudança importante no kernel 3.2 sobre como o syscalls funciona que pode afetar os algoritmos de construção de código de shell (cargas de registro específicas, etc) que são apresentadas em livros escritos de 3 a 4 anos atrás? O despejo acima parece muito diferente da saída apresentada no "Manual do Shellcoders" ou "Quebra a pilha"

Obrigado!

    
por kawa 20.01.2013 / 11:42

1 resposta

1

A implementação do syscall depende do hardware (pesadamente) - veja o artigo da wikipedia sobre syscalls e o artigo sobre kerneltrap . No x86 moderno, parece que int 0x80 foi abandonado em favor dos mais novos SYSENTER et al há algum tempo .

Para mim, __execve é assim:

000000000040f7c0 <__execve>:
  40f7c0:    b8 3b 00 00 00          mov    $0x3b,%eax
  40f7c5:    0f 05                   syscall 
  40f7c7:    48 3d 00 f0 ff ff       cmp    $0xfffffffffffff000,%rax
  40f7cd:    77 02                   ja     40f7d1 <__execve+0x11>
  40f7cf:    f3 c3                   repz retq 
  40f7d1:    48 c7 c2 c0 ff ff ff    mov    $0xffffffffffffffc0,%rdx
  40f7d8:    f7 d8                   neg    %eax
  40f7da:    64 89 02                mov    %eax,%fs:(%rdx)
  40f7dd:    48 83 c8 ff             or     $0xffffffffffffffff,%rax
  40f7e1:    c3                      retq   
  40f7e2:    66 90                   xchg   %ax,%ax
  40f7e4:    66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  40f7eb:    00 00 00 
  40f7ee:    66 90                   xchg   %ax,%ax

Observe o syscall no começo. A forma exata da função depende dos sinalizadores de compilação e da arquitetura para a qual o código é compilado - consulte as opções gcc -mtune e -march .

EDITAR: links adicionais interessantes:

por 20.01.2013 / 12:35