GNU/Linux >> Linux Esercitazione >  >> Linux

Perché questo codice si arresta in modo anomalo con la randomizzazione degli indirizzi attiva?

sub rsp, <size> per riservare spazio nello stack prima di toccarlo, se utilizzi più di 128 byte sotto RSP.

Quando si arresta in modo anomalo, guarda la mappa della memoria del tuo processo. Potresti utilizzare la memoria così al di sotto di RSP che il kernel non aumenta la mappatura dello stack e quindi è solo un normale accesso a una pagina non mappata =errore di pagina non valida => il kernel fornisce SIGSEGV.

(L'ABI definisce solo una zona rossa di 128 byte, ma in pratica l'unica cosa che può ostruire quella memoria è un gestore di segnale (che non hai installato) o GDB che esegue print some_func() usando lo stack del tuo programma per chiamare una funzione nel tuo programma.)

Normalmente Linux è abbastanza disposto a far crescere la mappatura dello stack senza toccare le pagine intermedie, ma a quanto pare controlla il valore di RSP. Normalmente sposti RSP invece di usare solo la memoria molto al di sotto del puntatore dello stack (perché non c'è alcuna garanzia che sia sicuro). Vedi Come viene allocata la memoria dello Stack quando si usano le istruzioni x86 'push' o 'sub'?

Un altro duplicato:quale eccezione può essere generata quando si sottrae il registro ESP o RSP? (stack crescente) dove si usa sub rsp, 5555555 prima di toccare il nuovo stack la memoria era sufficiente.

Stack ASLR potrebbe avviare RSP in punti diversi rispetto a un limite di pagina , quindi a volte potresti farla franca a malapena. Linux mappa inizialmente 132 kiB di spazio dello stack , e che include lo spazio per l'ambiente e gli argomenti nello stack all'accesso a _start . I tuoi 128 kiB sono molto vicini a questo, quindi è del tutto plausibile che a volte funzioni in modo casuale.

E a proposito, non c'è motivo per copiare effettivamente la memoria nello spazio utente, specialmente non 1 byte alla volta. Basta passare lo stesso indirizzo a write .

O almeno filtrare sul posto, se possibile, in modo che il footprint della cache sia inferiore.

Inoltre, il modo normale per caricare un byte è movzx eax, byte [mem] . Usa solo mov al, [mem] se desideri specificamente unire con il vecchio valore di RAX. Su alcune CPU, mov a al ha una falsa dipendenza dal vecchio valore che puoi rompere scrivendo il registro completo.

E a proposito, se il tuo programma sempre usa questo spazio, potresti anche allocarlo staticamente nel BSS. Ciò rende possibile un indirizzamento indicizzato più efficiente se si sceglie di assemblare un eseguibile dipendente dalla posizione (non PIE).


La zona rossa in amd64 è lunga solo 128 byte, ma stai usando 131072 byte sotto rsp. Sposta il puntatore dello stack verso il basso per racchiudere i buffer che vuoi memorizzare nello stack.


Linux
  1. Perché Tomcat funziona con la porta 8080 ma non con la 80?

  2. Perché git fallisce su push/fetch con troppi file aperti

  3. Perché questo ciclo di ritardo inizia a funzionare più velocemente dopo diverse iterazioni senza sospensione?

  4. Perché il mio $LD_LIBRARY_PATH viene disattivato quando utilizzo screen con bash?

  5. Non riconosco l'indirizzo del mio server DNS:significa che sono compromesso?

Perché la sostituzione del processo Bash non funziona con alcuni comandi?

Perché l'aggiunta di due punti interrompe questo schema Grep?

Perché Ping -f si comporta in questo modo?

Perché questo codice si arresta in modo anomalo con la randomizzazione degli indirizzi attiva?

Perché questa espressione regolare non funziona su Linux?

Perché il mio nome host appare con l'indirizzo 127.0.1.1 anziché 127.0.0.1 in /etc/hosts?