//Exo pour assimiler le PE.

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define USAGE "usage : ./%s <file>.\r\n"

int main(int argc , char* argv[])
{
    printf("ViewTheFuckinPE par 0vercl0k.\n");
    if(!argv[1]){printf(USAGE,argv[0]);return 0;}

    PIMAGE_DOS_HEADER infosExecutable; // Pointeur de Structure qui va nous permettre de stocker des infos , et de trouver l'addresse du PE header entre autre.
    PIMAGE_NT_HEADERS infosPE; // Pointeur de Structure qui va permettre de sotcker des infos sur le PE.

    HANDLE executableHandle = CreateFile(argv[1] , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , 0 , 0) , // CreateFile -> http://msdn2.microsoft.com/en-us/library/aa363858.aspx
           executableMappe = CreateFileMapping(executableHandle , NULL , PAGE_READONLY , 0 , 0 , NULL) ; //CreateFileMapping() -> http://msdn2.microsoft.com/en-us/library/aa366537.aspx

    LPVOID executableEnMemoire = MapViewOfFile(executableMappe , FILE_MAP_READ , 0 , 0 , 0); //MapViewOfFile -> http://msdn2.microsoft.com/en-us/library/aa366761.aspx


    if(executableHandle == INVALID_HANDLE_VALUE || executableMappe == INVALID_HANDLE_VALUE || executableEnMemoire == INVALID_HANDLE_VALUE)return 0;

    infosExecutable = (PIMAGE_DOS_HEADER)executableEnMemoire;

    if(infosExecutable->e_magic != IMAGE_DOS_SIGNATURE)
    {
        printf("[!] Il ne s'agit pas d'un binaire au format PE.\n");
        return 0;
    }

    printf("[~] Analyse en cours : \n");
    printf("- Entete DOS : %08X.\n",infosExecutable->e_magic);
    printf("- Adresse de la table de realocation : %08X.\n",infosExecutable->e_lfarlc);
    printf("- Adresse de l'entete PE de notre executable : %08X.\n",infosExecutable->e_lfanew);

    infosPE = (PIMAGE_NT_HEADERS)((char*)infosExecutable + infosExecutable->e_lfanew);// On trouve l'adresse du PE Header soit , celle du debut du fichier mappé + celle du pe header.
    //Nous caston en char* parce que si nous ne castons pas nous allons ajouter (infosExecutable->e_lfanew * sizeof(IMAGE_NT_HEADER)) une structure + 1 c'est incremmenter de 1 * sazise.

    if(infosPE->Signature != IMAGE_NT_SIGNATURE)
    {
        printf("[-] La signature PE est corrompu.\n");
        return 0;
    }

    printf("\n---<PE header>---\n\n- Signature PE : %08X\n",infosPE->Signature);
    printf("- Machine qui à compiler le binaire : %08X\n- Adresse du point d'entré : %08X\n",infosPE->FileHeader.Machine,infosPE->OptionalHeader.AddressOfEntryPoint);
    printf("- Nombre de sections (NumberOfSections) : %08X\n- Offset de la table des symboles (PointerToSymbolTable) : %08X\n",infosPE->FileHeader.NumberOfSections,infosPE->FileHeader.PointerToSymbolTable);
    printf("- Adresse Image Base (ImagaBase) : %08X\n\n---</PE header>---\n---<Sections>---\n\n",infosPE->OptionalHeader.ImageBase);

    PIMAGE_SECTION_HEADER infosSection = (PIMAGE_SECTION_HEADER)((char*)infosPE + sizeof(IMAGE_NT_HEADERS));

    for(int i = 0 ; i < (infosPE->FileHeader.NumberOfSections) ; i++)
    {
        printf("- Section %d(%s) : \n\t ->Adresse Virtual (RVA de la section) (VirtualAddress) : %08X\n\n",i,(char*)infosSection->Name,infosSection->VirtualAddress);
        infosSection++;
    }
    return 0;
}