(Advertencia: aquí estoy haciendo algunas "conjeturas educadas", en particular por analogía con lo que sucede en otros sistemas operativos.)
El comportamiento que describe es normal: un ejecutable de .NET es en realidad un tipo de script. Desde el punto de vista del kernel del sistema operativo, no hay ".NET". El núcleo conoce los archivos ejecutables . Para el núcleo, se puede acceder a un archivo para leer (una aplicación abre el archivo y luego lee los bytes con llamadas como ReadFile () ) o para ejecutar (consulte CreateProcess () ). Al ejecutar algunos archivos binarios, el contenido del archivo se asigna a la RAM a través de la MMU ; a nivel de MMU, las páginas tienen habilitados los derechos de lectura y ejecución. Sin embargo, si el archivo a ejecutar es un script , entonces el archivo binario que realmente se asigna a la RAM no es el propio archivo de script, sino el intérprete . El intérprete luego lee el contenido del script como datos .
Por lo tanto, cuando un archivo ejecutable es un script, los derechos de acceso realmente necesarios se "ejecutan" en el intérprete y "se leen" en el archivo del script. El sistema operativo también requerirá la "ejecución" en el archivo de script antes de aceptar localizar e iniciar el intérprete.
Un archivo ejecutable de .NET es, desde el punto de vista del kernel de Windows, un tipo de script; su intérprete es la máquina virtual CLR . Para el núcleo, el CLR no es nada especial. El CLR leerá el contenido del archivo .exe, encontrará el bytecode e lo interpretará (esa "interpretación" incluirá algunos compilación JIT pero esa es otra historia).
En cualquier caso, incluso si un usuario solo tiene el derecho de "ejecución" en un archivo binario pero no el derecho de "lectura", es probable que el usuario pueda adjuntar al proceso resultante y luego leer el archivo de esa manera. - porque, a nivel de MMU, las páginas que contienen el código serán ejecutables y legibles. Parece muy imprudente confiar en estos derechos de acceso para evitar la ingeniería inversa.