kernel Linux 3.2 syscalls

2

Sto solo provando a ottenere le istruzioni dell'assemblatore per < __ execve > del codice qui sotto perché voglio creare l'elenco di codici di accesso spawn della shell:

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

Objdump mi dà questo:

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

Da diversi testi che ho letto ci dovrebbe essere un int 0x80 da qualche parte nell'output di cui sopra. Perché non c'è uno?

Ci sono cambiamenti importanti nel kernel 3.2 riguardo al funzionamento di syscalls che potrebbero influenzare gli algoritmi di costruzione del shellcode (carichi di registro specifici, ecc.) presentati in libri scritti 3-4 anni fa? Il dump di cui sopra sembra molto diverso dall'output presentato in "Shellcoders Handbook" o "Smash the Stack"

Grazie!

    
posta kawa 20.01.2013 - 10:42
fonte

2 risposte

3

Gli interrupt hanno sostanziali overhead delle prestazioni, linux si è spostato su syscall / sysenter su x86 dove supportato. La pseudo-dll VDSO "linux-gate.so" (che ldd mostrerà) rende la chiamata più veloce specifica della piattaforma, puoi leggere di più qui:

  • link (Cosa c'è di meglio "int 0x80" o "syscall"?)
  • link (Come richiamare una chiamata di sistema tramite sysenter in assembly inline (x86 / amd64 linux)?)
  • link (Linux 2.5 ottiene vsyscalls, supporto sysenter)

Il codice che utilizza 0x80 continuerà a funzionare, sebbene le versioni attuali di glibc non utilizzeranno quel metodo su piattaforme x86 e kernel Linux moderni.

    
risposta data 20.01.2013 - 16:04
fonte
0

Quando si scrive codice C e si chiama una "funzione chiamata di sistema" come execve() , in realtà non si entra direttamente nel kernel; chiami una funzione nella libreria C standard, che fa il salto nel kernel (il int 0x80 ). In questo modo, il compilatore C non deve sapere nulla sulla convenzione di chiamata del kernel, e ciò consente modifiche nel tempo (ad es. Sostituire una chiamata di sistema con una migliore, con un'API distinta: la libc deve essere modificata, non le applicazioni ).

Per effettuare una chiamata di sistema diretta, devi ricorrere a scrivere da solo. Potresti dare un'occhiata al codice sorgente di libc per l'orientamento.

    
risposta data 20.01.2013 - 15:28
fonte

Leggi altre domande sui tag