ASSEMBLER MALIZIOSO

Quanti di voi si sono mai chiesti cos'è una sistem call in realtà?
Facciamo un esempio pratico per andarlo a capire a fondo:

bakunin: ~/C$ cat "int main(void) {fork();}" > a.c
bakunin: ~/C$ cc a.c
bakunin: ~/C$ cc a.c -ggdb
bakunin: ~/C$ gdb a.out
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) disassemble main
Dump of assembler code for function main:
0x8048400 <main>:       push   %ebp
0x8048401 <main+1>:     mov    %esp,%ebp
0x8048403 <main+3>:     sub    $0x8,%esp
0x8048406 <main+6>:     call   0x80482e0 <fork>
0x804840b <main+11>:    mov    %ebp,%esp
0x804840d <main+13>:    pop    %ebp
0x804840e <main+14>:    ret
End of assembler dump.
(gdb) disassemble fork
Dump of assembler code for function fork:
0x80482e0 <fork>:       jmp    *0x80495a4
0x80482e6 <fork+6>:     push   $0x8
0x80482eb <fork+11>:    jmp    0x80482c0 <_init+40>
End of assembler dump.
(gdb)

Il magico lavoro del linker. Non possiamo arrivare a quell'indirizzo in 
maniera troppo semplice. Il modo migliore per risolvere il problema è
compilare in maniera statica il programma di prima.

Spiego meglio: quando si compila un programma, tutte le funzioni come
printf, fork, qualsiasi in somma che noi non creiamo, sono prese dalle glibc.
Queste glibc possiedono tutto quel codice che permette la esecuzione della
fork e della printf. In particolare questo codice non viene messo all'interno
del nostro programma per economia di spazio, ma viene richiamato quando
serve attraverso a jmp (salti) in librerie condifise.

Questo obbrobrio di spiegazione serve a spiegare questo comando:

bakunin: ~/C$ cc a.c -ggdb -static

Con l'opzione static imponiamo che tutto il codice venga messo all'interno del
nostro software. Le dimensioni ovviamente aumentano.
bakunin: ~/C$ gdb a.out
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
(gdb) disassemble main
Dump of assembler code for function main:
0x80481d0 <main>:       push   %ebp
0x80481d1 <main+1>:     mov    %esp,%ebp
0x80481d3 <main+3>:     sub    $0x8,%esp
0x80481d6 <main+6>:     call   0x804bfc0 <fork>
0x80481db <main+11>:    mov    %ebp,%esp
0x80481dd <main+13>:    pop    %ebp
0x80481de <main+14>:    ret
End of assembler dump.
(gdb)

Uguale a prima. Ora la fork:
(gdb) disassemble fork
Dump of assembler code for function fork:
0x804bfc0 <fork>:       mov    $0x2,%eax
0x804bfc5 <fork+5>:     int    $0x80
0x804bfc7 <fork+7>:     cmp    $0xfffff001,%eax
0x804bfcc <fork+12>:    jae    0x80519d0 <__syscall_error>
0x804bfd2 <fork+18>:    ret
0x804bfd3 <fork+19>:    lea    0x0(%esi),%esi
0x804bfd9 <fork+25>:    lea    0x0(%edi,1),%edi
End of assembler dump.
(gdb)

Molto più interessante. Abbiamo trovato come funziona la fork:

mov    $0x2,%eax
int    $0x80

Siamo sicuri?

int main(void) {
asm("
mov    $0x2,%eax
int    $0x80
");
sleep(2000);
}

bakunin: ~/C$ ./a.out & ps aux | grep a.out
[1] 1162
bakunin   1162  0.0  0.2  1316  296 tty2     S    22:03   0:00 ./a.out
bakunin   1165  0.0  0.2  1316  296 tty2     S    22:03   0:00 ./a.out
bakunin: ~/C$

Esatto.
L'interrupt 0x80, gestisce le syscall del kernel di unix. Mettendo valori 
dentro al registro %eax possiamo lanciare le chiamate di sistema come noi
vogliamo.

Implementiamo un for:

int main(void) {
asm("
mov    $0x2,%eax
int    $0x80
jmp    .-7
");
}

Ed ecco un esempio di Assembler dentro il C. Il jmp di -7 byte ritorna 
esattamente al mov. Si poteva saltare anche solo a -2. Come si fa a sapere i
salti?

bakunin: ~/C$ cc a.c -ggdb
bakunin: ~/C$ gdb a.out
GNU gdb 5.2
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb)
(gdb) disassemble main
Dump of assembler code for function main:
0x80483d0 <main>:       push   %ebp
0x80483d1 <main+1>:     mov    %esp,%ebp
0x80483d3 <main+3>:     mov    $0x2,%eax
0x80483d8 <main+8>:     int    $0x80
0x80483da <main+10>:    jmp    0x80483d8 <main+8>
0x80483dc <main+12>:    mov    %ebp,%esp
0x80483de <main+14>:    pop    %ebp
0x80483df <main+15>:    ret
End of assembler dump.
(gdb)

