<chapter>
<title>Visão geral do formato PE</title>

<para>
O formato PE (Portable Executable) é o padrão para arquivos executáveis
utilizados nos sistemas MS-Windows atuais. Faremos um breve resumo sobre sua
estrutura, mas a documentação completa (em inglês) pode ser obtida
<ulink url="http://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx">
aqui</ulink>.
</para>

<para>
Quando um programador escreve um programa e o compila, não é somente o código
escrito por ele que vai para o executável. O compilador adiciona todas as
estruturas e informações necessárias para este executável seja devidamente
carregado pelo sistema operacional, utilize funções de bibliotecas externas
etc. Essas adição de informações precisa obedecer um padrão, uma especificação,
e é exatamente aí que o formato PE entra.
</para>

<section id="headers">
<title>Cabeçalhos</title>

Os primeiros bytes de um arquivo PE são elementos de vários cabeçalhos
diferentes. Estes bytes são na realidade os valores dos vários campos dos
cabeçalhos do PE. Um cabeçalho é um conjunto de campos e seus respectivos
valores. Vamos analisar o primeiro cabeçalho do PE, ou seja, o que está logo no
início de um arquivo PE.

<para>O primeiro cabeçalho num arquivo PE é o chamado Cabeçalho do DOS, ou no
inglês, DOS Header. Este cabeçalho possui a seguinte estrutura:</para>

<table>
<title>Cabeçalho do DOS</title>
<tgroup cols="4">
<thead>
<row>
<entry>Posição</entry>
<entry>Tamanho</entry>
<entry>Nome</entry>
<entry>Descrição</entry>
</row>
</thead>
<tfoot>
<row>
<entry>Total</entry>
<entry>64</entry>
<entry></entry>
</row>
</tfoot>
<tbody>

<row>
<entry>0x00</entry>
<entry>2</entry>
<entry>e_magic</entry>
<entry>Magic Number - para executáveis PE
deve ser sempre 0x5a4d</entry>
</row>

<row>
<entry>0x02</entry>
<entry>2</entry>
<entry>e_cblp</entry>
<entry></entry>
</row>

<row>
<entry>0x04</entry>
<entry>2</entry>
<entry>e_cp</entry>
<entry></entry>
</row>

<row>
<entry>0x06</entry>
<entry>2</entry>
<entry>e_crlc</entry>
<entry></entry>
</row>

<row>
<entry>0x08</entry>
<entry>2</entry>
<entry>e_cparhdr</entry>
<entry></entry>
</row>

<row>
<entry>0x0a</entry>
<entry>2</entry>
<entry>e_minalloc</entry>
<entry></entry>
</row>

<row>
<entry>0x0c</entry>
<entry>2</entry>
<entry>e_maxalloc</entry>
<entry></entry>
</row>

<row>
<entry>0x0e</entry>
<entry>2</entry>
<entry>e_ss</entry>
<entry></entry>
</row>

<row>
<entry>0x10</entry>
<entry>2</entry>
<entry>e_sp</entry>
<entry></entry>
</row>

<row>
<entry>0x12</entry>
<entry>2</entry>
<entry>e_csum</entry>
<entry></entry>
</row>

<row>
<entry>0x14</entry>
<entry>2</entry>
<entry>e_ip</entry>
<entry></entry>
</row>

<row>
<entry>0x16</entry>
<entry>2</entry>
<entry>e_cs</entry>
<entry></entry>
</row>

<row>
<entry>0x18</entry>
<entry>2</entry>
<entry>e_lfarlc</entry>
<entry></entry>
</row>

<row>
<entry>0x1a</entry>
<entry>2</entry>
<entry>e_ovno</entry>
<entry></entry>
</row>

<row>
<entry>0x1c</entry>
<entry>8</entry>
<entry>e_res</entry>
<entry></entry>
</row>

<row>
<entry>0x24</entry>
<entry>2</entry>
<entry>e_oemid</entry>
<entry></entry>
</row>

<row>
<entry>0x26</entry>
<entry>2</entry>
<entry>e_oeminfo</entry>
<entry></entry>
</row>

<row>
<entry>0x28</entry>
<entry>20</entry>
<entry>e_res2</entry>
<entry></entry>
</row>

<row>
<entry>0x3c</entry>
<entry>4</entry>
<entry>e_lfanew</entry>
<entry>Posição no arquivo da assinatura PE</entry>
</row>

</tbody>
</tgroup>
</table> 

<para>
Perceba que o valor presente nos dois primeiro bytes representa o campo de nome
e_magic. A posição do início do campo está representada em hexadecimal para
facilitar.
</para>

<para>
Podemos então dizer que os primeiros 64 bytes de um arquivo PE definem o
cabeçalho do DOS. O formato especifica que o valor do último campo, chamado
e_lfanew, é na verdade o endereço de uma assinatura PE. Esta assinatura possui
4 bytes e deve ser o número 0x4550, do contrário, o arquivo não é um PE válido.
</para>

<para>
Existem outros cabeçalhos no arquivo PE. Por favor, leia a documentação oficial
para maiores detalhes sobre este e outros cabeçalhos existentes.
</para>

</section>

<sect1 id="secoes">
<title>Seções</title>

<para>
Uma outra região do PE muito importante são as sessões. Tratam-se de áreas
delimitadas dentro do PE para abrigar certos tipos de dados. Cada seção tem uma
posição dentro do arquivo PE, ou seja, onde ela começa, e um tamanho, que torna
possível saber em qual byte ela termina.
</para>

<para>Se você imaginar um executável PE como um criado-mudo, as seções seriam
as gavetas. E como todo criado-mudo organizado, cada gaveta possui um tipo de
roupa (uma para calças, outra para camisas e assim por diante), mas nada impede
de separar duas ou mais gavetas só para camisas. O que não se pode fazer, pelo
menos no PE, é misturar as coisas.
</para>

<para>O código executável fica numa seção de código. Já dados do tipo texto
utilizados pelo programador para criar o programa, ficam em outra seção, que
não possui código executável e sim dados.</para>

<para>
As seções possuem um nome, apesar de não ser regra. Outro atributo importante
são as permissões da seção. Ela pode ser executável, legível e/ou gravável.
Abaixo uma lista de de seções normalmente encontradas em executáveis PE sadios:
</para>

<variablelist>
<varlistentry>
<term>.text / .code</term>
<listitem><para>Seção de código executável, normalmente a primeira a ser
executada (mas não é regra). Precisa de permissão de leitura e execução.</para></listitem>
</varlistentry>
<varlistentry>
<term>.data</term>
<listitem><para>Seção para dados (variáveis e outros). Precisa de permissão de
leitura e gravação.</para></listitem>
</varlistentry>
<varlistentry>
<term>.rdata</term>
<listitem><para>Seção para dados somente para leitura. Precisa de permissão de
leitura somente.</para></listitem>
</varlistentry>
</variablelist> 

<para>As seções podem conter qualquer configuração. Inclusive a partir destas
configurações, podemos inferir que estamos tratando de uma seção de um PE onde
o criador utilizou técnicas para evitar o trabalho de analistas de malware.
</para>

</sect1>

</chapter>
