X64 - ramka stosu i zmienne lokalne.

0
 
void dodaj() {
   char tab[4];
   tab[0] = 1;
   tab[1] = 2;
   tab[2] = 3;
   tab[3] = 4;
   tab[4] = 5;
   tab[6] = 6;
   tab[7] = 7;
   tab[8] = 8;
   tab[9] = 9;
   tab[10] = 10;
   tab[11] = 11;
   tab[12] = 12;
   tab[13] = 13;
   tab[14] = 14;
   tab[15] = 15;
   tab[16] = 16;
   tab[17] = 17;
   tab[18] = 18;
   tab[19] = 19;
   tab[20] = 20;
   tab[21] = 21;
   tab[22] = 22;
   tab[23] = 23;
   tab[24] = 24;
   tab[25] = 25;
   tab[26] = 26;                                                                
}

int main() {
      dodaj();
   return 0;
}

(gdb) disas main
Dump of assembler code for function main:
0x000000000040074e <+0>: push %rbp
0x000000000040074f <+1>: mov %rsp,%rbp
0x0000000000400752 <+4>: callq 0x4006e0 <_Z5dodajv>
0x0000000000400757 <+9>: mov $0x0,%eax
0x000000000040075c <+14>: pop %rbp
0x000000000040075d <+15>: retq
End of assembler dump.
(gdb) disas dodaj
Dump of assembler code for function _Z5dodajv:
0x00000000004006e0 <+0>: push %rbp
0x00000000004006e1 <+1>: mov %rsp,%rbp
0x00000000004006e4 <+4>: movb $0x1,-0x10(%rbp) <--- tab[0]
0x00000000004006e8 <+8>: movb $0x2,-0xf(%rbp) <--- tab[1]
0x00000000004006ec <+12>: movb $0x3,-0xe(%rbp) <--- tab[2]
0x00000000004006f0 <+16>: movb $0x4,-0xd(%rbp) <--- tab[3]
0x00000000004006f4 <+20>: movb $0x5,-0xc(%rbp) <--????????
0x00000000004006f8 <+24>: movb $0x6,-0xa(%rbp) <--????????
0x00000000004006fc <+28>: movb $0x7,-0x9(%rbp) <--????????
0x0000000000400700 <+32>: movb $0x8,-0x8(%rbp) <--????????
0x0000000000400704 <+36>: movb $0x9,-0x7(%rbp) <--????????
0x0000000000400708 <+40>: movb $0xa,-0x6(%rbp) <--????????
0x000000000040070c <+44>: movb $0xb,-0x5(%rbp) <--????????
0x0000000000400710 <+48>: movb $0xc,-0x4(%rbp) <--????????
0x0000000000400714 <+52>: movb $0xd,-0x3(%rbp) <--????????
0x0000000000400718 <+56>: movb $0xe,-0x2(%rbp) <--????????
0x000000000040071c <+60>: movb $0xf,-0x1(%rbp) <--????????
0x0000000000400720 <+64>: movb $0x10,0x0(%rbp) <---ebp
0x0000000000400724 <+68>: movb $0x11,0x1(%rbp) <---ebp
0x0000000000400728 <+72>: movb $0x12,0x2(%rbp) <---ebp
0x000000000040072c <+76>: movb $0x13,0x3(%rbp) <---ebp
0x0000000000400730 <+80>: movb $0x14,0x4(%rbp) <---ebp
0x0000000000400734 <+84>: movb $0x15,0x5(%rbp) <---ebp
0x0000000000400738 <+88>: movb $0x16,0x6(%rbp) <---ebp
0x000000000040073c <+92>: movb $0x17,0x7(%rbp) <---ebp
0x0000000000400740 <+96>: movb $0x18,0x8(%rbp) <---adres powrotu
0x0000000000400744 <+100>: movb $0x19,0x9(%rbp) <---adres powrotu
0x0000000000400748 <+104>: movb $0x1a,0xa(%rbp) <---adres powrotu
0x000000000040074c <+108>: pop %rbp
0x000000000040074d <+109>: retq
End of assembler dump.

Potrafi mi ktoś powiedzieć/wyjaśnić co to za przestrzeń oznaczona znakami zapytania ??
Kompilacja z Fedory jak coś

0

Drobne poprawki - oczywiście nie ebp tylko rbp i w notacji intela:

Dump of assembler code for function _Z5dodajv:
0x00000000004006e0 <+0>: push rbp
0x00000000004006e1 <+1>: mov rbp,rsp
0x00000000004006e4 <+4>: mov BYTE PTR [rbp-0x10],0x1
0x00000000004006e8 <+8>: mov BYTE PTR [rbp-0xf],0x2
0x00000000004006ec <+12>: mov BYTE PTR [rbp-0xe],0x3
0x00000000004006f0 <+16>: mov BYTE PTR [rbp-0xd],0x4
0x00000000004006f4 <+20>: mov BYTE PTR [rbp-0xc],0x5
0x00000000004006f8 <+24>: mov BYTE PTR [rbp-0xa],0x6
0x00000000004006fc <+28>: mov BYTE PTR [rbp-0x9],0x7
0x0000000000400700 <+32>: mov BYTE PTR [rbp-0x8],0x8
0x0000000000400704 <+36>: mov BYTE PTR [rbp-0x7],0x9
0x0000000000400708 <+40>: mov BYTE PTR [rbp-0x6],0xa
0x000000000040070c <+44>: mov BYTE PTR [rbp-0x5],0xb
0x0000000000400710 <+48>: mov BYTE PTR [rbp-0x4],0xc
0x0000000000400714 <+52>: mov BYTE PTR [rbp-0x3],0xd
0x0000000000400718 <+56>: mov BYTE PTR [rbp-0x2],0xe
0x000000000040071c <+60>: mov BYTE PTR [rbp-0x1],0xf
0x0000000000400720 <+64>: mov BYTE PTR [rbp+0x0],0x10
0x0000000000400724 <+68>: mov BYTE PTR [rbp+0x1],0x11
0x0000000000400728 <+72>: mov BYTE PTR [rbp+0x2],0x12
0x000000000040072c <+76>: mov BYTE PTR [rbp+0x3],0x13
0x0000000000400730 <+80>: mov BYTE PTR [rbp+0x4],0x14
0x0000000000400734 <+84>: mov BYTE PTR [rbp+0x5],0x15
0x0000000000400738 <+88>: mov BYTE PTR [rbp+0x6],0x16
0x000000000040073c <+92>: mov BYTE PTR [rbp+0x7],0x17
0x0000000000400740 <+96>: mov BYTE PTR [rbp+0x8],0x18
0x0000000000400744 <+100>: mov BYTE PTR [rbp+0x9],0x19
0x0000000000400748 <+104>: mov BYTE PTR [rbp+0xa],0x1a
0x000000000040074c <+108>: pop rbp
0x000000000040074d <+109>: ret

2

Huh? No maże Ci po stosie za tablicą, przecież to napisałeś w kodzie. Tablica ma 4 elementy a mażesz do "elementu" 27. Czego się spodziewałeś?

Ściślej mówąc ten kod nie wiadomo co robi, ponieważ zawiera undefined behavior.

0

To, że lecę poza zakres to wiem, robie to specjalnie by w gdb widzieć jaka wartość gdzie idzie dokładnie na stos.
W tym kodzie chodzi o to by zobaczyć jak wygląda stos, pytanie skąd ta "wolna przestrzeń" ?

2

Ah, chodzi Ci o to, że tablica zaczyna się od rbp-16?

GCC stara się zawsze zapewnić 16 bajtowy alignment stosu (ABI x86_64 tego wymaga i tak, kontroluje to opcja -mpreferred-stack-boundary). Od początku wszystko ustawiane jest tak, żeby każda kolejna ramka miała dobry alignment.

Przynajmniej wydaje mi się, że to to.

0

Brzmi logicznie ;) poczytam o tym, bo to chyba to, dzięki wielkie

3

To jest złe podejście, bo to jest UB więc kompilator ma prawo wygenerować zupełnie dowolny kod wynikowy.

0

To jak badać takie rzeczy na linuxie ? W windowsie mam windbg, oly, a na linuksie gdb jest slabo czytelne i konsolowe... Sa jakies inne opcje niz gdb ?

0

Z fajnych debuggerów pod linucha polecam DDD(nakładka na gdb), oraz konsolowy framework radare2.

2
Świetny Krawiec napisał(a):

To jak badać takie rzeczy na linuxie ? W windowsie mam windbg, oly, a na linuksie gdb jest slabo czytelne i konsolowe... Sa jakies inne opcje niz gdb

Ja nie piję do gdb, tylko do twojego kodu. Badania opierasz na kodzie, który ma undefined behavior, i analizujesz kod asemblera. Nie ma gwarancji, że w przypadku UB (wyjechanie poza tablicę w tym przypadku) kompilator wygeneruje taki kod, jaki ci się wydaje (czyli wyjeżdżający poza tablicę). Moża zademonstrować przykłady w których taki kod jest po prostu wyrzucany, albo okoliczna pętla staje się nieskończona, albo inne dziwne rzeczy się dzieją.

?
Nie stawiamy spacji przed znakiem zapytania.

0
Świetny Krawiec napisał(a):

To jak badać takie rzeczy na linuxie ? W windowsie mam windbg, oly, a na linuksie gdb jest slabo czytelne i konsolowe... Sa jakies inne opcje niz gdb ?

IDA

1 użytkowników online, w tym zalogowanych: 0, gości: 1