martes, 27 de mayo de 2014

Debugging (I) Llamadas al sistema (System calls) y III

En la arquitectura x86 las llamadas al sistema se realiza mediante la instrucción SYSENTER. (aunque no siempre ha sido así. Hasta los Pentium II era mediante la instruccion INT 2E)

Esta sustitución ha sido para mejorar el rendimiento de las llamadas al sistema porque eliminan cierta sobrecarga en la gestión de interrupciones que, en el caso de la interrupción 2E, era superflua.

Tenemos una forma ya fácil de localizar la llamada al sistema. Solo tendremos que situarnos con ollydbg en el módulo ntdll.dll y localizar esa instrucción.

Pero antes vamos a seguir ampliando nuestros conocimientos. La última función que encontramos dentro del modo usuario (anillo 3) es KiFastSystemCall. Localicemos dentro el módulo ntdll.dll el código.

En la ventana de ejecución de Ollydbg solo tendremos que seleccionar Search for --> Name in all modules. Y aquí la vemos. Sólo dos líneas, tres sin incluimos la instrucción RET.

KiFastSystemCall                   8BD4            MOV EDX,ESP
7C90E512                              0F34            SYSENTER
KiFastSystemCallRet                C3              RET

Y a continuación, debajo vemos:

KiIntSystemCall                    8D5424 08       LEA EDX,DWORD PTR [ESP+8]
7C90E524                                  CD 2E        INT 2E
7C90E526                                        C3        RET

Que son las formas antigua y modernas de llamar la sistema. Lo que nos que esta versión sistema también puede puede funcionar en procesadores más antiguos.
Los nombres de cada una de las funciones también nos dan una pista: llamada al sistema y llamada rápida al sistema.

En la instrucción SYSENTER colocaremos un breakpoint y lo dejaremos deshabilitado porque nos interesa que se pare en le función fopen que es la que estamos siguiendo. Ponemos otro breakpoint en la llamada a función fopen

Damos Ejecutar (F9). Cuando el programa se pare en la llamada a fopen iremos a la ventana de breakpoint y habilitaremos la parada en la instrucción SYSENTER y volvemos a dar F9. Como esperábamos se nos para en la instrucción SYSENTER.

Observemos el registro EAX que contiene el valor 0x54. Esto valor es el número que identifica a la llamada del sistema que va a abrir el fichero.

Ahora a ejecutar hasta el código de usuario (Alf+ F9) para ver si hay más llamadas al sistema. Nos volvemos a parar nuevamente. Esta vez el registro EAX tiene el valor 0x25. Seguimos con Alt+F9, se nos para una vez más, esta vez tenemos en el registro EAX el valor 0xB3.

A la cuarte vez que damos Alt+F9 el programa se para ya en el código de usuario. La conclusión es que la función fopen, no tiene una llamada al  sistema. !Tiene cuatro¡.

Podemos realizar un proceso similar con la función toupper para tener la certeza de que esta función no tiene ninguna llamada al sistema.

Conclusión. 

Ambas funciones, que nos suministra el juego de funciones de las bibliotecas de C y que pueden parecer iguales tienen en su interior un uso de la arquitectura del procesador muy diferente. Y, si bien es bueno, aislar de ciertas complejidades a la codificación también debemos ser conscientes cuando programamos que no todas las cosas son por dentro iguales.... aunque por fuera no seamos capaces de notarlo.

<-- Previa entrada




No hay comentarios:

Publicar un comentario