La pega de .NET es que necesita de un intérprete que traduce las instrucciones (.NET opcodes) en código máquina. Por lo que al compilar un ensamblado .NET, éste es guardado con las instrucciones que serán traducidas posteriormente, es decir, no es puro código máquina.
Esta es la gran diferencia entre los lenguajes interpretados y compilados. Si no conoces bien como funciona esto, imagínate el entorno de ejecucción de .NET como un supervisor que controla referencias de memoria, optimización y además permite correr tus programas hechos bajo .NET.
En C++ es el programador quien tiene que lidiar con el trabajo de liberar recursos, quien tiene que optimizar (aunque el compilador ayude..) etc
No digo nada del Framework pues en C++ también los puedes encontrar, sólo hago una distinción de la arquitectura interna, y ya veis que muy breve.
En cuanto a la seguridad en ensamblados de .NET, pues no existe, ya que todo es reversible, esté ofuscado, empaquetado etc Existen programas capaces de desofuscar y de invalidar técnicas anti reflectores.
https://github.com/0xd4d/de4dot Ahí encontraras los ofuscadores que es capaz de romper. Recomiendo agarrar unos buenos tutoriales de las "internals" de .NET, irse a la parte de metadatos, ver como se estructuran las definiciones de los miembros y métodos de clases y alterar cierta info.. Otra de ellas es cargar el ensamblado .NET mediante el CLR desde C++, así será más díficil para el cracker tirarle ing inversa (una de mis favoritas
).
Y todavía hay mas...
Saludos!