Cuando empezamos a debuggear archivos dll con OllyDbg, seguramente notaremos que el proceso es distinto en comparación con un ejecutable típico. En este sentido, la dll no es cargada en memoria de forma independiente, sino mediante otro archivo ejecutable que nos ofrece Olly. Por desgracia, si dicha dll está comprimida con algún packer, al debuggear podríamos obtener un entry point posterior a la rutina de unpacking. En este post exploraremos un pequeño truquito para solventar el problema mencionado.
Para empezar, tomaremos un archivo dll recibido en nuestro Laboratorio de Investigación de ESET Latinoamérica: fileeyeSupporterh.dll. Si abrimos este archivo con OllyDbg para su análisis, veremos que en realidad se carga el archivo loadDll.exe (provisto por Olly), quien será el encargado de invocar la función principal en la dll. Sin embargo, en este tipo de archivos existe una función DllMain que se ejecuta por única vez al ser cargada la dll en memoria, donde los packers suelen colocar su rutina de unpacking. Como podrán imaginarse, estas no son buenas noticias, ya que Olly no pausa la ejecución antes de DllMain, sino después, en la rutina que loadDll.exe invoque. Esto significa que el código de unpacking ya se ha ejecutado, haciendo muy difícil para el analista encontrar el Entry Point Original (OEP).
En la imagen que sigue se observa el entry point que Olly ha encontrado para nuestra dll:
Cabe destacar que esta dll se encuentra empaquetada con PECompact, y que este entry point es posterior al proceso de unpacking. Si continuamos ejecutando instrucción por instrucción, veremos que se lanzan varias excepciones, utilizando el mecanismo de Manejo Estructurado de Excepciones. El proceso será complicado y muy difícil de seguir, con lo cual debemos buscar otro enfoque.
El truco que utilizaremos en este caso es bastante sencillo: si Olly nos ofrece complicaciones con las dll, mas no con los exe, entonces hagamos que Olly piense que está abriendo un exe. Para ello, abriremos nuestra muestra con un editor que nos permita interpretar los valores del encabezado PE del archivo; por ejemplo, PEview:
Se observa que existe un flag IMAGE_FILE_DLL dentro del campo Characteristics que indica si el archivo es o no una dll. Vemos que la suma de los campos da como resultado 0xA18E; luego, si restamos el valor de IMAGE_FILE_DLL (0x2000), obtenemos 0x818E. Por ello, abriremos la muestra con un editor hexadecimal y cambiaremos el valor en el offset 0x116:
Luego de realizado el cambio, PEview nos muestra que el flag IMAGE_FILE_DLL no está presente. Si ahora abrimos la dll con Olly, vemos que el entry point ha cambiado: tenemos un salto a otra parte del código. Luego de realizado dicho salto, si tan sólo bajamos unas instrucciones, encontraremos el tail jump a simple vista y, consecuentemente, el OEP:
Ahora puede dumpearse la dll desempaquetada a disco, o continuar analizando en el debugger. Vale la pena aclarar que, si luego se desea ejecutar la muestra para observar su comportamiento, habrá que revertir el cambio que se realizó en el byte editado.
SHA-1 de la muestra analizada
fc27d195b8e86a87dee2d15e5508c0814e5321bb - fileeyeSupporterh.dll