Executável portátil - Portable Executable

Executável portátil
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

Estrutura de um executável portátil de 32 bits

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 , _CorExeMainou _CorDllMainin 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_COMHEADERentrada no diretório de dados do cabeçalho PE. IMAGE_COR20_HEADERassemelha-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

Referências

links externos