HTCinside



5 técnicas anti depuración que protegerán su software

Al publicar nuestros productos de software, todos solemos escribir en los EULA 'No puede aplicar ingeniería inversa, descompilar ni desensamblar el Software'. Pero en muchas situaciones, las palabras no son la mejor protección y realmente necesita introducir algunas herramientas técnicas para evitar la inversión del software y proteger su conocimiento para que no se divulgue.

Existen varios enfoques tecnológicos para prevenir la ingeniería inversa de software: anti-debug, anti-dump y otros. En esta publicación, nos centraremos en algunos métodos anti-depuración, ya que son el núcleo de la protección anti-ingeniería inversa. Adjuntar un depurador al proceso investigado para ejecutarlo paso a paso es una etapa muy importante de cualquier trabajo de inversión, así que echemos un vistazo a las herramientas que podemos usar para hacer que la vida de los inversores sea más difícil.


Hay un par de cosas que me gustaría mencionar al principio. La primera es que no existe una protección universal o 100% a prueba de balas contra la ingeniería inversa de software. Siempre hay una manera de que el inversor entre, la única estrategia que tenemos es hacer que su trabajo sea lo más duro y laborioso posible.

A continuación, existen bastantes técnicas contra la ingeniería inversa y, en particular, métodos contra la depuración, incluida la protección basada en el tiempo o incluso tecnologías específicas de código integrado como los nanomitas. En esta publicación, consideraremos solo varios enfoques estándar específicos para sistemas basados ​​en Windows, los más populares.

Los enfoques representados a continuación se describen en general.

Contenido


Contenido

  1. Funciones integradas para verificar la presencia del depurador
  2. Ocultar hilo
  3. Comprobaciones de bandera
  4. Detección de punto de interrupción
  5. Manejo de excepciones: SEH
  6. Conclusión

1 – Funciones integradas para verificar la presencia del depurador

Los sistemas Windows nos brindan algunas herramientas listas para crear una protección simple contra la depuración. Una de las técnicas más simples contra la depuración se basa en llamar a la función IsDebuggerPresent. Esta función devuelve VERDADERO si un depurador de modo de usuario está depurando el proceso actualmente.

Esta función se refiere al PEB (Process Environment Block, una estructura de sistema cerrado) y en particular a su campo En proceso de depuración. Los inversores cuando eluden dicha técnica de protección utilizan este hecho: p. Al aplicar la inyección de DLL, configuraron el valor de BeingDebugged en 0 justo antes de realizar esta verificación en el código protegido.

Un par de palabras sobre dónde realizar dicha verificación. La función principal no es la mejor opción: los inversores suelen comprobarlo primero en el listado desmontado. Es mejor realizar una comprobación antidepuración en TLS Callback, ya que se llama antes del punto de llamada de entrada del módulo ejecutable principal.

Otra opción de verificación funcional es CheckRemoteDebuggerPresent. A diferencia de la función descrita anteriormente, comprueba si otro proceso paralelo está actualmente depurando un proceso. Se basa en la función NtQueryInformationProcess y, en particular, en el valor ProcessDebugPort.


2 – Ocultar hilo

Si bien el grupo anterior de métodos se basó en verificar la presencia del depurador, este proporcionará protección activa contra él.

A partir de Windows 2000, la función NtSetInformationThread recibe el nuevo indicador denominado ThreadHideFromDebugger. Esta es una técnica anti depuración muy eficiente proporcionada en el sistema operativo Windows. Un subproceso con este indicador establecido se detiene para enviar notificaciones de eventos de depuración, incluidos puntos de interrupción y otros, por lo que se oculta de cualquier depurador. Configurar ThreadHideFromDebugger para el hilo principal complicará significativamente el proceso de adjuntar el depurador a un hilo.

La continuación lógica se introdujo en Windows Vista con la función NtCreateThreadEx. Tiene el parámetro CreateFlags, que configura, entre otros, el indicador THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER. El proceso con este indicador establecido se ocultará del depurador.

3 – Comprobaciones de banderas

La ejecución de la depuración se puede detectar mediante los valores modificados de diferentes indicadores en varias estructuras de sistemas y procesos.


Windows NT incluye una variable global denominada NtGlobalFlag con un conjunto de indicadores, que se utiliza para el seguimiento y la depuración del sistema. La estructura PEB mencionada anteriormente incluye su propio campo NtGlobalFlag. Durante la depuración, el valor de este campo se cambia con varios indicadores específicos establecidos. La verificación de estos indicadores puede generar activadores para la protección contra la depuración.

Un ejecutable puede restablecer las banderas NtGlobalFlag de la estructura PEB por medio de una estructura específica denominada IMAGE_LOAD_CONFIG_DIRECTORY, que contiene parámetros de configuración específicos para el cargador del sistema. Tiene el campo GlobalFlagsClear, que restablece las banderas NtGlobalFlag de PEB. De forma predeterminada, esta estructura no se agrega a un ejecutable, pero se puede agregar más tarde. El hecho de que un ejecutable no tenga esta estructura o el valor GlobalFlagsClear sea igual a 0, mientras que el campo correspondiente almacenado en el disco o en la memoria del proceso en ejecución no sea cero, indica la presencia de un depurador oculto. Esta verificación se puede implementar en el código ejecutable.

Otro grupo de indicadores es el del montón de procesos. Hay dos campos en la estructura _HEAP correspondiente: Flags y ForceFlags. Ambos cambian sus valores cuando se depura el proceso correspondiente y, por lo tanto, pueden ser la base de la verificación y protección anti-depuración.

Una verificación de bandera más, que se puede usar para detectar el depurador, es la verificación de Trap Flag (TF). Está en el registro de EFLAGS. Cuando TF es igual a 1, la CPU genera INT 01h (excepción «Single Step») después de cada ejecución de instrucción que respalda el proceso de depuración.

4 – Detección de puntos de ruptura

Los puntos de interrupción son la parte esencial de cualquier proceso de depuración y, por lo tanto, al detectarlos, podemos detectar y neutralizar un depurador. Las tácticas contra la depuración basadas en la detección de puntos de interrupción son una de las más poderosas y difíciles de eludir.

Hay dos tipos de puntos de interrupción: software y hardware.

Los puntos de interrupción del software los establece el depurador al inyectar la instrucción int 3h en el código. Por lo tanto, los métodos de detección del depurador se basan en el cálculo y control de la suma de comprobación de la función correspondiente.

No existe un método universal para luchar contra esta protección: un pirata informático tendrá que encontrar el fragmento de código que calcula la(s) suma(s) de verificación y reemplazar los valores devueltos de todas las variables correspondientes.

Los puntos de interrupción de hardware se establecen mediante registros de depuración específicos: DR0-DR7. Usándolos, los desarrolladores pueden interrumpir la ejecución de un programa y transferir el control a un depurador. La protección contra la depuración puede basarse en la verificación de los valores de estos registros o ser más proactivos y forzar el restablecimiento de sus valores para detener la depuración mediante la función SetThreadContext.

5 – Manejo de excepciones: SEH

El Manejo Estructurado de Excepciones o SEH es un mecanismo que permite que una aplicación reciba notificaciones sobre situaciones excepcionales y las maneje en lugar del sistema operativo. Los punteros a los controladores SEH se denominan marcos SEH y se colocan en la pila. Cuando se genera una excepción, la maneja el primer marco SEH de la pila. Si no sabe qué hacer con él, se pasa al siguiente en la pila y así sucesivamente hasta el controlador del sistema.

Cuando se está depurando la aplicación, un depurador debe interceptar el control después de la generación de int 3h, o un controlador SHE lo tomará. Esto se puede usar para organizar la protección contra la depuración: podemos crear nuestro propio controlador SEH y colocarlo en la parte superior de la pila y luego forzar la generación int 3h. Si nuestro controlador obtiene el control, el proceso no se depura; de lo contrario, podemos forzar medidas anti-depuración cuando detectamos un depurador.

Conclusión

Estas son solo algunas técnicas anti-depuración de una gran variedad de ellas.

Una buena práctica es combinar diferentes técnicas antirretroceso para que sea mucho más difícil eludir la protección. Las comprobaciones adicionales pueden ralentizar la ejecución de una aplicación, por lo que las técnicas de protección más sólidas suelen aplicarse a los módulos principales que contienen tecnologías y conocimientos patentados. Finalmente, es una compensación entre el nivel de seguridad del código y el rendimiento de la aplicación.

Me gustaría mencionar que la ingeniería inversa del software no siempre es ilegal y, a veces, se puede aplicar durante el proceso de investigación para tareas como la mejora de la compatibilidad, la aplicación de parches, el uso no documentado de la interfaz del sistema, etc. Servicios de ingeniería inversa legal entregado por profesionales también se ocupa de la protección contra la depuración, pero desde otro lado, sin pasar por alto.