Ir al contenido
Menú principal
Menú principal
mover a la barra lateral
ocultar
Navegación
Página principal
Cambios recientes
Página aleatoria
Ayuda sobre MediaWiki
Buscar
Buscar
español
Apariencia
Crear una cuenta
Acceder
Herramientas personales
No has accedido
Discusión
Contribuciones
Crear una cuenta
Acceder
Editando
Portable Executable
(sección)
Página
Discusión
español
Leer
Editar
Editar código
Ver historial
Herramientas
Herramientas
mover a la barra lateral
ocultar
Acciones
Leer
Editar
Editar código
Ver historial
General
Lo que enlaza aquí
Cambios relacionados
Información de la página
Apariencia
mover a la barra lateral
ocultar
Advertencia:
no has iniciado sesión. Tu dirección IP se hará pública si haces cualquier edición. Si
inicias sesión
o
creas una cuenta
, tus ediciones se atribuirán a tu nombre de usuario, además de otros beneficios.
Comprobación antispam. ¡
No
rellenes esto!
== Detalles técnicos == [[Archivo:Diagram PE (es).png|derecha|miniaturadeimagen|145px|<!-- Estructura interna de un archivo en formato PE. -->]] === Diseño === Un archivo PE consiste de una serie de cabeceras y secciones que indican al enlazador dinámico cómo asignar el archivo en memoria. Una imagen ejecutable consta de varias zonas diferentes, cada una de las cuales requieren diferente protección de memoria, por lo que el inicio de cada sección debe estar alineado a un límite de página. Por ejemplo, generalmente la sección <tt>.text</tt> (que contiene código de programa) es mapeado como «ejecutar/sólo lectura», y la sección <tt>.data</tt> (que contiene las variables globales) es mapeado como «no-ejecutar/lectura-escritura». Sin embargo, para evitar el desperdicio de espacio, las diferentes secciones no son alineadas en página en disco. Parte del trabajo del enlazador dinámico es mapear cada sección en memoria de manera individual y asignar los permisos correctos para las regiones resultantes, de acuerdo con las instrucciones que se encuentran en las cabeceras. === Tabla de secciones === La tabla de secciones se encuentra justo detrás de la cabecera PE. Esta es una tabla que contiene varias estructuras '''IMAGE_SECTION_HEADER'''. Estas estructuras contienen información sobre las secciones de los binarios para ser cargados en la memoria. El campo '''NumberOfSections''' de la estructura '''IMAGE_FILE_HEADER''' indica cuantas entradas hay en la tabla. El máximo soportado por Windows es de 96 secciones. Un prototipo de una tabla de secciones se ve de la siguiente manera: <syntaxhighlight lang="C"> typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; </syntaxhighlight> Cada sección tiene un nombre de 8 caracteres; este nombre no es significativo, pero normalmente se puede encontrar lo siguiente: {| class="wikitable" style="text-align:center; width:65%;" |- ! Nombre !! Descripción |- | .text | El código (instrucciones) del programa |- | .bss | Las variables no inicializadas |- | .reloc | La tabla de relocalizaciones |- | .data | Las variables inicializadas |- | .rsrc | Los recursos del archivo (cursores, sonidos, menús...) |- | .rdata | Los datos de solo lectura |- | .idata | La tabla de importación |- | .upx | Firma de una compresión UPX, propio de software UPX |- |- | .aspack | Firma de un paquete ASPACK, propio de software ASPACK |- |- | .adata | Firma de un paquete ASPACK, propio de software ASPACK |- |} === Tabla IMPORT === Una sección a mencionar es la tabla de importación de direcciones (en inglés ''import address table'' o IAT), que se usa como una tabla de búsqueda cuando la aplicación llama una función en un módulo diferente. Esto puede darse en forma de importación por ordinal o importación por nombre. Debido a que un programa compilado no puede conocer la ubicación en memoria de las bibliotecas de las que depende directamente, cada vez que se hace una llamada a la API es necesario un salto indirecto. Como el enlazador dinámico carga los módulos y los une, este escribe la dirección actuales en las ranuras IAT, de manera que apuntan a las ubicaciones de memoria correspondientes de la biblioteca de funciones. Aunque esto agrega un salto adicional en el costo de una llamada intra-módulo que resulta en una reducción del rendimiento, ofrece una ventaja clave: se reduce al mínimo el número de páginas de memoria que necesitan ser cambiados [[copy-on-write]] por el cargador, ahorrando memoria y tiempo de I/O de disco. Si el compilador conoce de antemano que será una llamada inter-módulo (mediante el atributo <tt>dllimport</tt>) puede producir código más optimizado que simplemente se traduce en una llamada indirecta [[opcode]]. === Relocalizaciones === Los archivos PE no contienen [[código independiente de la posición]]. En su lugar son compilados a una ''dirección base'' preferida, y todas las direcciones emitidas por el compilador/enlazador se fijan previamente. Si un archivo PE no puede ser cargado en su dirección preferida (porque ya fue tomada por algo más), el sistema operativo lo reajustará. Esto implica recalcular cada dirección absoluta y modificar el código para utilizar los nuevos valores. El cargador lo realiza comparando las direcciones de carga actual y preferida, y calculando un valor [[Delta encoding|delta]]. Esto se añade a continuación a la dirección preferida para llegar a la nueva dirección de la localización de memoria. Las relocalizaciones base son almacenadas en una lista y añadidas, cuando sea necesario, a una posición de memoria existente. El código resultante ahora es privado al proceso y no es más compartido, por lo que muchos de los beneficios de ahorro de memoria de las DLLs se pierden en este escenario. También retrasa la carga del módulo de manera significativa. Por esta razón, el reajuste es evitado siempre que sea posible, y las DLL proporcionadas por Microsoft tienen direcciones base pre-calculadas de manera que no se superpongan. Por lo tanto, en el caso de no reajuste, PE ofrece la ventaja de un código muy eficiente, pero en presencia de reajuste, el éxito en el uso de memoria puede ser costoso. Esto contrasta con ELF, que utiliza código totalmente independiente de la posición y una tabla de desplazamiento global, que abandona tiempo en ejecución contra el uso de memoria en favor de estos últimos.
Resumen:
Al guardar los cambios aceptas los
términos de uso
y liberas de forma irrevocable tu contribución conforme a los términos de las licencias
licencia CC BY-SA 4.0
y
GFDL
. Aceptas igualmente que un hipervínculo o URL es atribución suficiente conforme a la licencia Creative Commons.
Cancelar
Ayuda de edición
(se abre en una ventana nueva)
Buscar
Buscar
Editando
Portable Executable
(sección)
Añadir idiomas
Añadir tema