(Attenzione: qui sto facendo alcune "congetture istruite", in particolare per analogia con ciò che accade in altri sistemi operativi.)
Il comportamento che descrivi è normale: un eseguibile .NET è in realtà una specie di script. Dal punto di vista del kernel del sistema operativo, non esiste ".NET". Il kernel conosce i file eseguibili . Per il kernel, è possibile accedere a un file per lettura (un'applicazione apre il file e quindi legge i byte con chiamate come ReadFile () ) o per in esecuzione (vedere CreateProcess () ). Durante l'esecuzione di alcuni file binari, il contenuto del file viene mappato nella RAM tramite MMU ; a livello MMU, le pagine hanno entrambi i diritti di lettura ed esecuzione abilitati. Tuttavia, se il file da eseguire è uno script , il file binario che viene effettivamente mappato nella RAM non è il file di script stesso, ma l'interprete . L'interprete legge quindi il contenuto dello script come dati .
Quindi, quando un file eseguibile è uno script, i diritti di accesso effettivamente richiesti sono "esegui" sull'interprete e "leggono" sul file di script. Il sistema operativo richiederà anche il comando "Esegui" sul file di script prima di accettare di individuare e avviare l'interprete.
Un file eseguibile .NET è, dal punto di vista del kernel di Windows, una sorta di script; il suo interprete è la macchina virtuale CLR . Per il kernel, il CLR non è niente di speciale. Il CLR leggerà i contenuti .exe, troverà bytecode e lo interpreterà (che "interpretazione" includerà alcuni Compilazione JIT ma questa è un'altra storia).
In ogni caso, anche se un utente ha solo il diritto "esegui" su un file binario ma non il diritto "letto", allora è probabile che l'utente possa collegarsi al processo risultante e quindi leggere il file in questo modo - - perché, a livello MMU, le pagine che contengono il codice saranno sia eseguibili che leggibili. Sembra poco saggio affidarsi a questi diritti di accesso per evitare il reverse engineering.