Domanda

Su Linux (o Solaris) esiste un modo migliore dell'analisi manuale ripetuta di / proc / self / maps per capire se è possibile leggere, scrivere o eseguire ciò che è memorizzato in uno o più indirizzi in memoria?

Ad esempio, in Windows hai VirtualQuery .

In Linux, posso mprotect per cambiare quei valori, ma non riesco a rileggerli.

Inoltre, c'è un modo per sapere quando cambiano quelle autorizzazioni (ad esempio quando qualcuno usa mmap su un file dietro la mia schiena) oltre a fare qualcosa di terribilmente invasivo e usare ptrace su tutti i thread del processo e intercettare qualsiasi tentativo di creare un syscall che potrebbe influenzare la mappa di memoria?

Aggiornamento:

Sfortunatamente, sto usando questo all'interno di una JIT che ha pochissime informazioni sul codice che sta eseguendo per ottenere un'approssimazione di ciò che è costante. Sì, mi rendo conto che potrei avere una mappa costante di dati mutabili, come la pagina vsyscall utilizzata da Linux. posso ripiegare in sicurezza supponendo che tutto ciò che non è incluso nell'analisi iniziale sia mutabile e pericoloso, ma non sono del tutto soddisfatto di questa opzione.

In questo momento, quello che faccio è leggere / proc / self / maps e costruire una struttura attraverso la quale posso cercare binariamente la protezione di un determinato indirizzo. Ogni volta che ho bisogno di sapere qualcosa su una pagina che non è nella mia struttura rileggo / proc / self / maps supponendo che sia stata aggiunta nel frattempo o che stavo per segfault comunque.

Sembra proprio che l'analisi del testo per ottenere queste informazioni e non sapere quando cambia sia terribilmente croccante. ( / dev / inotify non funziona praticamente su nulla in / proc )

È stato utile?

Soluzione

Non conosco un equivalente di VirtualQuery su Linux. Ma alcuni altri modi per farlo che possono o meno funzionare sono:

  • si imposta un gestore di segnale che intrappola SIGBUS / SIGSEGV e si procede con la lettura o la scrittura. Se la memoria è protetta, verrà chiamato il codice di trapping del segnale. In caso contrario, il codice di trapping del segnale non viene chiamato. Ad ogni modo, vinci.

  • puoi tracciare ogni volta che chiami mprotect e costruisci una struttura dati corrispondente che ti aiuti a sapere se una regione è protetta da lettura o scrittura. Questo è utile se hai accesso a tutto il codice che utilizza mprotect.

  • puoi monitorare tutte le chiamate mprotect nel tuo processo collegando il tuo codice con una libreria che ridefinisce la funzione mprotect . È quindi possibile creare la struttura di dati necessaria per sapere se una regione è protetta da lettura o scrittura e quindi chiamare il sistema mprotect per impostare davvero la protezione.

  • puoi provare a usare / dev / inotify e monitorare il file / proc / self / maps per qualsiasi modifica. Immagino che questo non funzioni, ma dovrebbe valerne la pena.

Altri suggerimenti

Esiste una sorta di / was / proc / [pid | self] / pagemap, documentazione nel kernel, avvertenze qui: https://lkml.org/lkml/2015/7/14/477 Quindi non è del tutto innocuo ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top