2010-07-06 17 views
7

He desarrollado mis habilidades de programación hasta el punto en que puedo hacer la mayoría de las cosas cotidianas bastante bien y fácilmente, y pensé que algún día hacer un motor polimórfico realmente pondría a prueba mis habilidades, y me preguntaba si alguien tenía alguna sugerencia sobre hacer un motor polimórfico para un programa, por dónde empezar, tal vez algunos ejemplos de código? Realmente nada sería de gran ayuda en este punto :)Motores polimórficos, en idiomas administrados?

aquí están algunos de mis recursos que les ofrecía:

+1

¿Qué es el motor polimórfico? – OscarRyz

+2

Supongo que el motor polimórfico tiene algo que ver con la frase de run-on? :) –

+1

¿Está planeando codificar virus administrados? :) –

Respuesta

5

Como menciono en un comentario, esto es posible en .NET usando el espacio de nombres mágico System.Reflection.Emit. Simplemente crea un nuevo DynamicMethod y emite códigos de operación [válidos], y luego llama a Invoke.

He pasado las últimas horas tratando de crear un escaparate simple para un programa "limpio" que crearía nuevas copias de sí mismo con código il cifrado. El enfoque que elegí fue tener un método Exec, tomar los il-bytes (usando MethodBase.GetMethodBody), encriptarlos y emitir un nuevo ensamblado con la clave iv + y los bytes cifrados. El método principal se descifraría, crearía un nuevo DynamicMethod, llamaría al DynamicILInfo.SetCode y con suerte funcionaría. No lo hizo.

La cosa de cifrado/descifrado funcionó, y mi código emitido fue correcto. Sin embargo, parece que no puede tomar los bytes brutos de un ensamblaje y simplemente ejecutarlos en otro.

Datos (de BitConverter.ToString) de la ejecución A y ejecución B.
A: 28-01-00-00-0A ...
B: 28-11-00-00-0A ...

A menos que sepa los valores de bytes para cada código de operación, abra ILDAsm, elija Ver> Mostrar bytes. También hay una vista> Mostrar valores de token que también ayuda a eliminar errores. Presione ctrl-m para Ver> MetaData> ¡Mostrar! para resolver tokens y otras criaturas mágicas.

"28 01 00 00 0A" -> LLAMADA 0A000001 -> [Según ctrl-m] MethodBase.GetCurrentMethod

Estos valores simbólicos diferentes se generan secuencialmente por el compilador. Esto significa que es imposible garantizar que todo funcione con bytes sin formato. Solo piense en el caso común en el que el compilador solo creó tokens para cada llamada de método requiere descifrar su matriz de bytes, y usted llama a Console.WriteLine en su código cifrado. No se escribe dicho token, y obtendrá una "BadImageFormatException: Bad binary signature" al invocar su método dinámico.

lo dejo como tarea para la lectura (o hasta que estoy aburrido de nuevo) para transformar la matriz de bytes, durante el proceso de emisión, a un formato que el descifrador puede leer y emiten de bytes il reales. El proceso de emisión creará todos los tokens necesarios, por lo que debería funcionar.

Si desea alejarse de todo lo maravilloso de emitir códigos de operación, realice una compilación dinámica a partir de código almacenado como cadenas (que, por supuesto, puede cifrarse). Esto, sin embargo, pierde tanto inteligencia, frescura y todo lo demás que se puede utilizar para medir la genialidad pura del desarrollador (¡USTED!). Consulte this tutorial para ver rápidamente la compilación dinámica y la ejecución de C# dentro de las cadenas.

+0

¿Alguna vez terminaste aburriéndote de nuevo? ;) – caesay

0

Bueno, hasta donde yo sé, un motor polimórfico es solo el código que quieres que se ejecute encriptado, y luego vincularlo con un módulo de descifrado. Entonces, todo lo que necesita hacer es encriptar su código en una cadena. Luego escribes un descifrador. Utilizaría una clase de encriptación simétrica básica como hxxp: //www.obviex.com/samples/Code.aspx? Source = EncryptionCS & Title = Symmetric% 20Key% 20Encryption & Lang = C% 23 Después de eso, ejecute el código en memoria, algo así como hxxp: //support.microsoft.com/kb/304655

EDIT: Si desea obtener más en profundidad, siempre se puede escribir su propio cifrado/descifrado, lo convierten en algo así como base_64 (sin clave), en lugar de AES (con una llave)

Espero que ayude, Max

+0

El polimorfismo es un código que no solo se cifra/descifra, sino que se CAMBIA todo el tiempo. Cada vez que se ejecuta, el código debe ser diferente, manteniendo el algoritmo original intacto. – caesay

+0

Oh, eso es interesante. Supongo que podría escribir su propio idioma básico, cada uno de sus comandos podría traducirse en múltiples comandos C#. Esto te permitiría crear tu código, luego analizarlo? Un ejemplo podrían ser los diferentes bucles en los que podría usar cualquiera de ellos para recorrer una matriz, y podría cambiar los nombres de las variables en la parte superior. Eso sería bastante polimórfico para mí;) – Ben

0

código polimórfico no es posible en C# o el hombre idiomas envejecidos. Requiere que se genere un código de ensamblaje para una plataforma específica (.NET no es específico de la plataforma) en un área de almacenamiento intermedio o de datos, luego se salta a ese área de almacenamiento intermedio o de datos. Hay muchas capas de software y hardware en el lugar para evitar que eso suceda; vea el bit de NX en Wikipedia, por ejemplo.

No puede hacerlo en código administrado. Tendría que escribirlo en código no administrado y llamar a eso.

Espero que ayude.


Consulte el útil comentario sobre esta respuesta, ya que puede crear dinámicamente código administrado a partir del código administrado; Estaba considerando un código no administrado, como se usa en general.

+3

¿Pero no podrías emitir código IL en DynamicMethod e Invoke() eso? – sisve

+1

Sí, sugiero que escriba una respuesta al respecto. –

+0

@simon que realmente debería, eso suena como una muy buena solución. – Ben

Cuestiones relacionadas