File: pe.docbook

package info (click to toggle)
readpe 0.85.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,636 kB
  • sloc: ansic: 21,151; xml: 558; makefile: 448; sh: 422
file content (263 lines) | stat: -rw-r--r-- 6,262 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
<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>