Ingeniería inversa de software

Reversando para usar librerías

Segun el libro "Secrets of Reverse Engineering" una de las aplicaciones de ingeniería inversa de software es poder utilizar funcionalidades no documentadas en librerías de código cerrado creadas por terceros. Se dice que Microsoft mantiene funciones escondidas o no documentadas en sus API’s que son utilizadas por los programas creados en Microsoft y así tener ventaja sobre programas creados por terceros (quienes a veces no conocen de la existencia de dichas funciones). En este ejercicio analizarás un DLL para averiguar sus funciones, entenderlas y luego invocarlas desde un programa.

La famosa programadora Miss Terry Oza ha creado una librería de funciones para trabajar con listas pero no la quiere compartir con nadie (a menos que pasen un poco de trabajo). Has conseguido el DLL donde están implementadas sus funciones: MathFuncsDll.dll y su archivo acompañante MathFuncsDll.lib. Conociendo lo incordia que es Terry no será sorpresa que los nombres de las funciones que implementó no tengan nada que ver con su funcionalidad. La única pieza de información que tienes es que le encanta usar estructuras (en vez de clases). Su ex-jevo la espió una vez que estaba programando y vió que la estructura que utiliza para implementar sus listas es la siguiente:

struct List {
 int mySize;
 int myArray[1024];
};

También es de esperarse que las funciones realicen labores típicas de listas tales como crear, borrar elementos, insertar elementos, buscar tamaño, determinar si está vacía, imprimirla, etc.

Puedes encontrar los archivos DLL y LIB en:

Paso 1

Realiza reverse engineering a MathFuncsDLL.dll para lograr entender sus funciones. Puedes comenzar abriendo el DLL desde OllyDbg y averiguando las funciones que exporta. De ahí puedes explorar el código desensamblado de cada función para tratar de entenderla. Esto envuelve al menos:

  1. Entender sus parámetros y los tipos de los parámetros

  2. Entender el algoritmo que implementa

  3. Entender su valor de retorno (si alguno)

Documenta tus hallazgos.

Paso 2

Utiliza tus descubrimientos para (usando las funciones creadas por Terry) hacer un programa que:

  1. cree una lista
  2. valide que está vacia
  3. le inserte los números impares desde el 1 al 7
  4. borre el segundo número de la lista
  5. la imprima

El proyecto de Visual Studio testingTheDLL (disponible en http://ccom.uprrp.edu/~rarce/testingTheDLL.zip ) es un esqueleto para que pruebes el programa. Este proyecto presume que los files MathFuncsDLL.dll y MathFuncsDLL.lib viven C:\Windows\Temp. Cópialos a ese directorio para que Visual Studio los encuentre.

Nota el prototipo e invocación de las funciones abra y cadabra. El prototipo es así:

namespace MathFuncs{
 __declspec(dllimport) unsigned int abra(int a, int b);
 __declspec(dllimport) unsigned int cadabra(int a);
...
}

Cuando analices el DLL te darás cuenta que todas las funciones fueron creadas bajo el namespace MathFuncs. Por esto el prototipo de esas funciones debe incluir ese namespace. La especificación __declspec(dllimport) establece que las implementaciones de abra y cadabra se encuentra en algún DLL. Bajo condiciones normales, cuando utilizas las funciones de un DLL que ha sido provisto de buena fe tienes un archivo .h que contiene los prototipos de las funciones. Sin embargo, cuando solo tenemos el DLL debemos deducir los prototipos de las funciones y generarlos nosotros mismos.

Dentro de la función main podrás notar que la invocación a abra y cadabra se hace especificando su namespace seguido del nombre de la función.

std::cout << MathFuncs::abra(5, 10) << std::endl;
std::cout << MathFuncs::cadabra(21) << std::endl;

Entregables

A través de un link que se proveerá en Moodle, someta un zip que contenga:

  1. Un documento que describa el análisis que realizó a las funciones de la librería (paso 1)

  2. El archivo .cpp donde invoca las funciones (paso 2)