Endereçamento
Last updated
Last updated
Onde já se viu dois executáveis com o ImageBase em 0x400000 rodarem ao mesmo tempo se ambos são carregados no mesmo endereço de memória? Bem, a verdade é que não são. Existe um esquema chamado de memória virtual que consiste num mapeamento da memória RAM real física para uma memória virtual para cada processo no sistema, dando a eles a ilusão de que estão sozinhos num ambiente monotarefa como era antigamente (vide MS-DOS e outros sistemas antigos). Essa memória virtual também pode ser mapeada para um arquivo em disco, como o pagefile.sys. O desenho a seguir ilustra o mecanismo de mapeamento:
Conforme explicado no capítulo sobre as Seções dos arquivos PE, a memória é dividida em páginas, tanto a virtual quanto a física. No desenho, os dois processos possuem páginas mapeadas pelo kernel (pelo gerenciador de memória, que é parte deste) em memória física e em disco (sem uso no momento). Perceba que as páginas de memória não precisam ser contíguas (uma imediatamente após a outra) no layout de memória física, nem no da virtual. Além disso, dois processos diferentes podem ter regiões virtuais mapeadas para a mesma região da memória física, o que chamamos de páginas compartilhadas.
Em resumo, o sistema gerencia uma tabela que relaciona endereço físico de memória (real) com endereço virtual, para cada processo. Todos "acham" que estão sozinhos no sistema, mas na verdade estão juntos sob controle do kernel.
O endereço virtual, em inglês Virtual Address, ou simplesmente VA, é justamente a localização virtual em memória de um dado ou instrução. Por exemplo, quando alguém fazendo engenharia reversa num programa diz que no endereço 0x401000 existe uma função que merece atenção, quer dizer que ela está no VA 0x401000 do binário quando carregado. Para ver a mesma função, você precisa carregar o binário em memória (normalmente feito com um debugger, como veremos num capítulo futuro) e verificar o conteúdo de tal endereço.
Em inglês, Relative Virtual Address, é um VA que, ao invés de ser absoluto, é relativo à alguma base. Por exemplo, o valor do campo entrypoint no cabeçalho Opcional é um RVA relativo à base da imagem (campo ImageBase no mesmo cabeçalho). Com isso em mente, avalie seu valor na saída a seguir:
No exemplo acima, o campo entrypoint tem o valor 0x39c2, que é um RVA. Como este campo é relativo ao ImageBase, o VA (endereço virtual) do entrypoint é então dado pela sua soma com o valor de ImageBase:
Os RVA's podem ser relativos à outras bases que não a base da imagem. É preciso consultar na documentação qual a relatividade de um RVA para convertê-lo corretamente para o VA correspondente.