Saltar al contenido

¿Por qué PE necesita Original First Thunk (OFT)?

Solución:

El primer procesador original es necesario si las importaciones están vinculadas pero el .DLL importado no coincide.

En una nueva versión sin parches de Windows, se conocen todas las direcciones de todas las funciones en los .DLL base (ntdll, kernel32, user32, etc.). Tome shell32, por ejemplo, se vincula a kernel32!CreateProcess y la verdadera dirección de CreateProcess se puede almacenar directamente en shell32. Esto se denomina enlace de importación y permite al cargador omitir el paso en el que busca todas las direcciones de las funciones importadas.

Esto no funciona si el .DLL importado no se ha cargado en su dirección preferida ni si el .DLL ha cambiado (actualización de seguridad, etc.). Si esto sucede, entonces el cargador tiene que buscar las funciones “de la manera normal” y se debe usar la matriz de primer procesador original porque ese es el único lugar donde se almacenan los RVA de los nombres de las funciones.

Si no se utiliza el enlace de importación, la primera matriz de procesador original es opcional y es posible que no esté presente.

ASLR probablemente ha hecho que esta optimización sea irrelevante.

Permítanme resumir muchas cosas para ustedes aquí. Cuando carga una biblioteca, por ejemplo, Milad.dll y luego intenta llamar a una función como MPrint, el cargador dinámico del sistema operativo Windows tiene que resolver la dirección de la función MPrint y luego llamarla. ¿Cómo puede el sistema operativo resolver la dirección de esa función?

Windows pasa por algunas cosas realmente complicadas que quiero contarte esos pasos con una simple lengua. El cargador dinámico del sistema operativo Windows para resolver la dirección de la función en los archivos DLL debe verificar la tabla de nombres de importación (INT), la tabla ordinal de importación (IOT) y la tabla de direcciones de importación (IAT). Estas tablas señaladas por AddressOfNames, AddressOfNamesOrdinal y AddressOfFunction miembro en el directorio de exportación de una estructura PE.

Después de que el sistema operativo cargue Milad.dll en el espacio de direcciones del proceso de destino con la ayuda de LoadLibrary, llenará la tabla INT, IOT e IAT con su RVA en el espacio de direcciones de destino del proceso con GetProcAddress y hará algunos cálculos.

Hay una matriz de Import Directory en la estructura del proceso que tiene OriginalFirstThunk, TimeDateStamp, ForwarderChain, Name, FirstThunk que estos miembros apuntan a algunas direcciones importantes.

  1. Nombre en Import Directory (Image_Import_Data) apuntó al nombre de la DLL que el proceso intenta llamar, en este ejemplo esta DLL es Milad.dll.
  2. OriginalFirstThunk apuntó a la tabla de nombres de importación, que incluye los nombres de las funciones exportadas por Milad.Dll. Las funciones en esta tabla tienen un índice único cuyo cargador toma ese índice y va al siguiente paso y hace referencia a Importar tabla ordinal con ese índice y toma el valor que hay en ese índice de Importar tabla ordinal que es otro valor entero.
  3. FirstThunk es otro miembro importante que apunta a IAT. en el paso anterior, el cargador dinámico toma un valor entero a través de IOT. este valor es un número de índice que el cargador dinámico se refiere a IAT con ese valor. En esta tabla, hay una dirección en el valor de índice que el cargador dinámico obtiene de INT-IOT. Después de estos pasos, cuando el cargador dinámico encuentra la dirección correcta de la función, coloca esa dirección en la tabla de direcciones de importación para la función MPrint. Entonces el proceso puede llamar a esa función con su dirección.

Esta es una explicación simple de las cosas complicadas que hace el cargador para resolver la dirección de las funciones en los archivos DLL a través de los miembros Nombre, OFT (INT) y FT (IAT) en Image_Import_Data.

Necesitamos saber que cuando el archivo PE se carga en la memoria, el cargador PE buscará IMAGE_THUNK_DATAs e IMAGE_IMPORT_BY_NAMEs y determinará las direcciones de las funciones de importación. Luego reemplaza los IMAGE_THUNK_DATAs en la matriz apuntada por FirstThunk con las direcciones reales de las funciones. Por lo tanto, cuando el archivo PE esté listo para ejecutarse. La matriz de RVA apuntada por OriginalFirstThunk permanece sin cambios de modo que si surge la necesidad de encontrar los nombres de las funciones de importación, el cargador PE aún puede encontrarlas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *