Compilador para hookear funciones

Iniciado por Halos, 2 Abril 2013, 14:07 PM

0 Miembros y 1 Visitante están viendo este tema.

Halos

Buenas, estoy haciendo un programa en C++ que me hookea varias funciones del sistema para monitorizar las acciones del usuario. Empecé hookeando el típico MessageBox y va sin ningún problema. El problema viene ahora cuando aspiro a algo más, como por ejemplo InternetConnect. Inyecto la DLL en el proceso sin ningún problema y se parchean bien las APIs de mi interés. La ejecución dentro de mi función no da fallos, pero el problema viene al hacer el 'retn'.

Con el Olly he visto que la pila queda niveles diferentes (que no se limpia bien al salir de la función inyectada) cuando vuelve de la llamada InternetConnectA sin hookear y hookeada. Me da la sensación de que la culpa es de mi compilador, ya que uso el g++ de MinGW. He probado el compilador de Borland y me da fallos que por lo visto se pueden arreglar si instalo la interfaz gráfica. El hecho es que yo soy más de editor de texto y terminal para programar y compilar. No sé si seguir buscando otro compilador más Microsoft y menos "linuxero" como el de MinGW o si es un fallo mio.

Básicamente mi manera de hookear es la siguiente:
1. Aprovechando el hotpatching de windows y hago un salto a los 5 bytes anteriores, donde se encuentra el salto a mi código (compilado con g++)
2. Desde mi código guardo en un fichero info de la conexión obtenida a través de los parámetros. Vamos, que no modifico los parámetros para nada. (El fallo no está en este código del fichero, probé a comentarlo y seguía dando el fallo).
3. Llamo a la función original.  (Esta dirección la obtendo sumando 2 a la dirección que me devuelve GetProcAddress, así evito el salto a mi código.
4. Devuelvo el valor que me ha dado la función original.

Mi sensación es que al mezclar código de windows con código compilado con g++ es cuando empiezan a ocurrir las cosas extrañas. ¿Puede ser esa la razón? ¿Qué usáis vosotros para crear vuestras DLL para inyectarlas?

Un saludo y gracias

Halos

#1
Sigo analizando qué es lo que ocurre y he visto que la función MessageboxA, cuando la hookeo, aunque no me da ningún problema, en verdad se queda la pila sucia, y cada vez con más y más basura.

Os dejo aquí el código de las funciones inyectadas: https://gist.github.com/anonymous/63c842a743a8ea49fea9

¿Puede ser que el fallo esté ne los typedef? Me da que por algún lado el código no sabe limpiar la pila porque no "sepa" la cantidad de parámetros que le llegó.

ukol

Hace mucho hice un hooker en C (con objetivo de hacerlo lo más que pudiera en C), ya no recuerdo mucho, me acordé porque ayer rebuscando por el disco buscando música encontré el proyecto aunque ya no sé donde está de nuevo :( y no tengo ganas de buscarlo.
Pero creo que había varios problemas.
Primero no usas el hotpatching de Windows, eso me lió un poco, corrígeme si me equivoco. O sea, lo haces tu a mano. Si no es así de esa tecnología no sé nada, seguro que encuentras info por ahí.
En otro caso, en C puro no lo puedes hacer (pero sí con extensiones de los compiladores).
C++ creo que es más complicado a nivel binario, añaden mucha porquería... no te sé decir.

Mmmm... cuanto lío, acabo de borrar un tocho que tenía escrito detallando las cosas a tener en cuenta...
creo que lo más sencillo es esto:
Coge el debuguer y pon un break en la api (en el patch), sigue paso a paso hasta volver a la función llamada, la pila tiene que ser la misma, es lo único que importa. Rastrea lo que la modificó.

(No leí el nuevo mensaje)

ukol

La convención de llamada por defecto de C/C++ no es cdecl? puede ser eso?

85

Me cerraron el Windows Live Spaces, entonces me creé un WordPress XD
http://etkboyscout.wordpress.com/

BloodSharp

Cita de: ukol en  2 Abril 2013, 15:06 PM
La convención de llamada por defecto de C/C++ no es cdecl? puede ser eso?

Sí, la convención por defecto de Mingw es cdecl, lo recuerdo por un problema que tuve de corrupción de pila en kernel en un hook de sysenter :silbar: (Lindas pantallas azules que tuve por eso...  :rolleyes:)

en cuanto al prototipo de tu función que apunta a la dirección original fijate que la declaraste con la convención stdcall, por lo cuál la función hookeada también debería estar escrita de la misma manera:

Ejemplo:
HINTERNET __stdcall HookerInternetConnect(...)


B#



Halos

Gracias por las respuestas! La cosa andaba por donde apuntasteis, por la convención de las llamadas utilizada. He compilado la DLL con el cambio que me sugirió IEAX añadiendo __stdcall en las funciones, ya que no era suficiente añadir el __stdcall en el typedef, y va a las mil maravillas.  ;-)

Gracias también por el enlace de 85. De depurar y depurar programas había visto que el manejo de la pila era diferente de un programa a otro, pero desconocía los diferentes estándares, así que no sabía la razón de poner el "__stdcall" en el typedef.

85

Me cerraron el Windows Live Spaces, entonces me creé un WordPress XD
http://etkboyscout.wordpress.com/