jueves, 5 de diciembre de 2013

Obteniendo la localización del teléfono (GPS) con C# en Windows Phone/ Windows 8 App

Con el fin de ahorrarme unas cuantas respuestas a correos electrónicos, voy a plasmar aquí un pedazo de código fuente en C# que sirve para obtener las coordenadas, posición o localización (como más os guste) de un dispositivo con Windows Phone 8 o aplicación de la tienda de Windows 8.

Obviamente es un código a modo de prueba de concepto, vosotros deberéis adaptarlo adecuadamente según la necesidad y por supuesto realizar las comprobaciones de errores pertinentes, más allá del Try/Catch de rigor.

using System;
using Windows.Devices.Geolocation;

namespace GPSTesting
{

public delegate void GeoCallback(double Latitud, double Longitud)

// Definición de la clase ... blah, blah, blah ...

public async void GPSCoordenadas(GeoCallback callback)
{
    try
    {
        Geolocator Localizador = new Geolocator();
        Localizador.DesiredAccuracy = PositionAccuracy.Default;
        Geoposition Posicion = await Localizador.GetGeopositionAsync();
       callback(Posicion.Coordinate.Latitude, Posicion.Coordinate.Longitude);
    }
    catch (Exception)
   {
        // ...
   }
}
}

¡Así de fácil! Que os aproveche.

Emulador de Windows Phone 8

Si tu intención es desarrollar aplicaciones para Windows Phone 8, una de las cosas que inevitablemente deberás conocer son los requisitos hardware/software que necesitarás.
 
A nivel de software, sin duda una de las soluciones más lógicas sería utilizar el SDK correspondiente, el Windows Phone SDK 8.0 y como no podía ser menos, el sistema deberá ser un Windows 8 Pro o superior.
 
Ahora bien, en la parte del hardware la cosa se te puede complicar un poco, debido a los requerimientos del sistema necesarios para poder ejecutar el "Emulador de Windowsl Phone 8". Cuando digo "requerimientos necesarios", en realidad lo que quiero decir es "Requerimientos OBLIGATORIOS".
 
A nivel de BIOS/CPU, tu equipo deberá soportar las siguientes características:
 
  • Virtualización Hardware (Hardware-assisted Virtualization)
  • Traducción de direcciones de segundo nivel (SLAT - Second Level Address Translation)
  • Prevención de ejecución de datos por Hardware (DEP - Data Execution Prevention)
 
Además, necesitarás:
  • 4 GB de RAM o más
  • Por supuesto 64 bits
  • Windows 8 Pro de 64 bits
 
A nivel de red:
  • DHCP
  • Configuración automática de DNS
 
Ya en el sistema operativo deberás activar Hyper-V y tu usuario deberá pertenecer a un grupo de administradores de Hyper-V para evitar problemas de permisos con el emulador.
 
De todo esto, es posible que una de las cosas que más te pueda provocar dolores de cabeza sea SLAT. En cualquier caso, para saber si tu equipo reúne las condiciones adecuadas, puedes hacer uso de la herramienta COREINFO de Mark Russinovich, que puedes descargar en Technet de Microsoft (los vagos aquí tenéis el enlace http://technet.microsoft.com/en-us/sysinternals/cc835722.aspx)
 
Una vez ejecutéis dicha herramienta y observéis los resultados que os muestra, no desesperéis a la primera de cambio, quizás tengas una última oportunidad de reunir los requisitos. Por ejemplo, entra en la BIOS de tu equipo y comprueba si la virtualización está activada.
 
Ni que decir tiene que si tu equipo no reune tales condiciones, la mejor opción es adquirir un móvil con Windows Phone 8 para hacer el testeo de tus aplicaciones, algo que sin duda, siempre es recomendable incluso utilizando previamente el emulador.
 
Nuevamente tocará invertir para ampliar infraestructura de desarrollo.

lunes, 27 de mayo de 2013

Policías y Ladrones - Crónicas de la 2

Aquí os dejo el vídeo de un documental emitido en la 2, en el programa Crónicas. Trata sobre la ciberdelincuencia o ciberdelitos, desde el punto de vista del Grupo de Delitos Telemáticos de la Guardia Civil, la Brigada de Investigación Tecnológica de la Policía y Profesionales del mundo de la Seguridad Informática.
 
Sin duda un documental muy interesante para CONCIENCIAR a todos aquellos escépticos o "ignorantes" -con todos los respetos del mundo-, que piensan que la seguridad informática no es para ellos, porque ¿Quién va a querer algo de mi ordenador? ¡Si yo no tengo nada que esconder ni que merezca la pena! La respuesta es muy sencilla ¿Quién querría entrar en tu casa y para qué? ¿Quién querría robar tu vehículo y para qué? ¿Quién querría secuestrarte y para qué? Si total, no eres un personaje público, famoso, millonario, etc.
 
Tened mucho cuidado con vuestros dispositivos electrónicos. Si estáis conectados a la red, ya corréis el riesgo y aunque "solo" sea para cometer un delito desde vuestro ordenador, teléfono móvil, etc. ya sois perfectos objetivos, aunque no creáis tener nada importante que proteger.
Por cierto, me permito daros un consejo, ahora que llega el verano recordad que no es recomendable que publiquéis en vuestros servicios de redes sociales y demás (Facebook, Twitter, Google+, Tuenti, WhatsApp, Line, etc) que os vais de vacaciones a las Maldivas desde el 15 de Junio al 1 de Julio, mas que nada, porque en cierto modo le estarás contando a los malos que "tu casa probablemente quede vacía".
 

sábado, 11 de mayo de 2013

Ingeniería Inversa de Firmware en un PIC 16Fxxx de Microchip

Como parece que no tengo mejores cosas que hacer, no se me ocurre otra forma mejor de pasar una tarde de Sábado que hacer un poco de Ingeniería Inversa a un microcontrolador PIC de la casa Microchip.
 
En esta ocasión se trata de un microcontrolador de la familia 16Fxxx (tipo 16F876, 16F84, etc.) cuyos opcodes tienen un tamaño de 14 bits. El mismo sistema será válido para otros microcontroladores de otras familias o incluso fabricantes, incluso aún cambiando la arquitectura del microcontrolador, la base esencial del análisis será similar en multitud de casos.
 
Siempre que se me plantea una situación similar, me gusta entender los entresijos de lo que tengo entre manos y, en la medida de lo posible intento empezar "a mano" o "a pelo" en el proceso de obtención de los Nemotécnicos ó, en definitiva las instrucciones en lenguaje ensamblador.
 
A continuación os muestro un pequeño pedacito de un firmware que he estado analizando, se trata del comienzo del mismo y, ni que decir tiene, que intentar analizar el funcionamiento de un programa observando tan solo estos números:

0F28CE00030E83128F00040890000A0891004F089200492B ...
 
es de paranóico/marciano, como poco. Si hay alguien en el planeta que observando esas ristras de números es capaz de interpretar la lógica que esconden, que me lo presenten, por favor.
 
En definitiva, cuando se trata de entender el funcionamiento de un software/firmware del cual no tenemos su código fuente, la cosa se complica bastante como para ponerse a leer números. Esto no funciona así, en su lugar, un primer paso consiste en transformar esos números en los citados Nemotécnicos que conformaran el programa en lenguaje ensamblador, sin duda, mucho más inteligible para el ser humano.
 
Incluso, en algunas circunstancias, se da un paso mas allá y se genera un código fuente en un lenguaje de más alto nivel o pseudocódigo, que podría ser utilizando nuestras propias palabras o basándonos en un lenguaje de programación estándar.
 
Bueno, no me quiero enrrollar más con palabrería así que, voy al grano.
 
La idea es bastante simple, extraemos el firmware de la memoria del microcontrolador o si se da el caso de la memoria externa en donde se encuentre alojado. Inicialmente se tratará de una ristra de ceros y unos, para finalmente obtener valores hexadecimales y por último los preciados nemotécnicos del lenguaje ensamblador equivalente.
 
Así, en el trozo del ejemplo anterior, el equivalente en código binario (0's y 1's) de los valores 0F28CE0003 sería:
 
111100101000110011100000000000000011

Si los agrupamos de 8 en 8 bits, lo podremos convertir fácilmente a valores hexadecimales equivalentes a 1 byte:

00001111 = 0x0F
00101000 = 0x28
11001110 = 0xCE
00000000 = 0x00
00000011 = 0x03

Y así con todo, pero bueno lo que quiero dejar en claro, es que nosotros inicialmente lo único que podemos "sacar" del microcontrolador serán "una corriente" de ceros y unos, los cuales agruparemos de 8 en 8 para formar bytes y poder representar más fácilmente los distintos opcodes en formato hexadecimal.
 
Una vez tenemos los valores en hexadecimal, la obtención de los nemotécnicos es relativamente sencilla, aquí es donde las cosas empezarán a cambiar de unas arquitecturas de microcontrolador a otras.
 
En el caso que nos ocupa de la familia 16Fxxx de Microchip, tenemos opcodes de 14 bits, lo que nos hace ver claramente que tendremos que tomar los valores de dos en dos bytes. Volviendo al ejemplo, los valores quedarían separados de la siguiente manera:

0F28 CE00 030E 8312 8F00 0408 9000 0A08 9100 4F08 9200 492B ...

Como os podeis imaginar, hacer todo este proceso a mano es una locura, aquí tan solo tenemos unos pocos opcodes, pero un firmware del mundo real, por ejemplo el que podemos encontrar en un mando a distancia moderno, el ordenador de abordo de un coche, una televisión, un teléfono móvil, etc se compone de miles/millones de opcodes. ¡Aquí tan solo estoy mostrando 12!
 
Pero claro, hacerlo de esta forma, te obliga a entrar de lleno en las tripas del microcontrolador a un muy bajo nivel. Entender la arquitectura del microcontrolador, su conjunto de instrucciones, interpretación de las tablas de opcodes, organización de la memoria, registros, etc, etc. Y esto es lo que a mi me gusta.
 
¡Seguimos!. Por último y de momento, el siguiente paso después de obtener los valores agrupados de dos en dos bytes, es convertirlos a sus opcodes equivalentes y, en el caso del ejemplo aquí los tenemos:

280F goto  0x00F  
00CE movwf memoria_4e   
0E03 swapf STATUS, W
1283 bcf   STATUS, 5
008F movwf memoria_0f   
0804 movf  FSR, W   
0090 movwf memoria_10   
080A movf  PCLATH, W
0091 movwf memoria_11   
084F movf  memoria_4f, W
0092 movwf memoria_12   
2B49 goto  ETQ_349


Ahí tenemos el pedacito de programa en lenguaje ensamblador mucho más fácil de interpretar, aunque todavía se puede mejorar y mucho. Además si observáis, hay varias cosas que os deberían llamar la atención. La primera es con los valores en hexadecimal, os habréis dado cuenta de que están "invertidos" los bytes con respecto a los originales del ejemplo. Bueno, esto tiene nuevamente que ver con la arquitectura del microcontrolador y como gestiona su memoria. En este caso, se almacenan con el valor menos significativo primero y el más significativo después lo que en informática denominamos como Little-Endian (su opuesto sería el Big-Endian), pero bueno, esto es otro tema.
 
Con el fin de mejorar todavía un poco más el código ensamblador generado, he añadido las direcciones de memoria en la primera columna, para ver claramente que el primer salto (goto) se hace a la dirección indicada por 0x0F, a la cual la he "etiquetado" como Inicio_00F. También se ve claramente que el programa inicia su ejecución en la dirección 0x04, etc.
 
Explicar aquí porque empieza el programa con esa primera instrucción de salto, tampoco es plan, pero por si os pica la curiosidad, tiene que ver con el vector reset (trocito de programa que ejecuta el microcontrolador cuando se produce una interrupción de tipo reset y bla, bla, bla).

Vector_Reset  org 0x000
        goto            Inicio_00f  ; 280F



Vector_Reset  org 0x000
 
04      movwf           mem_4e      ; 00CE
05      swapf           STATUS, W   ; 0E03
06      bcf             STATUS, 5   ; 1283
07      movwf           mem_0f      ; 008F
08      movf            FSR, W      ; 0804
09      movwf           mem_10      ; 0090
0A      movf            PCLATH, W   ; 080A
0B      movwf           mem_11      ; 0091
0C      movf            mem_4f, W   ; 084F
0D      movwf           mem_12      ; 0092
0E      goto            ETQ_349     ; 2B49


0F Inicio_00f

        ...


Como veis, se trata de un tema muy interesante que da mucho de sí. Podría estar horas y horas escribiendo sobre el tema hasta producir varios libros probablemente, pero como introducción para aquellos que os queráis animar, ya da!
 
Me consta que varías cosas de las que he hablado quedan en el aire, pero entenderéis que no es el objetivo de este post. Doy por supuesto, que los que estéis leyendo este post ya sabéis de que van todos esos detalles (código binario, conversión a hexadecimal, registros, organización de memoria, estructura de un opcode, etc.)
 
¡Menudo un rollo que he soltado! No se que será peor, si que yo lo escriba o que vosotros lo leáis, en fin, un saludo!

miércoles, 8 de mayo de 2013

La interrupción del minuto

Desde hace muchos años mi cabeza es una nube de pensamientos, ideas e intenciones como consecuencia de la inmensa cantidad de temas que despiertan mi interés, más claro está, las obligaciones contractuales que todos tenemos con nuestros trabajos y/o familias.
 
Esta situación, hace que mi tiempo libre de obligaciones, deje de ser tiempo libre. Conclusión:

"Todo mi tiempo está ocupado"

Para disponer de tiempo libre, es decir, ese tiempo que dedicamos a NO HACER NADA, es preciso organizarse, de lo contrario, no conseguirás ninguno de tus objetivos, o al menos te resultará más costoso hacerlo.

La única manera de conseguir alcanzar con éxito todas aquellas tareas que me propongo, ha sido, es y probablemente será la organización. Sí, ya lo sé, esto que acabo de decir es obvio, pero cuidado, organizarse cuando pretendemos hacer infinidad de cosas, no es labor sencilla y, es preciso recurrir a algún método eficaz para alcanzar nuestros objetivos de forma satisfactoria y sobre todo placentera.
 
Hoy por hoy, puedo decir que utilizo un método eficaz, quizás algún día escriba algo sobre esto (lo anotaré para no olvidarlo y así aligerar "my head"). Como podéis ver de mi frase anterior, a cada paso, estamos generando nuevas tareas, ideas o intenciones, en este caso, he generado una nueva intención: publicar algo sobre mi sistema de gestión del tiempo.

Recurrir a las listas de tareas, gestión de prioridades, planificación de proyectos, división de tareas en sub-tareas, el uso correcto de la agenda, notas temporales tipo pos-it con el fin de aligerar nuestro "coco" y un largo etcétera más de técnicas, es algo que se convierte en el pan de cada día, pero hay algo importante que debemos tener siempre muy presente: las interrupciones

Debemos tener claro y asumido cuan hábito inspiratorio o espiratorio, que la tarea más importante siempre será la que estemos realizando en cada momento y que esta no debe interrumpirse bajo ningún concepto, salvo en casos extremos y por cuestiones de prioridad (asumiendo los riesgos o consecuencias)

Dicho esto, viene el tema de este post. La famosa y peligrosa frase:
 
¿Tienes un minuto?
 
¡Cuidado cuando oigáis esta frase! Si estas en medio de una tarea, la respuesta debería ser "NO", salvo determinados casos que tendremos que saber valorar.
 
Mi experiencia me dice, que cuando se nos interrumpe con la pregunta ¿Tienes un minuto? al final, casi siempre, termina siendo más de un minuto y, en multitud de ocasiones, esa interrupción genera nuevas tareas, ocupaciones o lo que es peor preocupaciones que no harán más que entorpecer, retrasar y alterar el flujo de ejecución de nuestra actual tarea.

Por lo tanto, a partir de ahora cuando alguien os pregunte ¿Tienes un minuto? Piénsatelo dos veces antes de responder rápidamente con un "SI". Quizás sea más correcto responder con frases del tipo:

  • ¿Te importa si te atiendo más tarde?
  • ¿Es urgente?
  • Llámame dentro de una hora

 En definitiva, intentar posponer la interrupción para otro momento en el que si preveas disponer de "1 minuto"
 
¡Ojo! ¿Tienes un minuto? es similar a:
 
  • Suena el timbre pero yo no espero a nadie
  • Suena el teléfono pero yo no espero llamada urgente de nadie
  • etc.
¡Cuidado con todas estas situaciones de índole interruptor!

domingo, 28 de abril de 2013

Google Glass - Unas "gafas" futuristas que ya están aquí.

A mi personalmente la idea me parece genial. Un dispositivo práctico, cómodo y desde luego parece bastante prometedor. Se puede acoplar fácilmente a tus propias gafas, lo cual, desde un punto de vista estético, también es importante. Quisiera tener el gusto de probarlas, pero de momento no han caido en mis manos.



Para los que no lo conozcáis, Google Glass permite proyectar (gracias a un micro-proyector),
imágenes sobre la escena real que visualizamos. Interesante para mostrar en tiempo real, información sobre el tiempo, noticias, correo, mensajes, GPS, incluso me atrevo a añadir las constantes vitales, con los sensores adicionales pertinentes (esto ya es apreciación mía) etc.



Aquí tenéis la web de Google Glass donde podéis ver más imágenes y un video:


Pero bueno, independientemente de todo esto, a mi personalmente la parte que más me interesa, como de costumbre es responder a la pregunta ¿Cómo?, puesto que el ¿Qué? y el ¿Por qué? son más que evidentes.

Y con respecto al ¿Cómo?, nada mejor que tener acceso al código fuente del KERNEL que forma tan futurista artefacto.

Pues sí, Google a liberado bajo licencia GPL el código fuente del kernel de "Google Glass" y para los interesados lo podéis descargar desde la página web del proyecto:


Eso sí, os adelanto de antemano, que se trata de un archivito comprimido de unos 65 MBytes, que una vez descomprimido se quedará en unos 500 MBytes y que arroja la friolera de más de 37700 archivos repartidos en unos 2300 directorios (carpetas de las de ahora :) Para los que hayan "metido mano" al kernel de Linux, esto no les sorprenderá, es más, el kernel de Google Glass existe gracias al kernel de Linux, al igual que Android -no se trata de kernels creados desde cero-

La inmensa mayoría de estos archivos son código fuente en lenguaje "C" y "Ensamblador". Así que ya sabéis, si estáis aburridos y no sabéis que hacer, pues a jugar un rato con esas miles y miles de líneas de código.

Con respecto a la parte hardware, todavía no he podido comprobar nada, esencialmente se basa en un micro-proyector y una especie de prisma sobre el cual se proyecta la imagen superpuesta. Según tengo entendido contará con una resolución de 640x360 pixels, una cámara de 5MP capaz de capturar imagen o video en HD 720p,  conectividad WiFi 802.11 b/g y Bluetooth, unos 16 GB  de unidad de almacenamiento, supongo que "ampliables", micrófono, altavoces, etc.

 
En esta imagen si os fijáis bien, se puede apreciar "el prisma" o la "pantalla en ángulo" que hace posible que podamos ver la imagen proyectada. NOTA AL MARGEN: A modo de experimento, tomad una lupa, una hoja de papel vegetal o papel cebolla y "proyectar" la imagen de la televisión sobre el papel, variad el ángulo del papel con respecto a la lupa y veréis lo que sucede. Tendréis que variar la distancia desde la lupa al papel para lograr una imagen nítida, lo cual va en función de la "Longitud focal" de la lupa. Una vez encontrado el punto de foco, ¡voilá!


Aquí podéis ver una infografía sobre su funcionamiento:


Habrá que esperar a que caiga una en nuestras manos para poder hacer una análisis real, pero mientras tanto, ya tenemos información suficiente para entretenernos un largo rato.

Por cierto, antes de "meterle mano" al kernel de Google Glass, os recomiendo que bajéis a la farmacia a por un par de cajas de "aspirina plus extra forte a tuti pleni" ;)

Saludos!

viernes, 26 de abril de 2013

WinDbg - Setting breakpoint on Entry Point

Hay varias formas de localizar el punto de entrada (EP) de un programa, y aquí expongo un par de ellas. La primera es la más sencilla y rápida, la segunda un poco más compleja pero que abre el abanico de opciones.

WinDbg como sabemos dispone de varios pseudo-registros predefinidos que nos facilitan bastante las sesiones de depuración. Uno de estos registros es $exentry. Para colocar un breakpoint en el punto de entrada del ejecutable basta con escribir este comando:

0:000> bu @$exentry

El segundo método es un poco más enrevesado pero igualmente válido. Consiste en localizar manualmente el entrypoint mediante el uso de las cabeceras PE del módulo. Para ello, lo primero que hacemos es buscar la ImageBase del ejecutable. Esto lo podemos conseguir con el comando LM que nos dará el ImageBase y el ImageSize, pero también podemos localizarlo con el comando !PEB que nos muestra información sobre el proceso (PEB - Process Environment Block)

Una vez tenemos la ImageBase tenemos que buscar la dirección del entry point en las cabeceras del módulo. Existe una cabecera opcional de valores en el formato PE que nos muestra este dato. Para ello ejecutamos el comando:

0:000>  !dh ImageBase.

De toda la información que nos muestra este comando, nos quedamos con "Adress of Entry Point". Se trata de una dirección relativa a la ImageBase, por lo tanto el EntryPoint real lo calculamos sencillamente sumando ambos valores.

Para colocar el breakpoint con este método utilizamos el siguiente comando:

0:000> bp ImageBase + EntryPoint

Por supuesto, hay herramientas externas a WinDbg que nos proporcionan estos datos, pero para ejecutables que no están comprimidos y/u ofuscados, estos métodos van perfecto!

sábado, 20 de abril de 2013

Force ASLR - Trasladando forzosamente la ImageBase

Si ASLR (Address Space Layout Randomization) se introdujo como un nuevo sistema de mitigación de ataques al sistema operativo Windows Vista (sí también a Linux y otros), con la aparición de Windows 7 y Windows Server 2008 R2 Microsoft ha querido fortificar aún más esta técnica mediante una actualización que incorpora lo que han denominado como "Force ASLR" algo así como ASLR Forzoso u obligatorio.

Con ASLR, el sistema operativo lo que persigue es aleatorizar o trasladar el espacio de direcciones de las librerías y aplicaciones con cada reinicio, de tal forma, que no sea predecible la ubicación de su dirección base. Como consecuencia, averiguar por ejemplo, la dirección de una determinada API del sistema o porción de código de una aplicación ya no es tan trivial (que no imposible).

Esta característica está activada por defecto en la mayor parte de las librerías del sistema operativo y, en bastantes programas siempre y cuando el desarrollador active el flag /DYNAMICBASE en el momento del "linkado".

Aquí aparece el primer "punto débil" de ASLR, ya que, debe ser el desarrollador el que decida si activarlo o no. Ahora bien, esto dependerá del entorno de desarrollo utilizado, ya que por ejemplo con Visual Studio 2008 en adelante, estará activado por defecto, no así con otros compiladores.

Bien, dicho esto sobre ASLR, aparece en acción "Force ASLR" con el fin de proteger aquellas librerías o programas cuya característica o flag /DINAMICBASE no está activado.

Con esta actualización, tenemos a nuestra disposición una nueva clave en el registro de windows:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\

En esa sub-clave podemos crear una nueva entrada por cada programa o módulo que queramos proteger. Para ello, tan solo hay que añadir una nueva clave con el nombre de imagen exacto del programa (Botón derecho/Nueva clave). A continuación deberemos añadirle a esa clave un nuevo valor de tipo QWORD (Botón derecho/Nuevo/Valor QWORD) y lo renombramos como: MitigationOptions.

A esta nueva entrada la podemos asignar uno de los valores siguientes:
  •  0x000 : No asignado
  •  0x100 : Aleatorización activada
  •  0x200 : Aleatorización explícitamente desactivada
  •  0x300 : Aleatorización activada con fallo de carga del módulo
En el primer caso (0x000), se indica de manera explícita que "Force ASLR" no ha sido asignado.

En el segundo caso, el valor 0x100, indica que se active ASLR para el módulo indicado, pero debemos tener en cuenta que solamente se aplicará la aleatorización del espacio de direcciones, en el caso de que el módulo disponga de la "Relocation Table", en caso contrario, el módulo será cargado, si procede, en la dirección indicada en su campo "ImageBase"

En el tercer caso (0x200) se indica de manera explícita que "Force ASLR" ha sido desactivado para ese módulo concreto.

Y finalmente, el último valor (0x300) activa ASLR al igual que el valor 0x100), pero en esta ocasión si el módulo no dispone de la tabla de reubicaciones (Relocation Table), en lugar de cargarlo en su "ImageBase", se producirá un error de carga.

En cualquier caso indicaros que hay herramientas (EMET) que permiten utilizar todo esto sin necesidad de manipular de forma manual el registro de windows, lo cual, como sabéis puede tener consecuencias catastróficas para el sistema operativo y/o el resto del software.

ADVERTENCIA: Modificar estos valores puede hacer que ciertos programas funcionen de manera anómala, tened en cuenta que si en algún programa hacen "uso directo" de las direcciones de memoria "pre-supuestas" y activamos "Force ASLR" estas obviamente cambiaran.

jueves, 11 de abril de 2013

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!

viernes, 5 de abril de 2013

WinDbg Symbols Path

Si estás leyendo esta entrada del blog supongo que ya sabes perfectamente la importancia que tienen los símbolos (Públicos y Privados) a la hora de depurar software. En esta ocasión me voy a centrar en las formas que tenemos para indicarle al depurador de Microsoft donde se encuentran los símbolos.

En el caso de WinDbg lo podemos especificar de diversas maneras:

  • Desde línea de comandos con el comando -y
  • Utilizando la variable de entorno _NT_SYMBOL_PATH ó _NT_ALT_SYMBOL_PATH
  • Desde el menú File\Symbol File Path
  • Utilizando el comando .sympath

Los símbolos pueden residir en una unidad de almacenamiento local (Ej. el disco duro) o bien proceder de una fuente o servidor remoto.

En el la caso de una unidad local, indicaremos la ruta completa a los mismos, ej.;

.sympath d:\desarrollo\windbg\symbols

Cuando tengamos que cargar los símbolos desde un servidor remoto lo indicaremos así:

.sympath srv*http://msdl.microsoft.com/download/symbols

También podemos indicar ambos casos en una sola instrucción:

.sympath d:\desarrollo\windbg\symbols;srv*http://msdl.microsoft.com/download/symbols

Es recomendable "cachear" los símbolos de forma local para evitar conectar con el servidor remoto cada vez que los necesitemos. Esto lo podemos conseguir utilizando el parámetro "cache":

.sympath cache*d:\desarrollo\windbg\symbols;srv*http://msdl.microsoft.com/download/symbols

Por último, aclarar que si queremos configurar el "path" desde el menú File/Symbol File Path, no es preciso incluir el comando .sympath

viernes, 1 de marzo de 2013

Defensa crea el Mando Conjunto de Ciberdefensa

¡ Por fín, ya era hora majos! Pero bueno, más vale tarde que nunca.

El ministro de Defensa, Pedro Morenés, ha creado ya el Mando Conjunto de Ciberdefensa, con el que las Fuerzas Armadas se protegerán frente a ciberataques y contribuirán a la ciberseguridad del país, para lo que podrán desarrollar una "respuesta oportuna, legítima y proporcionada" ante "amenazas o agresiones".

Pulsa aquí para leer la noticia completa

jueves, 31 de enero de 2013

Inicializar un std::vector en C++

Lo primero que tenemos que hacer es crear la plantilla que se va a utilizar para inicializar los vectores:

template <typename T>
class init_vector {

public:

init_vector<T>& operator<< (const T& value) {
    internal_vector.push_back(value);
    return *this;
}

operator std::vector<T>() const {
    return internal_vector;
}

private:

std::vector<T> internal_vector;

};

A la hora de inicializar un vector podemos utilizar esta plantilla de manera muy sencilla y elegante:

std::vector<int> v = init_vector<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9;
std::vector<string> empresas = init_vector<string>() << "Google" << "Microsoft" << "Apple" << "Nokia";



Bucles for basados en rango, Inferencia de tipo y Referencia

#include <vector>

int main()
{
    std::vector<string>meses;
    meses.push_back("Enero");
    meses.push_back("Febrero");
    meses.push_back("Marzo");
    meses.push_back("Abril");
    meses.push_back("Mayo");
    meses.push_back("Junio");
    meses.push_back("Julio");
    meses.push_back("Agosto");
    meses.push_back("Septiembre");
    meses.push_back("Octubre");
    meses.push_back("Noviembre");
    meses.push_back("Diciembre");

    // Mostrar en consola los meses utilizando un bucle for basado en rango.    

   for (string m: meses) {
       cout << m << endl;
        //m = "cadena_no_se_puede_modificar";
   }
   


    // Con inferencia de tipo.
   for (const auto m: meses) {
       cout << m << endl;
       //m = "cadena_no_se_puede_modificar";
   }

    // Con inferencia de tipo y referencia

    for (auto& m: meses) {
       cout << m << endl;
       m = "cadena_modificada";
   }
}