poniedziałek, 26 stycznia 2015

Penetrujemy aplikacje napisane w języku C - narzedzie GDB cz.3

To już ostatni wpis do wstępu z narzędziem GDB. Wydaje mi się, że jest to wiedza po której można ta aplikacje dalej poznawać, bo jest ona naprawde duża.
Wracając do tematu, chciałbym się skupić na tym czy jesteśmy w stanie określić co znajduje się w adresie rip i takim oto sposobem omówię kilka instrukcji, by sprawdzić jak wygląda nasz kod maszynowy, który wcześniej był zapisany w aplikacji C.
 (gdb) x/10i $rip  
 =&gt; 0x400564 <main>:     movl  $0x0,-0x4(%rbp)  
   0x40056b <main>:     jmp  0x40057b <main>  
   0x40056d <main>:     mov  $0x400634,%edi  
   0x400572 <main>:     callq 0x400440 <puts plt="">  
   0x400577 <main>:     addl  $0x1,-0x4(%rbp)  
   0x40057b <main>:     cmpl  $0x9,-0x4(%rbp)  
   0x40057f <main>:     jle  0x40056d <main>  
   0x400581 <main>:     mov  $0x0,%eax  
   0x400586 <main>:     leaveq   
   0x400587 <main>:     retq    
 (gdb)   

Kod robi podwójny skok pamięci do instrukcji
 cmpl  $0x9,-0x4(%rbp)  

Jest to instrukcja porównawcza, która sprawdza czy warunek jest spełniony, jeśli wartości są mniejsze lub równe to jest ponowy skok do pamięci 0x40056d, a w przeciwnym wypadku idzie do kolejnej instrukcji. Nasŧepnie możemy wykonywać kolejne instrukcje i zauważyć, że w pewnym momęcie zobaczymy instrukcje puts.
 (gdb) nexti   
 0x000000000040056b     5          for(i = 0; i < 10; i++) {   
 (gdb) x/i %rip  
 A syntax error in expression, near `%rip'.  
 (gdb) x/i $rip  
 => 0x40056b <main+15>:     jmp  0x40057b <main+31>  
 (gdb) nexti   
 0x000000000040057b     5          for(i = 0; i < 10; i++) {   
 (gdb) x/i $rip  
 => 0x40057b <main+31>:     cmpl  $0x9,-0x4(%rbp)  
 (gdb) nexti   
 0x000000000040057f     5          for(i = 0; i < 10; i++) {   
 (gdb) x/i $rip  
 => 0x40057f <main+35>:     jle  0x40056d <main+17>  
 (gdb) nexti   
 6               puts("Hello, world!\n");   
 (gdb)   

Teraz sprawdzę na jaki adres pamięci wskazuje teraz program:
 (gdb) i r rip  
 rip      0x40056d     0x40056d <main+17>  
 (gdb) x/2i $rip  
 => 0x40056d <main+17>:     mov  $0x400634,%edi  
   0x400572 <main+22>:     callq 0x400440 <puts@plt>  
 (gdb)   

Ciekawe co kryje edi i mogę to spokojnie także podglądnąć:
 (gdb) i r edi  
 edi      0x1     1  
 (gdb) x/6cb $0x400634  
 Value can't be converted to integer.  
 (gdb) x/6cb 0x400634  
 0x400634:     72 'H'     101 'e'     108 'l'     108 'l'     111 'o'     44 ','  
 (gdb)   
Znalazłem Hello world, aby wygadało lepiej można wydrukować to tak:
 (gdb) x/12cb 0x400634  
 0x400634:     72 'H'     101 'e'     108 'l'     108 'l'     111 'o'     44 ','     32 ' '     119 'w'  
 0x40063c:     111 'o'     114 'r'     108 'l'     100 'd'  
GDB to wspaniałe narzędzie, gdzie ja nie pokazałem jego wszystkich możliwości i aby się lepiej go nauczyć, trzeba popatrzeć jak każda instrukcja wygląda po skompilowaniu na kod maszynowy - czyli życzę miłej zabawy, w analizowaniu programów napisanych w C. Nasŧepny post będzie omawiał wsŧep do projektu jaki z kumplami zaczynamy, a po jego zakończeniu powrócimy do C i może postaramy się zrobić jakiś nabzdurzyć pamięci.

Brak komentarzy:

Prześlij komentarz