CLR via WinDBG – Introducción (importancia de las bases)

CLR via Windbg va a intentar ser una serie de posts donde veamos int.detacherioridades de la plataforma .Net a través de la herramienta de depuración WinDBG, nos conectaremos a procesos, veremos la relaciones entre clases del framework, utilización de memoria, Garbage colector, depuración de problemas típicos….

Antes de empezar la serie dedicada a .Net tenemos que hacer algo de trabajo previo para familiarizarnos con la estructura de un proceso Win32 y depuración básica con WindBG (no voy a entrar en threads, hilos…son lineas generales, para preguntas concretas utilizad los comentarios del blog), nada demasiado complicado, será como hacer un croquis de una habitación para saber cómo movernos por ella con los ojos cerrados 😉 

Aunque todavía no os haya dado info para instalar la herramienta, cargar procesos… iré poniendo salidas de diferentes comandos para que veáis algo de parte práctica.

So….let’s kick it!

Al compilar estamos haciendo que nuestro código fuente se aloje en un archivo con una estructura preparada para cargarse en memoria ( Portable Executable ), ya sea para ejecutarse por si mismo o para ser un recurso para otro código. En esa estructura podemos encontrar información como: Dirección base donde se intentará cargar el módulo en la memoria, la Import Address Table, cabeceras con información relativa a la ejecución, variables globales, cabecera CLR en caso de ser un proceso .NET…

Cuando esa estructura se carga en memoria y se le asignan recursos para ejecutarse podemos hablar de que forma parte de un proceso. Con el depurador, podemos adjuntarnos a procesos y obtener cualquier información de estos, como las cabeceras, el código, la memoria virtual del proceso (hasta 2Gb si no utilizamos ningún flag /3gb), los diferentes threads con sus callstacks…

Una vez el proceso esta en ejecución, lo que nos interesa a nosotros es, o bien obtener un volcado de memoria con toda la información relativa al proceso (importante cuando hay un problema mientras el proceso se ejecuta y no podemos pararlo porque sigue dando un servicio) o bien nos adjuntamos a el y lo vamos depurando mientras se va ejecutando. En cualquier caso, para que un depurador se adjunte a un proceso (ya sea para volcar información a un archivo o para depurarlo en vivo), lo que pasa entre bastidores es que el proceso del depurador hace un createRemoteThread para poder trabajar en el proceso remoto y acceder a sus estructuras.

De modo que, si según nos adjuntamos a un proceso listamos todos sus threads, veremos que uno de ellos es un thread recién creado. (Tened en cuenta que lo que véis a continuación en una pila de llamadas, de modo que hay q leerlo de abajo a arriba)

ChildEBP RetAddr
0181fc48 7780f0a9 ntdll!DbgBreakPoint
0181fc78 76423833 ntdll!DbgUiRemoteBreakin+0x3c
0181fc84 777ba9bd kernel32!BaseThreadInitThunk+0xe
0181fcc4 00000000 ntdll!_RtlUserThreadStart+0x23

IMP –> Hace falta tener privilegios sobre el proceso al que nos vamos a adjuntar, de modo que o bien lo creamos nosotros (arrancamos el proceso desde el propio depurador), o bien somos administradores.

 

Batallita Las bases son muy importantes para saber por donde nos movemos, . Como no vamos a hacer un curso de arquitectura de computadores, ni de compiladores, las bases irán saliendo según vayamos avanzando. Intentar’e explicarlas para los que las tengan más oxidadas 🙂

Tuve un caso donde una sección crítica se quedaba huérfana y no había forma de saber porqué, una opción era poner un breakpoint en las funciones EnterCriticalSection y LeaveCriticalSection de ntdll para ver quien pedía/liberaba la sección crtítica . El problema es que si yo pongo un breakpoint en esas funciones….van a dispararse les llame el módulo que les llame!!! Lo que a mi me interesaba era que se disparasen sólo cuando llamase un módulo específico.

Ahí entraba en juego la IAT (import address table). Es una tabla de consulta para cuando un módulo quiere llamar a un API WIndows.Un programa compilado no sabe la situación de memoria en la que se encurta las librerías de las que depende, hace falta un salto intermedio. De modo que ahi tenemos la información que queremos…dónde va a ir mi módulo justo antes de llamar a las APIs que me interesan 😉 Sólo falta saber la dirección para poner un breakpoint 🙂

Supongamos un módulo SAMPLE1…obtenemos su dirección base (!peb te da la del proceso, ahora no quiero el proceso, quiero un módulo concreto)

 

   0:004> lm    –> miro los módulos cargados en memoria
   start end module name
   2f220000 2f239000 SAMPLE1
   6d9b0000 6dc75000 ONINTL 
   6e2e0000 6e318000 rapistub

Con su dirección base, voy a volcar las cabeceras

   0:004> !dh 2f220000

   File Type: EXECUTABLE IMAGE
   FILE HEADER VALUES
   14C machine (i386)
   4 number of sections
   …
   1000 [ 260] address [size] of Import Address Table Directory
   …

Y ahora que se donde empieza (2f220000+1000) y lo que ocupa (260), vuelco esa sección de la memoria (cambio los nombres de las funciones para legibilidad…y pq no quiero q se vean los nombres reales 😉 )

   0:004> dps 2f220000+1000 2f220000+1000+260
   2f221000 76427fae kernel32!FuncionA
   2f221004 76409145 kernel32!FuncionB
   2f221008 763e91ab kernel32!EnterCriticalSection
   2f22100c 76427b1c kernel32!LeaveCriticalSecion
   2f221010 76427a2c kernel32!FuncionE
   2f221014 763e1d27 user32!FuncionF
   2f221018 764245a7 user32!FuncionG
   …….

Lo que obtengo son las direcciones donde estan esas funciones, de modo que sé donde poner el breakpoint para trazar la información de la llamada, en SAMPLE1+1008 y SAMPLE1+100c  (estos bp’s siempre hay que hacerlas relativas a la dirección base, no vaya a ser que haya una realocation)

 

Recursos para profundizar para el que quiera

Especificación PE/COFF

Artículo de formato de PE 

Próximo post de la serie CLR via WinDBG – Introducción (Símbolos)

CLR via Windbg – string vs securestring

Ayer en el Octoberconference organizado por el grupo de usuarios de Málaga tuve la oportunidad de dar una charla de depuración en entornos de producción. Es una sesión muy especial que me trae muy gratos recuerdos de mi trabajo en soporte de Microsoft.

Durante la sesión vemos la importancia de la minuciosidad ante un problema en un entorno de producción, captura de volcados de memoria, análisis básico win32 y análisis en .NET.

Los asistentes siempre se sorprenden de la facilidad con la que se puede obtener los valores de las variables (passwords, strings de conexión, requests en asp.net…) en memoria. Unos 10 minutos antes de empezar, Unai Zorrilla me sugirió que hiciésemos una demo con SecureString para que se viese la utilidad de esa clase.

A si que vamos a por ello…

Partimos de este código

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security;

namespace ConsoleApplication1
{
  class Program
   {
     static void Main(string[] args)
     {
       using (SecureString ss = new SecureString())
       {
           string noss = string.Empty;
           while (true)
           {
             ConsoleKeyInfo cki = Console.ReadKey();
             if (cki.Key == ConsoleKey.Enter) break;
             ss.AppendChar(cki.KeyChar);
             noss += cki.KeyChar.ToString();
           }
          Console.WriteLine(“secure:”+ss);
          Console.WriteLine(“No secure:”+noss);
          Console.ReadLine();
       } 

     }
 }
}

Ejecutamos la aplicación e introducimos algo de texto pulsando enter, vemos los resultados de los Console.WriteLine…y nos quedamos ahi, no damos al segundo enter que si no perdemos la ejecución

Y ahora abrimos nuestro entorno de depuración de volcados favorito, el windbg 🙂

Pulsamos F6 y seleccionamos el proceso de la aplicación

Según nos adjuntamos al ejecutable, pasamos a cargar la extensión SOS en memoria. Esta hará posible que depuremos aplicaciones .NET desde WinDBG de forma muy sencilla.

.loadby sos mscorwks

Y ahora estamos preparados para investigar la memoria del proceso. Vamos a listar los objetos manejados de los stacks de los diferentes threads (~ = thread,  *=todos, e=ejecutar, !dumpstackobjects = mostrar objetos .net del stack del thread en curso)

~*e !dumpstackobjects

Si cotilleamos un poco la salida encontraremos estos valores (las direcciones hex pueden cambiar)

0580ebdc 0168981c System.String prueba prueba
0580ebe0 01683984 System.Security.SecureString

Son las referencias a los objetos que estamos buscando. Si volcamos el System.String, vemos la siguiente estructura

0:010> !do 0168981c
Name: System.String
MethodTable: 790fcb30
EEClass: 790fca90
Size: 44(0x2c) bytes
GC Generation: 0
(C:WindowsassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)
String: prueba prueba  –> juas que chivato, no? reconoce el string y me lo muestra tal cual 🙂
Fields:
MT Field Offset Type VT Attr Value Name
791018e0 4000096 4 System.Int32 0 instance 14 m_arrayLength
791018e0 4000097 8 System.Int32 0 instance 13 m_stringLength
790fe534 4000098 c System.Char 0 instance 70 m_firstChar
790fcb30 4000099 10 System.String 0 shared static Empty
>> Domain:Value 00374ea8:790d81bc <<
7912b1d8 400009a 14 System.Char[] 0 shared static WhitespaceChars

Si no nos lo mostrase tal cual, en negroesta resaltado lo que parece ser la dirección de comienzo del string que contiene la memoria (dir base de la clase string + 0x0c). De modo que vamos a volcarla directamente a ver que vemos.

0:010> du 0168981c +0x0c
01689828 “prueba prueba”

Demasiado fácil 😛 Vamos a volcar ahora el secure string a ver que es lo que vemos…

0:010> !do 01683984
Name: System.Security.SecureString
MethodTable: 791915e4
EEClass: 792316d8
Size: 20(0x14) bytes
GC Generation: 0  //mhhh ya no se chiva :/
(C:WindowsassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)
Fields:
MT Field Offset Type VT Attr Value Name
791916a0 4001e6e 4 …ty.SafeBSTRHandle 0 instance 01689700 m_buffer
791018e0 4001e6f 8 System.Int32 0 instance 13 m_length
79107584 4001e70 c System.Boolean 0 instance 0 m_readOnly
79107584 4001e71 d System.Boolean 0 instance 1 m_enrypted
79107584 4001e72 b00 System.Boolean 0 shared static supportedOnCurrentPlatform
>> Domain:Value 00374ea8:1 <<

Véis que en este caso no hay nada que cante ni ninguna dirección de donde se pueda rascar, quizás tenga que ver con que SecureString fue el resultado de una petición del gobierno de USA para proteger cierta información en memoria, por eso no se deja ver el contenido 🙂

Gracias por la idea Unai! (y a los asistentes por aguantarme)

Happy Hacking!

 

PD ->  .detach para liberar el proceso 😛

Paintball!!

Tras el TTT y MVP open day del viernes pasado unos cuantos nos fuimos a echar un Paintball el sabado…no se si fue una buena decision xD

Según llegué empezaron las hostilidades..que si te voy a barrer del mapa, que si me las vas a pagar todas juntas, que si yo soy el master chief del halo y te voy a dar para el pelo…blah blah blah }=P

Tuvimos una serie de escenarios preparados para darnos de bolazos ( troncos, un jeep, zanjas, un fuerte…) a si que nos metimos en el papel, a saltar los fajos de paja, escondidos cual ninja tras unas maderas esperando a algún despistado…muhahahaha

El hecho es que me dieron para el pelo…y para la boca..y para las piernas…creo que quedan pocos sitios sin bolazos por mi cuerpo. Forme parte del honroso equipo de Windows Media (los nombres los puso el del paintball..anda que no podia habernos llamado halo, gears of wars, viva piñata…):

Haciendo el ganso con una venda en la cabeza a modo de victima:

Equipo Windows Media al completo..weeeeeeeeeeeee!!!!!

Lo pasé genial, a ver si repetimos en breve y me llevo las pinturas de guerra 😛

 

aio!

!ASP.NET & APIs recientes de MS

Si estas leyendo este post…

…posiblemente trabajes con asp.net en vez de con php o con jsp.

…posiblemente estarás familiarizado (de oidas vale) con tecnologías como ASP.NET AJAX, Windows Live Services o Silverlight.

…posiblemente darás por hecho que al ser tecnologías de MS, como tu estás en plataforma MS las puedes utilizar sin problemas.

…pero…posiblemente no hayas caido en que son tecnologías de cliente independientes de la plataforma de lado del servidor, de modo que si conoces a un developer !ASP.NET estás tardando en decirle que se lance a asp.net ajax (librería cliente javascript), a los Windows Live Services (REST, XML-RPC, SOAP) y a Silverlight 1.0 🙂

¿Por qué no sacarle partido!

Por ejemplo…. el Windows Live Contacts Control.

¿Que es eso? El contactscontrol es la forma fácil de acceder a diferentes servicios de Live, encapsula todo el trabajo de autenticarse contra Live ID, obtener contactos de Live Data y Live Contacts. Tecnológicamente, es un control Javascript que permite a un usuario de un sitio web ver a sus contactos de Windows Live desde la web.

¿Para qué vale? Tiene dos aplicaciones posibles. Una es sencillamente que puedas comunicarte con tus contactos desde la página web, ya sea a través de correo o de IM. La segunda es que envies cierta información de alguno de tus contactos al sitio web (dirección postal para incluirlos en un mapa, envio de algun regalo, dirección de correo para que le notifiquen de algo…). En cuanto pueda haré un post del mecanismo de comunicación del control con la página web para pasarle esa información, hay un whitepaper que es una pasada :)~~

¿Cómo se come? muuuuuy fácil. Hay que hacer 3 páginas HTML o lo que prfieras.

Privacypolicy.htm –> Política de privacidad que se le mostrará al usuario del sitio web en caso de que quiera incluir información de sus contactos. Pon lo que quieras 🙂

channel.htm –> Necesaria para el mecanismo de comunicación del control con la página web en la que esta alojado. Bájate esta página con el botón derecho y copia el contenido.

tupagina.htm –> Aqui empieza el ‘desarrollo’.

1. Primero incluye un par de scripts en el head para referenciar el control

<script type=”text/javascript”
src=”http://controls.services.live.com/scripts/base/v0.3/live.js”>
</script>
<script type=”text/javascript”
src=”http://controls.services.live.com/scripts/base/v0.3/controls.js”>
</script>

2. Incluimos un namespace en el html para poder referenciar el control

<html xmlns:devlive=”http://dev.live.com”>

3. Incluimos el control. Para ver el detalle de cada uno de los parámetros pásate por la web oficial o pregunta en el post 😉 Hemos de especificar la información que necesitamos de los contactos en dataDesired y podemos capturar eventos que lanza el control con funciones Javascript.

Tened en cuenta que puede haber diferencias en la funcionalidad de cada view (tile, list, tilelist) y por lo tanto en los parámetros. Para una lista completa, pasaos por el API.

<devlive:contactscontrol
style=”width:250px;height:500px;float:right;border:solid 1px black;”
devlive:view=”list”
devlive:privacyStatementURL= “http://miUrl.com/privacyPolicy.htm”
devlive:channelEndpointURL=”http://miUrl.com/channel.htm”
devlive:dataDesired=”name,email
devlive:market=”es”
devlive:onSignin=”onSignin”
devlive:onSignout=”onSignout”
devlive:onError=”onError”
devlive:onData=”onData”>
</devlive:contactscontrol>

4. Capturamos los eventos. Solo el onData recibe parámetros. Recibirá un array de elementos con los campos que hayamos especificado en dataDesired, de modo que esta fácil recorrerlo 😉

<script type=”text/javascript”>
function onData ( p_elementos )
{
  var s = “Hecho! ” + p_elementos.length + ” elementos recibidos. <br>”
  for (var i = 0; i < p_elementos.length; i++) {
     s += “<p>”
     s += “Nombre: ” + p_elementos[i].name +”<br>”
     s += “Email: ” + p_elementos[i].email;
     s += “</p>”
  }
  alert(s);
}
</script>

El propio control tiene una serie de métodos para manejar contactos (añadir, borrar…)  lo veremos más adelante.

fácil, no? Pruébalo! pero ten en cuenta que esta en beta 🙂 y echale un ojo al FAQ si ves que ocurre algo que no esperas.

:wq!

UG + MVP Open Day + .NET Clubs

Dentro de unas 7 horas empieza una jornada de lo más interesante en las oficinas de MS en La Finca (Madrid)

Como algunos ya sabéis, parte de mi departamento esta orientada al trabajo con comunidades de usuarios:

Alfonso Rodriguez, David Carmona y yo nos dedicamos a comunidades de desarrolladores profesionales

Beatriz Ordoñez y Ethel Garcia-Simón se encargan de comunidades de desarrolladores universitarios

David Cervigón y José Parada se encargan de comunidades de ITPros

Carlos Oramas de comunidades de Aquitectos de Software

Amadeo Andrés se encarga de comunidades de entusiastas (locos por la tecnología aunque no se dediquen a ella 8 horas 🙂 )

Pero no somos el único departamento que trabajamos con comunidades. Por ejemplo, Cristina Gonzalez se encarga de premiar con el titulo de MVP a miembros de las comunidades de usuarios por su aportación a las comunidades de forma desinteresada.

Pues bien, mañana hay un remix en la oficina, se junta una reunión de MVPs  con una reunión de miembros de grupos de usuarios profesionales y una reunión de grupos de usuarios en universidades…GENIAL!!!

Dado que no somos todos desarrolladores tendremos varios tracks en paralelo para ir tocando diferentes áreas y que todos podamos entretenernos. Desarrollo, Sistemas, Office además de las sidemeetings de rigor para abordar temas específicos de cada comunidad…

Es uno de esos dias en los que no paras y acabas muerto pero te lo pasas como un enano 😛  además, como normalmente el 80% de los asistentes los conoces de reuniones anteriores, de charlas por grupos de usuarios (en breve a depurar a Málaga!), eventos… pues hay un ambiente genial. Lo malo…lo malo es que entre participar en alguna sesión, ayudar en otra, ver que todo vaya como debe e intentar saludar y preguntar cómo va la vida, se te pasa el dia en un pispas!!

En la parte técnica del evento nos vamos a centrar en los siguientes puntos (en el track de desarrollo):

Planes de MSDN para este año (Alfonso Rodriguez y David Salgado)

Noticia reciente y ronda de preguntas sobre la liberación de código fuente de .NET (David Salgado)

Servicios de Windows Live para desarrolladores (DS..en breve una serie de posts..veréis que virguerías 😀 )

Silverlight (Isabel Gómez – MS)

ADO.NET Synch Services (Unai Zorrilla – Plain Concepts)

Showtime (David Carmona con AJAX, Messenger, Silverlight, WPF… casi ná)

Seguridad SQL y LDAP (el maligno y el chico maravilla)

No se si mañana tendré energias para contar cómo fue todo, pero el sábado cómo muy tarde tendreís los puntos destacados.

He decidido poneros deberes de vez en cuando, y voy a empezar hoy…. id a www.live.com haced una busqueda ( por ejemplo site:telecinco.es) y mirad el total de resultados, luego haced la misma búsqueda en google y mirad tb los resultados. Que véis?…No esta mal eh…nuestro indice ha crecido 4 veces con los ultimos cambios…vamos mejorando bastante eh? 😉

Han sido cambios introducidos en la última semana, de todos modos, tendremos que esperar algo más para ver todos los cambios reflejados. El motor que funciona en el mercado en-US esta por encima del español, para muestra un botón:

 mercado en-us: http://search.live.com/results.aspx?q=will+smith&mkt=en-us&scope=&FORM=LIVSOP (rank de celebridades, videos, albumes, busquedas relacionadas…)

 mercado es-es: http://search.live.com/results.aspx?q=will+smith&mkt=es-es&scope=&FORM=LIVSOP (visto el anterior…este como que no dice nada x) …a ver si se nos propagan los cambios cuanto antes)

Pero todo se irá replicando 😀

Corto y cierro que tengo 5 horas para dormir. Saludos a toda la gente que esta por Oviedo en el Fundamentos Web!!! el año que viene no se me escapa.