Se dice que Denuvo es un sistema de software a prueba de manipulaciones, lo que significa que se usa para proteger DRM de juegos convencionales (como Steam u Origin). Aparentemente, es una nueva versión de VMProtect (enlace en ruso; traducción parcial al inglés aquí – enlace; también enlace de lectura).
No lo he mirado y asumo que será mucho trabajo hacerlo (está hecho para que sea difícil de entender), pero, respaldado por cualquier información que pueda encontrar, si alguien me pide que invente algo como esto, esto es lo que intentaría:
- Primero, la máquina virtual normal y el código de detección del depurador , por ejemplo, VMware responde a una IRQ específica; Si llamar a esto no es un error, está ejecutando en una máquina virtual. No será muy efectivo (los depuradores parcheados y las máquinas virtuales imitarán las respuestas del hardware real), pero también es fácil de implementar.
- Usaría los mismos canales de comunicación que usan los depuradores . Si ya hay un depurador conectado, esto no funcionará (lo que puedo detectar y dejará en libertad bajo fianza) o al menos confundirá al otro depurador.
- Intentaría cronometrar la ejecución de las funciones y fianza si veo que algo toma un orden de magnitud más de lo habitual. El código que se ejecuta lentamente es un síntoma de un depurador o algún tipo de rastreo (o una CPU que es demasiado lenta para ejecutar el juego de todos modos).
- Para los programadores de ensamblaje, el código era información antes de que fuera genial. Un programa puede cifrar y descifrar sus propias instrucciones , y utilizar la criptografía de caja blanca para no revelar la clave en la memoria (la “clave” está incrustada en la estructura de un código grande y complejo). Un cracker tendría que engañar al esquema de protección para descifrar y cifrar datos para él, lo que puede ser difícil.
- Seguí religiosamente las peores prácticas de desarrollo de software . Las funciones se dividirán en miles de piezas conectadas con saltos indirectos, habrá redundancia en todas partes y todo estará conectado a todo lo demás. El flujo del programa sería lo más retorcido posible . Por supuesto, cada variable será una variable global, y algunos valores de algunas variables se reutilizarán para múltiples propósitos no relacionados en diferentes partes del programa, mientras que otros no servirán para nada (sin que esto sea obvio) o sirvan como partes de un valor cuando se combina con otros. Escribiría un programa que pueda convertir código bueno a código malo, porque escribir esto a mano sería una locura. Esto se llama ofuscación de código .
- O tal vez podría llevar esto un paso más allá y traducir el programa a la peor CPU jamás imaginada : una máquina virtual hecha específicamente para tener un horrible conjunto de instrucciones y semántica de ejecución. Habrá millones de instrucciones que hacen lo mismo de maneras ligeramente diferentes, y trataría de hacer que la misma instrucción signifique cosas diferentes dependiendo de cuándo la ejecute.
- Si conozco algún error en sus depuradores , me aseguraré de que mi código los active o de lo contrario los haga funcionar lentamente.
- Voy a saltar a la mitad de las instrucciones para confundir a los analizadores estáticos; en última instancia, las instrucciones de la CPU son solo un montón de bytes; puede crear un esquema similar a esos textos en los que si lee solo la primera letra de cada fila, recibe un mensaje diferente al de leer el texto normalmente.
Lo anterior probablemente tiene sentido, porque mencionan explícitamente en su sitio web que protege “funciones de juego no críticas de rendimiento” : las técnicas anteriores tienen un gran impacto en el rendimiento, y destruir el bucle principal del juego habría sido inaceptable. También hay este extracto del Manual del usuario de VMProtect:
- ¿Cómo podemos evitar la inanición en el problema de los filósofos?
- Cómo encontrar correspondencia en dos imágenes en las que los objetos son bolas del mismo tamaño y color
- ¿UBC, USC o UCI son mejores para la informática de pregrado?
- Si se quita el chip BIOS después de que el sistema se haya iniciado, ¿la computadora simplemente continuará funcionando hasta el próximo reinicio?
- ¿Se puede asignar memoria virtual sin tener que depender de fallas de página?
Las formas más eficientes de proteger una aplicación son la ofuscación y la virtualización que complican el análisis del código de la aplicación protegida. En general, la alta eficiencia de estos métodos de protección se basa en el factor humano: cuanto más complejo es el código y más recursos utiliza la aplicación, más difícil es para un cracker comprender la lógica del programa y, en consecuencia, descifrar la protección.
[…]
La única desventaja de la virtualización es la velocidad de ejecución relativamente baja, por lo que este método solo debe aplicarse a partes del código que no son críticas para la velocidad de ejecución.
Entonces, ¿cómo es exactamente algo de esto nuevo? Pues no lo es ; Los dos factores importantes que hacen que el craqueo sea lento son, primero:
No hubo buenos depuradores de 64 bits hasta hace poco. OllyDbg, Immunity y similares solo funcionan para aplicaciones de 32 bits. Y las herramientas dejadas por la generación anterior de crackers, las que sabían cómo escribir un compilador optimizador (para deshacerse de la ofuscación o una máquina virtual), ya no funcionan.
Y segundo, con Steam matándolo en los países “piratas” (SteamSpy – Rusia – Estadísticas del país), la motivación para escribir las herramientas no es la misma; si anteriormente tu única esperanza de jugar ese juego era encontrar o escribir un crack para él, ahora solo espera y obtén un 75% de descuento.
Dicho esto, tales sistemas a menudo tienen vidas extremadamente cortas: no existe un método seguro para proteger el software en hardware no protegido, y si el esquema de protección es interesante, siempre atraerá a los crackers. Además, si la protección es de uso general, hay una forma de uso general para vencerla (puede leer más en http://whiteboxcrypto.com/files/… (PDF)). Sin embargo, el esfuerzo por romper la protección puede ser similar al esfuerzo por lograrlo , y solo un lado en ese conflicto realmente está recibiendo su pago.
La forma en que Denuvo se mantiene al tanto de eso es actualizando constantemente su sistema , casi con cada lanzamiento del juego. Sospecho que esto es parte de la razón por la cual es tan costoso. Ya había un par de grietas para los juegos de Denuvo, pero AFAIK no eran “verdaderas grietas” (es decir, no quitaron la protección por completo; explotaron errores o incluso sacrificaron cuentas legítimas de Steam para evitarlo).