Executável portátil - Portable Executable
Extensão de nome de arquivo |
.acm , .ax , .cpl , .dll , .drv , .efi , .exe , .mui , .ocx , .scr , .sys ,.tsp
|
---|---|
Tipo de mídia da Internet |
application / vnd.microsoft.portable-executable |
Desenvolvido por | Atualmente: Microsoft |
Tipo de formato | Bibliotecas binárias , executáveis , objetos e compartilhadas |
Estendido de |
COFF executável DOS MZ |
O formato Portable Executable (PE) é um formato de arquivo para executáveis , código-objeto , DLLs e outros usados em versões de 32 bits e 64 bits dos sistemas operacionais Windows . O formato PE é uma estrutura de dados que encapsula as informações necessárias para o carregador do sistema operacional Windows gerenciar o código executável empacotado . Isso inclui referências de biblioteca dinâmica para vinculação , tabelas de exportação e importação de API , dados de gerenciamento de recursos e dados de armazenamento local de thread (TLS). Em sistemas operacionais NT , o formato PE é usado para EXE , DLL , SYS ( driver de dispositivo ), MUI e outros tipos de arquivo. A especificação Unified Extensible Firmware Interface (UEFI) afirma que PE é o formato executável padrão em ambientes EFI.
Nos sistemas operacionais Windows NT, o PE atualmente suporta as arquiteturas de conjunto de instruções (ISAs) x86-32 , x86-64 (AMD64 / Intel 64), IA-64 , ARM e ARM64 . Antes do Windows 2000 , o Windows NT (e, portanto, o PE) suportava os ISAs MIPS , Alpha e PowerPC . Como o PE é usado no Windows CE , ele continua a oferecer suporte a várias variantes dos ISAs MIPS, ARM (incluindo Thumb ) e SuperH .
Os formatos análogos ao PE são ELF (usado no Linux e na maioria das outras versões do Unix ) e Mach-O (usado no macOS e iOS ).
História
A Microsoft migrou para o formato PE dos formatos NE de 16 bits com a introdução do sistema operacional Windows NT 3.1 . Todas as versões posteriores do Windows, incluindo o Windows 95/98 / ME e a adição do Win32s ao Windows 3.1x, suportam a estrutura de arquivos. O formato manteve o suporte legado limitado para preencher a lacuna entre os sistemas baseados em DOS e NT. Por exemplo, os cabeçalhos PE / COFF ainda incluem um programa executável DOS , que por padrão é um esboço do DOS que exibe uma mensagem como "Este programa não pode ser executado no modo DOS" (ou semelhante), embora possa ser um DOS completo versão do programa (um caso notável posterior é o instalador do Windows 98 SE). Isso constitui uma forma de binário gordo . O PE também continua a servir à plataforma Windows em constante mudança. Algumas extensões incluem o formato .NET PE (veja abaixo), uma versão de 64 bits chamada PE32 + (às vezes PE +) e uma especificação para Windows CE.
Detalhes técnicos
Layout
Um arquivo PE consiste em vários cabeçalhos e seções que informam ao vinculador dinâmico como mapear o arquivo na memória. Uma imagem executável consiste em várias regiões diferentes, cada uma das quais requer proteção de memória diferente; portanto, o início de cada seção deve ser alinhado ao limite da página. Por exemplo, normalmente a seção .text (que contém o código do programa) é mapeada como execute / readonly, e a seção .data (mantém as variáveis globais) é mapeada como no-execute / readwrite. No entanto, para evitar o desperdício de espaço, as diferentes seções não são alinhadas com a página no disco. Parte do trabalho do vinculador dinâmico é mapear cada seção para a memória individualmente e atribuir as permissões corretas às regiões resultantes, de acordo com as instruções encontradas nos cabeçalhos.
Tabela de importação
Uma seção digna de nota é a tabela de endereços de importação (IAT), que é usada como uma tabela de consulta quando o aplicativo está chamando uma função em um módulo diferente. Pode ser na forma de importação por ordinal e importação por nome . Como um programa compilado não pode saber a localização da memória das bibliotecas das quais depende, um salto indireto é necessário sempre que uma chamada de API é feita. À medida que o vinculador dinâmico carrega módulos e os une, ele grava endereços reais nos slots IAT, de forma que eles apontem para as localizações de memória das funções de biblioteca correspondentes. Embora isso acrescente um salto extra sobre o custo de uma chamada intramódulo, resultando em uma penalidade de desempenho, oferece um benefício importante: O número de páginas de memória que precisam ser alteradas na cópia na gravação pelo carregador é minimizado, economizando memória e tempo de E / S do disco. Se o compilador souber com antecedência que uma chamada será entre módulos (por meio de um atributo dllimport), ele pode produzir um código mais otimizado que simplesmente resulta em um opcode de chamada indireta .
Relocações
Os arquivos PE normalmente não contêm código independente de posição . Em vez disso, eles são compilados para um endereço base preferencial e todos os endereços emitidos pelo compilador / vinculador são fixados com antecedência. Se um arquivo PE não puder ser carregado em seu endereço preferido (porque já foi obtido por outra pessoa), o sistema operacional o realocará . Isso envolve recalcular cada endereço absoluto e modificar o código para usar os novos valores. O carregador faz isso comparando os endereços de carga preferenciais e reais e calculando um valor delta . Em seguida, ele é adicionado ao endereço preferencial para chegar ao novo endereço do local de memória. As realocações de bases são armazenadas em uma lista e adicionadas, conforme necessário, a um local de memória existente. O código resultante agora é privado para o processo e não pode mais ser compartilhado , portanto, muitos dos benefícios de economia de memória das DLLs são perdidos neste cenário. Também retarda o carregamento do módulo significativamente. Por esse motivo, o rebasing deve ser evitado sempre que possível, e as DLLs enviadas pela Microsoft têm endereços de base pré-calculados para não se sobreporem. No caso de não realocar o PE, portanto, tem a vantagem de um código muito eficiente, mas na presença de realocar o acerto de uso de memória pode ser caro. Isso contrasta com o ELF, que usa código totalmente independente de posição e uma tabela de deslocamento global, que troca o tempo de execução em favor de um menor uso de memória.
.NET, metadados e o formato PE
Em um executável .NET, a seção de código PE contém um stub que invoca a entrada de inicialização da máquina virtual CLR , _CorExeMain
ou _CorDllMain
in mscoree.dll
, muito parecido com os executáveis do Visual Basic . A máquina virtual então usa os metadados .NET presentes, cuja raiz IMAGE_COR20_HEADER
(também chamada de "cabeçalho CLR") é apontada por uma IMAGE_DIRECTORY_ENTRY_COMHEADER
entrada no diretório de dados do cabeçalho PE. IMAGE_COR20_HEADER
assemelha-se fortemente ao cabeçalho opcional do PE, essencialmente desempenhando sua função para o carregador CLR.
Os dados relacionados ao CLR, incluindo a própria estrutura raiz, estão normalmente contidos na seção de código comum .text
,. É composto de alguns diretórios: metadados, recursos incorporados, nomes fortes e alguns para interoperabilidade de código nativo. O diretório de metadados é um conjunto de tabelas que lista todas as entidades .NET distintas no assembly, incluindo tipos, métodos, campos, constantes, eventos, bem como referências entre eles e outros assemblies.
Use em outros sistemas operacionais
O formato PE também é usado pelo ReactOS , já que o ReactOS se destina a ser compatível com o binário do Windows. Ele também tem sido historicamente usado por vários outros sistemas operacionais, incluindo SkyOS e BeOS R3. No entanto, SkyOS e BeOS eventualmente mudaram para ELF .
Como a plataforma de desenvolvimento Mono pretende ser binária compatível com o Microsoft .NET Framework , ela usa o mesmo formato PE da implementação da Microsoft. O mesmo vale para o .NET Core multiplataforma da Microsoft .
Em sistemas operacionais semelhantes ao Unix x86 (-64) , os binários do Windows (no formato PE) podem ser executados com o Wine . O HX DOS Extender também usa o formato PE para binários nativos do DOS de 32 bits, além de poder, até certo ponto, executar binários do Windows existentes no DOS, agindo assim como um equivalente do Wine para DOS.
Em IA-32 e x86-64 Linux também se pode executar o Windows ' DLLs sob LoadLibrary.
O Mac OS X 10.5 tem a capacidade de carregar e analisar arquivos PE, mas não é binário compatível com o Windows.
Firmware UEFI e EFI usam arquivos executáveis portáteis, bem como a convenção de chamada Windows ABI x64 para aplicativos .
Veja também
- Exe
- Formato executável e vinculável
- Mach-O
- a.out
- Comparação de formatos de arquivos executáveis
- Compressão executável
- ar (Unix) uma vez que todas as bibliotecas COFF usam o mesmo formato
- Virtualização de aplicativos
Referências
links externos
- Formato PE (documento online mais recente)
- Especificação do Microsoft Portable Executable e Common Object File Format (revisão 8.1, formato OOXML )
- Especificação do Microsoft Portable Executable e Common Object File Format (revisão 6.0, formato .doc )
- O artigo original do Portable Executable de Matt Pietrek ( MSDN Magazine, março de 1994)
- Parte I. Uma análise aprofundada do formato de arquivo executável portátil Win32 de Matt Pietrek ( MSDN Magazine, fevereiro de 2002)
- Parte II. Uma análise aprofundada do formato de arquivo executável portátil Win32, de Matt Pietrek ( MSDN Magazine, março de 2002)
- O formato de arquivo .NET por Daniel Pistelli
- Blog de Ero Carrera que descreve o cabeçalho PE e como percorrer
- PE Internals fornece uma maneira fácil de aprender o Portable Executable File Format