2009-09-03 12 views
7

Ho alcune domande relative ai processi Windows nel kernel e in usermode.Processi Windows nel kernel vs sistema

Se ho un'applicazione Hello World e un driver mondiale Hello che espone una nuova chiamata di sistema, foo(), sono curioso di sapere cosa posso e cosa non posso fare quando sono in modalità kernel.

Per i principianti, quando scrivo la mia nuova app ciao mondo, mi viene dato un nuovo processo, il che significa che ho il mio spazio per la mia modalità utente VM (lascia che sia semplice, finestre a 32 bit). Quindi ho 2 GB di spazio che possiedo ", posso colpire e sbirciare fino a che i miei cuori non si accontentano. Tuttavia, sono vincolato dal mio processo. Non posso (non permettiamo di portare la memoria condivisa in questo ancora) toccare qualcun altro memoria.

Se, scrivo questo ciao world driver, e lo chiamo dalla mia app utente, I (il codice del driver) è ora in modalità kernel.

Primo chiarimento/domande: Sono ANCORA nello stesso processo dell'app per la modalità utente, corretto? Hai ancora lo stesso PID?

Memoria Domande: La memoria viene presentata al mio processo come VM, anche se ho 1 GB di RAM, posso ancora accedere a 4 GB di memoria (2 GB utente/2 GB di kernel - non mi interessa i dettagli degli switch sui server, o specifiche, solo un'ipotesi generale qui). Come processo utente, non posso dare un'occhiata a nessun indirizzo di memoria in modalità kernel, ma posso fare tutto ciò che voglio nello spazio utente, corretto?

Se chiamo nel mio driver hello world, dal codice del driver, ho ancora la stessa vista della memoria usermode? Ma ora ho anche accesso a qualsiasi memoria in modalità kernel?

Questa memoria in modalità kernel è SHARED (diversamente dalla modalità Utente, che è la copia dei miei processi)? Cioè, scrivere un driver è più come scrivere un'applicazione filettata per un singolo processo che è il sistema operativo (programmazione a parte?)

Domanda successiva. Come autista, potrei cambiare il processo che sto eseguendo. Supponiamo che conosca un'altra app (ad esempio un server web usermode) e carichi la VM per quel processo, modifichi il suo puntatore di istruzioni, impili o carichi codice diverso nel processo e poi torni alla mia app? (Non sto cercando di fare nulla di nefasto qui, sono solo curioso di sapere cosa sia in realtà significa essere in modalità kernel)?

Inoltre, una volta in modalità kernel, posso impedire al sistema operativo di impedirmi? Penso che in Windows sia possibile impostare il livello IRQL per farlo, ma non lo capisco appieno, anche dopo aver letto il libro di Solomons (Inside Windows ...). Chiederò un'altra domanda, direttamente correlata a IRQL/DPC ma, per ora, mi piacerebbe sapere se un driver del kernel ha il potere di impostare un IRQL su High e prendere il controllo del sistema.

Altro a venire, ma le risposte a queste domande potrebbero aiutare.

+0

Non credo che questa è una domanda cattiva, +1. –

risposta

3

Un buon primer per questo argomento sarebbe trovato a: http://www.codinghorror.com/blog/archives/001029.html

Come sottolinea Jeff fuori per lo spazio di memoria in modalità utente:

"in modalità utente, il codice di esecuzione non ha alcuna possibilità di accedere direttamente all'hardware o la memoria di riferimento.Il codice in esecuzione in modalità utente deve delegare alle API di sistema per accedere all'hardware o alla memoria.A causa della protezione offerta da questo tipo di isolamento, i crash in modalità utente sono sempre recuperabili.La maggior parte del codice in esecuzione sul computer verrà eseguito in modalità utente."

Così la vostra applicazione non avranno accesso alla memoria Kernel Mode, infact la tua comunicazione con il conducente è probabilmente attraverso IOCTL (cioè IRP).

Il kernel ha però accesso a tutto, anche a mappature per la vostra processi in modalità utente: questa è una strada a senso unico, la modalità utente non può essere mappata in modalità kernel per ragioni di sicurezza e stabilità, anche se i driver in modalità kernel possono mappare nella memoria modalità utente, vorrei sconsigliarlo

Almeno questo è il modo era di nuovo prima di WDF Non sono sicuro delle capacità di mappatura della memoria con i driver in modalità utente

Vedere anche: http://www.google.com/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fdownload.microsoft.com%2Fdownload%2Fe%2Fb%2Fa%2Feba1050f-a31d-436b-9281-92cdfeae4b45%2FKM-UMGuide.doc&ei=eAygSvfuAt7gnQe01P3gDQ&rct=j&q=user+mode+mapping+into+kernel+mode&usg=AFQjCNG1QYQMcIpcokMoQSWJlGSEodaBHQ

7

Ogni processo ha un "contesto" che, tra le altre cose, contiene i mapping VM specifici per quel processo (< 2 GB normalmente in modalità a 32 bit). Quando il thread in esecuzione in modalità utente passa alla modalità kernel (ad esempio da una chiamata di sistema o una richiesta IO), lo stesso thread è ancora in esecuzione, nel processo, con lo stesso contesto. PsGetCurrentProcessId restituirà la stessa cosa a questo punto come GetCurrentProcessID avrebbe avuto appena prima in modalità utente (lo stesso con ID thread).

Le mappature della memoria utente fornite con il contesto sono ancora attive quando si accede alla modalità kernel: è possibile accedere direttamente alla memoria utente dalla modalità kernel. Ci sono cose speciali che devono essere fatte perché questo sia sicuro: Using Neither Buffered Nor Direct I/O. In particolare, un tentativo di accesso agli indirizzi non valido nell'intervallo di spazio utente solleverà un'eccezione SEH che deve essere intercettata e il contenuto della memoria utente può cambiare in qualsiasi momento a causa dell'azione di un altro thread in quel processo. L'accesso a un indirizzo non valido nell'intervallo di indirizzi del kernel causa un bugcheck. Un thread in esecuzione in modalità utente non può accedere a nessuna memoria del kernel.

Lo spazio indirizzo del kernel non fa parte del contesto di un processo, quindi viene mappato lo stesso tra tutti. Tuttavia, qualsiasi numero di thread può essere attivo in modalità kernel in qualsiasi momento, quindi non è come un'applicazione a thread singolo. In generale, i thread supportano le proprie chiamate di sistema quando entrano in modalità kernel (al contrario di avere thread dedicati al kernel worker per gestire tutte le richieste).

Le strutture sottostanti che salvano lo stato del thread e del processo sono tutte disponibili in modalità kernel. La mappatura della VM di un altro processo viene eseguita in anticipo rispetto all'altro processo creando un MDL da tale processo e associandolo nello spazio degli indirizzi del sistema. Se vuoi solo modificare il contesto di un altro thread, questo può essere fatto interamente da user mode. Si noti che una discussione deve essere sospesa per cambiare il suo contesto senza avere una condizione di competizione. Il caricamento di un modulo in un processo dalla modalità kernel è sconsigliato; tutte le API del caricatore sono progettate per essere utilizzate solo dalla modalità utente.

Ogni CPU ha una corrente pari a IRQL in esecuzione. Determina quali cose possono interrompere ciò che sta facendo la CPU. Solo un evento da un IRQL superiore può prevenire l'attività corrente della CPU.

  • PASSIVE_LEVEL è dove viene eseguito tutto il codice utente e la maggior parte del codice del kernel. Molte le API del kernel richiedono l'IRQL essere PASSIVE_LEVEL
  • APC_LEVEL è usato per APC kernel
  • DISPATCH_LEVEL è per gli eventi scheduler (noto come il dispatcher in NT terminologia). L'esecuzione a questo livello ti impedirà di essere anticipata dallo scheduler. Si noti che non è sicuro avere alcun tipo di errore di pagina a questo livello; ci sarebbe una possibilità di deadlock con il gestore della memoria che tenta di recuperare le pagine.Il kernel eseguirà il bugcheck immediatamente se presenta un errore di pagina a DISPATCH_LEVEL o superiore. Ciò significa che non è possibile accedere in modo sicuro al pool di paging, ai segmenti di codice paginato o alla memoria utente che non è stata bloccata (ad esempio da un MDL).
  • Sopra questo sono i livelli collegati ai livelli di interruzione del dispositivo hardware, noto come DIRQL.
  • Il livello più alto è HIGH_LEVEL. Niente può prevenire questo livello. È usato dal kernel durante un bugcheck per fermare il sistema.

vi consiglio di leggere Scheduling, Thread Context, and IRQL

Problemi correlati