Moderators Leandro Fróes Posted September 12, 2017 at 07:38 PM Moderators Share Posted September 12, 2017 at 07:38 PM Boa tarde pessoal!! Acharam que o PE ia abandonar vocês?? Que nada rapaz, só uma pausa do feriado msm pra galera dormir mais =D Se me permitem, gostaria de fazer uma observação que se aplica nos estudos: Estou colocando os campos da documentação aqui assumindo que sejam sempre verdadeiros, mas sabemos que não é bem assim. Este é o padrão que o Windows segue, mas quando o assunto é (in)segurança padrões são meio problemáticos(?!). Como o foco aqui é simplesmente apresentar o formato vou focar justamente nisso e deixar possíveis problemas/melhorias/macumbas para o futuro, depois que todos nós (e eu estou bem incluso nisso) entendermos tudo Bom, vamos ao que interessa? Aqui faremos o uso de mais uma ferramenta, um debugger pra ser mais preciso. Usarei o OllyDbg na versão 2.01, mas fique à vontade para usar um de sua preferência. E o que é um debugger? Resumindo é uma ferramenta com a capacidade de interpretação dos opcodes, transformando-os em linguagem assembly (disassembly) e permitindo interação com o binário compilado. Lembram da estrutura IMAGE_NT_HEADERS? typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER OptionalHeader; } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; No post passado vimos o FileHeader, agora iremos para a IMAGE_OPTIONAL_HEADER que segue o seguinte formato segundo a documentação: typedef struct _IMAGE_OPTIONAL_HEADER { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; Grandinho, né? Bem, aqui temos o nome “opcional”, mas na verdade toda imagem possui um cabeçalho deste (entenda imagem como um programa carregado em memória). Este header possui informações importantes que ajudam no carregamento e execução do nosso executável. Magic A identificação do tipo de imagem é feito deste campo. Aqui podemos ver se ela é um PE32, PE32+ ou uma ROM image. Os bytes no caso seriam: 0x10B - PE32 0x107 – ROM Image 0x20B – PE32+ PE32, certo? O zero da esquerda é omitido ali em cima, mas ainda sim são dois bytes. MajorLinkerVersion e MinorLinkerVersion Simplesmente um byte indicando a maior versão do linker e outro byte indicando a menor. Sempre que leio algo sobre PE dizem que este campo não é lá essas coisas, eu não faço ideia da versão do meu linker, por exemplo, então se alguém souber uma utilidade interessante para este campo pf me ajude Converta ai pra decimal rapaz!!! SizeOfCode DWORD indicando o tamanho, em bytes, da seção .text (ou .code) ou a soma de todas essas seções se houver várias seções de texto Entenda que quando falamos que a seção se chama .text é simplesmente um nome, uma convenção para o loader as identificar. SizeOfInitializedData DWORD indicando o tamanho, em bytes, da seção .data ou a soma de todas essas seções se houver várias seções de dados inicializados. SizeOfUninitializedData DWORD indicando o tamanho, em bytes, da seção .bss ou a soma de todas essas seções se houver várias seções de dados não inicializadas. AddressOfEntryPoint Aqui temos uma DWORD que é o endereço do Entry Point (um RVA para ser mais exato) relativo ao Base Address que indica (pelo menos deveria) o começo do programa em memória. Para executáveis este é o começo do programa, para drivers é a função de inicialização e para DLL's é um campo opcional. Caso não haja E.P o campo será zero. Olha lá o danado no Debugger . Note que há um número somado ao nosso RVA, este se chama BaseAddress, veremos mais pra frente. BaseOfCode DWORD relativa ao Base Address indicando o endereço do começo da seção .text(.code) quando ela é carregada em memória, seu RVA. BaseOfData DWORD relativa ao Base Address indicando o endereço do começo da seção .data quando ela é carregada em memória, RVA novamente. ImageBase Quando temos uma imagem carregada em memória precisamos de um endereço para ela, certo? Um executável possui um endereço preferencial, assim como uma DLL. Este endereço é uma DWORD e é chamado de BaseAddress, pois indica o primeiro byte em memória. O valor preferencial para aplicações Windows NT, XP, 95, 98, 2000 é 0x00400000 (explicado o porque dos valores do Olly, né?=D) e para DLL's 0x00010000. 0x400000 o nosso, faz algum sentido o valor ali no debugger agora ? Some ai: 0x400000 + 0x14E0 SectionAlignment Alinhamento da seção (em bytes) quando é carregada em memória indicado por uma DWORD. O tamanho padrão é de uma página de acordo com a arquitetura. Nosso alinhamento de seção é de 4096 bytes. FileAlignment Alinhamento dos dados propriamente ditos das seções da imagem. O padrão é 512. Caso o SectionAlignment seja menor que o tamanho de uma página o FileAlignment será o mesmo do SectionAlignment. 200h = 512 dec, então estamos com o padrão mesmo. MajorOperatingSystemVersion e MinorOperatingSystemVersion 2 WORDS indicando a maior e menor versão do sistema requerido. Não sei muito bem sobre este campo =/ MajorImageVersion e MinorImageVersion 2 WORDS indicando a maior e menor versão da imagem. Também não sei muito sobre MajorSubsystemVersion e MinorSubsystemVersion 2 WORDS indicando a maior e menor versão do SubSystem. Este campo deve ser checado pois a versão vai influenciar na maneira como a aplicação rodará (questão gráfica, por exemplo) Win32VersionValue DWORD reservada e é sempre zero aparentemente. SizeOfImage DWORD que indica o tamanho total (em bytes) da imagem quando carregada em memória, aqui estão inclusos os headers, seções etc e este tamanho deve ser múltiplo da SectionAlignment(até porque este alinhamento trata da imagem carregada). Vamos ver se é múltiplo ? Lembrando que nosso resto deve ser zero. Vamos rodar a ferramenta mais potente do nosso arsenal, a calculadora do windows *-* (brincadeira, usem o shell mesmo). 0x01D000 = 118784 em decimal, dividimos entao por 4096 (alinhamento da seção) e obtemos 29 com resto zero, certinho!! SizeOfHeaders A soma de todos os cabeçalhos, data directory e cabeçalhos das seções. Esta DWORD deve ser múltipla do FileAlignment e é o offset do começo do arquivo até os dados propriamente ditos. Saque sua calculadora e faça novamente a conta, mas agora convertendo e dividindo por 512, aqui deu 1024 e na divisão deu 2, confere? CheckSum Esta DWORD , para as versões atuais do NT, só é checada se a imagem for um driver NT (o driver não carregará se o checksum não estiver correto). Para outros tipos de binários o checksum não precisa ser fornecido e pode ser 0. No nosso caso tem essa macumba ai (o algoritmo para calcular o checksum não é explicitamente aberto). Subsystem Esta WORD representa o Subsystem esperado para executar a imagem. Segue a tabelinha da doc: Constant Value Description IMAGE_SUBSYSTEM_UNKNOWN 0 An unknown subsystem IMAGE_SUBSYSTEM_NATIVE 1 Device drivers and native Windows processes IMAGE_SUBSYSTEM_WINDOWS_GUI 2 The Windows graphical user interface (GUI) subsystem IMAGE_SUBSYSTEM_WINDOWS_CUI 3 The Windows character subsystem IMAGE_SUBSYSTEM_OS2_CUI 5 The OS/2 character subsystem IMAGE_SUBSYSTEM_POSIX_CUI 7 The Posix character subsystem IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 Native Win9x driver IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 Windows CE IMAGE_SUBSYSTEM_EFI_APPLICATION 10 An Extensible Firmware Interface (EFI) application IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER 11 An EFI driver with boot services IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER 12 An EFI driver with run-time services IMAGE_SUBSYSTEM_EFI_ROM 13 An EFI ROM image IMAGE_SUBSYSTEM_XBOX 14 XBOX IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16 Windows boot application. Para você que curte programar em C essa tabela é uma *enum* =D. E qual o nosso valor? DllCharacteristics Características da imagem da DLL (isso se for uma, claro). No nosso caso não é então o campo de 16 bits (WORD) estará zerado. SizeOfStackReserve e SizeOfStackCommit Aqui temos 2 DWORDS indicando o espaço que será reservado para a Stack e o espaço que de fato será entregue no momento que carregar a imagem, respectivamente. Se você não sabe muito bem o que é a estrutura de uma pilha aconselho dar uma lidinha rápida =) Aqui no caso será entregue COMMITED bytes e caso precise de mais espaço iremos de crescer uma página de cada vez (consulte o tamanho da página de acordo com a arquitetura) até chegar no valor reservado que é: RESERVED SizeOfHeapReserve e SizeOfHeapCommit Mais duas DWORDS seguidas com a mesma ideia dos campos explicados acima =) LoaderFlags DWORD aparentemente reservada e com o valor zerado NumberOfRvaAndSizes DWORD indicando o número de entradas do DataDirectory (último item da nossa estrutura e que veremos posteriormente). Cada entrada mostra uma localização e um tamanho, respectivamente. Que tal conferirmos tudo isso com o grande readpe do pev? Aparentemente tudo certo...Chegamos ao fim de mais uma estrutura!! Ficou com alguma dúvida? Pretendo pontuar alguns conceitos interessantes para melhor entendimento do PE mais pra frente, mas não deixem de estudar. Conto com vocês para melhorarem as besteiras que eu falo hein . Feedbacks etc etc só mandar bala e obrigado!! Link to comment Share on other sites More sharing options...
Administrators Fernando Mercês Posted October 2, 2017 at 04:08 AM Administrators Share Posted October 2, 2017 at 04:08 AM Muito legal, Leandro. Tem muito pouca material sobre o formato PE em Português, principalmente atualizado. É muito bom te ver desenvolvendo o estudo, programando em C, enfim, estudando ER em geral. Vamos juntos! ;-) Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.