Dado que ciertas instrucciones, estructuras de datos o caminos de ejecución pueden no quedar muy claros a la hora del análisis con desensambladores, el análisis dinámico con debuggers es la alternativa natural. Sin embargo, así como existen técnicas utilizadas por los desarrolladores de malware para complicar el desensamblado, también podemos encontrar diversas técnicas de anti-debugging. En este post analizaremos algunas de ellas.

Probablemente, los métodos más populares de anti-debugging son aquellos que se basan en llamadas a la API de Windows. Esto se debe a la sencillez con que se puede manejar la detección del debugger, si bien resulta particularmente ventajoso para el analista de malware. En este sentido, al revisar los imports con una herramienta como PEiD o Dependency Walker, funciones como IsDebuggerPresent, GetTickCount, OutputDebugString o NTQueryInformationProcess llaman la atención y nos alertan de la posible presencia de este tipo de técnicas.

De cualquier modo, hoy no nos centraremos en los mecanismos que utilizan llamadas al sistema, sino que veremos algunas estructuras de datos que pueden ser consultadas mediante unas pocas instrucciones y que suelen pasar desapercibidas. Dichas estructuras se encuentran presentes en una sección de memoria conocida como Process Environment Block (PEB), que contiene ciertos parámetros de ejecución asociados a un proceso. Entre esos parámetros se pueden mencionar las variables de entorno, módulos cargados por el proceso, direcciones en memoria e información de debugging.

El PEB es accesible desde un puntero almacenado en fs:[0x30]. Desde allí se puede acceder a la dirección base de la estructura, que contiene los siguientes campos:

estructura process environment block
El segundo, BeingDebugged, contendrá un valor igual a cero si el proceso no está siendo debuggeado, y distinto de cero si efectivamente está siendo analizado con una herramienta como OllyDbg. Luego, cualquier programa malicioso no tendrá más que revisar el estado de este campo, variando su comportamiento si detectase la presencia de un debugger. Así, en la siguiente imagen observamos un conjunto de instrucciones en un programa que lleva a cabo la comprobación:

beingdebugged flag
Vemos que, si BeingDebugged no tiene un valor igual a cero, se invoca exit, terminando la ejecución. De lo contrario, aparece un nuevo control: dentro del campo Reserved4 se encuentra el ProcessHeap, un puntero hacia el primer heap que el loader ha reservado en memoria. Entre los primeros campos de esta estructura se encuentra ForceFlags, que indica si el heap ha sido creado dentro de un debugger. Como se puede ver en la imagen anterior, ProcessHeap se accede desde el byte 0x18 en el PEB, mientras que ForceFlags, 16 bytes desde la dirección base del ProcessHeap.

Por último, quiero agregar un campo más que suele ser consultado por el malware para determinar si corre en un debugger: NTGlobalFlag. Este campo puede ser accedido con un desplazamiento de 0x68 bytes desde la dirección base del PEB. Su valor se construye como una combinación de diversos flags, que indican si las estructuras en el heap han sido creadas por un debugger. No entraremos en los detalles, pero sí debemos saber que, si este campo tiene el valor 0x70, el proceso ha sido lanzado desde un debugger. En la siguiente imagen observamos el código correspondiente en un ejecutable malicioso:

ntglobalflag
Vale la pena destacar que cada uno de estos campos puede ser comprobado de forma independiente de los otros en cualquier malware con capacidades anti-debugging. En otras palabras, debemos estar atentos a la presencia de referencias al PEB en el binario que estemos analizando; cualquier ocurrencia de fs:[0x30] levantará sospechas.

Ahora bien, ¿cómo podemos contrarrestar el uso de estas técnicas? Existen dos aproximaciones básicas: en primer lugar, mientras el proceso está siendo debuggeado, pueden modificarse los bytes en el PEB en forma manual, antes de que se realicen las comparaciones, o se pueden parchear los saltos condicionales. En segundo lugar, pueden utilizarse plugins como PhantOm, que realizan las modificaciones de manera automática.