Ir al contenido principal

WinDbg Breakpoint on key pressed

Imaginad por un momento que os surge la necesidad de detener la ejecución de un programa cuando se pulsa una determinada tecla o combinación de estas, en fin, algo normal que a cualquier persona se le puede pasar por la imaginación, ¿o no?. Bromas aparte, para conseguirlo podemos utilizar infinidad de técnicas y en esta ocasión voy a comentaros la última que he empleado yo en uno de los trabajos que estoy realizando actualmente.

Esta técnica consiste en colocar un punto de ruptura en la llamada a la API TranslateAccelerator. Ahora bien, debemos tener en cuenta que si colocamos un breakpoint de ejecución sin más, el debugger estará constantemente saltando y no podremos conseguir nuestro objetivo o, cuando menos, será muy desesperante.

Para evitar tal situación, lo que tenemos que hacer es utilizar un breakpoint condicional para indicarle al debugger que se detenga solamente cuando se cumple una determinada condición o condiciones y por consiguiente que continúe con la ejecución normal del programa en el resto de los casos.

A modo de ejemplo y haciendo uso de uno de los depuradores que más me gusta (sí el depurador de Microsoft), vamos a detener la ejecución del programa cuando se pulse la tecla INTRO. Para esto, es preciso conocer tanto el prototipo de la API TranslateAccelerator que podéis ver a continuación:

int WINAPI TranslateAccelerator(
  _In_  HWND hWnd,
  _In_  HACCEL hAccTable,
  _In_  LPMSG lpMsg
);


como las estructuras de datos involucradas, ya que, si os fijáis el tercer parámetro de la API es un puntero a la estructura MSG. En este caso la principal estructura que debemos conocer es MSG, ya que necesitaremos hacer buen uso de algunos de sus miembros:

typedef struct tagMSG {
  HWND   hwnd;
  UINT   message;
  WPARAM wParam;
  LPARAM lParam;
  DWORD  time;
  POINT  pt;
} MSG, *PMSG, *LPMSG;


Llegados a este punto, ya conocemos bien a nuestro objetivo y cómo podemos "jugar" con él. Ahora tan solo falta saber cómo le decimos al depurador que utilice toda esta información. Aunque puede hacerse de varias formas, la técnica que expongo aquí es mediante el uso del evaluador de expresiones al estilo C++ que incorpora el debugger.

Si observamos la estructura MSG, enseguida nos damos cuenta de que hay varias cosas muy útiles para conseguir nuestro objetivo. Dado que queremos detener la ejecución del programa al pulsar una tecla, será preciso acceder al miembro 'message' de MSG.

En concreto el mensaje que vamos a capturar será WM_KEYDOWN cuyo valor constante equivalente en hexadecimal es el 0x0100. Además, como no queremos que se detenga la ejecución al pulsar cualquier tecla, sino solamente la tecla ENTER, también tendremos que utilizar el miembro 'wParam' que nos indicará cual es la tecla (VK_KEY) que se ha pulsado. En este caso para la tecla ENTER el valor que deberá contener 'wParam' será 0x0D (ya sabéis el número de la suerte).

Bueno, pues ahora sí que tenemos a nuestro alcance todo lo que necesitamos, así que, manos a la obra. Vamos a indicarle al debugger cual será nuestro maravilloso breakpoint:

bp 003814ac "j @@c++((((ole32!MSG *)@eax)->message == 0x0100) && (((ole32!MSG *)@eax)->wParam == 0x0D)) ''; 'gc'"

Como digo, hay muchas maneras de conseguir esto mismo, pero para mi caso concreto, esta era la más efectiva. La expresión habla más o menos por si sola, no obstante si tenéis alguna duda, sentiros libres de comentarlo.

¡Suerte y feliz debugging!

Comentarios

Entradas populares de este blog

Como usar el TL431 (muy facil)

En este artículo, no vamos a entrar en el funcionamiento interno de este IC, ni tampoco en sus características técnicas, puesto que para esos fines ya existe su hoja de datos correspondiente. Más bien, lo que pretendo aquí es dejar constancia de como podemos utilizar este IC desde un punto de vista práctico, útil y sobre todo de una manera sencilla, con el objetivo de que cualquiera pueda utilizarlo. Si has llegado hasta aquí, probablemente ya sabes que por internet hay mucha información sobre este IC, pero también bastante confusa o excesivamente técnica, sin mostrar tan siquiera un ejemplo de funcionamiento, o como calcular sus pasivos. Pues se acabó, a partir de hoy y después de leer este post, ya te quedará claro como utilizar el TL431 para obtener una tensión de referencia estable y precisa. Vamos al grano y que mejor que empezar aclarando que el TL431 NO ES EXACTAMENTE UN ZENER como se empeñan en decir en muchos sitios, es verdad que se le conoce como el Zener Progra...

Driver L293D de Texas Instruments

El L293D de Texas Instruments es sin lugar a dudas un circuito integrado de un gran valor cuando necesitamos controlar motores de corriente continua o bipolares de pasos (Bipolar stepping motors) Es cierto que se trata de un puente en H (o medios puentes), en este caso cuádruple, que sin bien podríamos crearlo con transistores, el echo de que se encuentre integrado en un único chip es de agradecer. Capáz de conducir corrientes bidireccionales de hasta 1 amperio en el modelo L293 y hasta 600 mA en el modelo L293D y con tensiones que van desde los 4.5V hasta los 36V en ambos modelos. Por supuesto podemos utilizarlo en otras aplicaciones o para controlar otros componentes: motores de corriente continua, relés, motores de paso bipolares, solenoides en general y cualquier carga que requiera una alta corriente y tensión. Las entradas son de tipo TTL y se activan por parejas, es decir, desde la pata Enable 1,2EN, activamoslas entradas 1 y 2 y desde la pata Enable 3,4EN activamos la 3...

El Robin Hood de los procesos pobres (Vamos de escalada)

Pues sí, has leído bien, hoy nos vamos de escalada, pero ojo! No nos vamos a las montañas, nos vamos al interior, al kernel del sistema operativo Windows 10 en esta ocasión, aunque es aplicable a otras versiones con algunos mínimos cambios. Hoy la cosa va de EoP (Elevation of Privilege), escalada de privilegios en el sistema. Vamos a ver cómo hacer de Robin Hood para "mangarle" el “Access Token” al usuario "NT AUTHORITY\SYSTEM" a través de la estructura _EPROCESS del proceso “System” para dárselo al pobre CMD.EXE. ¿Con qué fin? Pues darle poder absoluto sobre el sistema a un usuario limitado, por ejemplo para que pueda utilizar la calculadora, o el notepad sin limitaciones :) Venga vale, que es broma, que en realidad será para utilizarlo en una shellcode y un driver de dispositivo firmado por alguien :) Antes  de  comenzar  hay  que  dejar  claro  que  vamos  a  necesitar  algunas herramientas para realizar este proce...