Et kanarieord er en sekvens av biter plassert ved grensen mellom en buffer (for eksempel en stabel) og kontrolldata i et program, som en måte å oppdage og reagere på bufferoverløp.
Hvor mange biter er disse kanariene på Linux, vanligvis?
Et kanarieord er en sekvens av biter plassert ved grensen mellom en buffer (for eksempel en stabel) og kontrolldata i et program, som en måte å oppdage og reagere på bufferoverløp.
Hvor mange biter er disse kanariene på Linux, vanligvis?
La oss prøve det! Her er et veldig enkelt eksempelprogram.
int test (int a) {return a;}
Kompiler det med GCC og avskjær samlingen på monteringsfasen. ( -S
-flagget vil gjøre dette.) Gi nytt navn til monteringsfilen (slik at den ikke blir overskrevet) og kompiler igjen, denne gangen legger du også til -fstack-protector-all
og -mstack-protector-guard = global
flagg. Det første flagget muliggjør stabile kanarifugler for alle funksjoner, det andre velger en global kanarifugl i stedet for en trådlokal. (Tråd-lokal standard er sannsynligvis mer nyttig i praksis, men samlingen for den globale versjonen er lettere å forstå.)
Når vi sammenligner de to genererte monteringsfilene, ser vi følgende tillegg (kommentarene er mine).
movl% edi, -20 (% rbp); lagre funksjonsparameter på stabel (ikke relatert til kanari) movq __stack_chk_guard (% rip),% rax; last magisk verdi i RAX-register movq% rax, -8 (% rbp); lagre RAX-register på stabelen (plasser kanarifuglen) movl -20 (% rbp),% eax; last funksjonsparameter i EAX-register for retur (ikke relatert til kanari) movq -8 (% rbp),% rcx; last kanariværdi i RCX-register movq __stack_chk_guard (% rip),% rdx; laste magisk verdi i RDX register cmpq% rdx,% rcx; sammenligne kanariverdi med forventet verdi je .L3; hvis de er de samme, hopp til etiketten. L3 (fortsett) ring __stack_chk_fail; Ellers (stakk korrupsjon oppdaget), ring behandleren.L3: la
Vi kan se at kanarifuglen håndteres i RAX-, RCX- og RDX-registerene som alle er 64 bit brede. (Deres 32-biters kolleger vil hete EAX, EBX og EDX. De 16 biters versjonene heter AX, BX og CX. De 8 bit-variantene AL, BL og CL.) En annen anelse er at operasjonene for å lagre, laste og sammenligne canary (MOVQ og CMPQ) har et Q-suffiks som identifiserer en 64-biters instruksjon. (32-biters instruksjoner har "L" -suffiks, 16 bit-instruksjoner a "W" og 8-biters versjoner a "B".
Derfor konkluderer vi at kanarifuglen er en 64-biters verdi, noe som gjør sans for en 64-biters arkitektur (x86_64 GNU / Linux i mitt tilfelle). Jeg forventer at de alltid vil bruke den opprinnelige ordstørrelsen, da det gir mest mening for meg. Du kan prøve det samme eksperimentet på maskinene dine og se hva du får.
Som jeg kan lese på denne siden: Stack Smashing Protector
Stackkanarien er innfødt i ordstørrelse, og hvis den velges tilfeldig, må en angriper gjette riktig verdi blant 2 ^ 32 eller 2 ^ 64 kombinasjoner
Antall bits som brukes må være lik prosessoren i Word. Så hvis du har en 32-bits prosessor, er dens Word-størrelse 32, og derfor er kanariordet 32 bits langt.