PE basis 4- practice - Import table - Table everywhere - relocation table - written in the new file overwrite

PE basic training

 

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

struct TypeOffset
{
    WORD Offset : 12;
    WORD Type : 4;
};

// Save the file size 
DWORD FileSize = 0 ;

// Save the file base address 
DWORD FileBase;

// Save DOS head 
PIMAGE_DOS_HEADER DosHeader = nullptr;

PIMAGE_NT_HEADERS NtHeader = nullptr;


DWORD RVAtoFOA(DWORD rva)
{
    @ 1 acquires the section table 
    Auto SectionTables = IMAGE_FIRST_SECTION (NtHeader);

    // 2. Get the number of zones 
    WORD = NtHeader- the Count> FileHeader.NumberOfSections;

    // 3. The traversing sections 
    for ( int I = 0 ; I <the Count; ++ I)
    {
        // 4 determines whether or not present in the zone 
        IF (RVA> = SectionTables [I] && .VirtualAddress 
            RVA <(SectionTables [I] + .VirtualAddress SectionTables [I] .SizeOfRawData))
        {
            // calculate the location and returns the value 5. After Found 
            return RVA - SectionTables [I] + .VirtualAddress SectionTables [I] .PointerToRawData;
        }
    }

    // 6. not found return -1 
    return - . 1 ;
}


VOID OpenPeFile(LPCSTR FileName)
{
    // Open the file 
    HANDLE the Handle = CreateFileA (FileName, GENERIC_READ, NULL,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    // 2. Get File Size 
    FileSize = GetFileSize (the Handle, NULL);

    // 3. The read file data 
    DWORD OperSize = 0 ;
    FileBase = (DWORD)new BYTE[FileSize];
    ReadFile(Handle, (LPVOID)FileBase, FileSize, &OperSize, NULL);

    // 4. Analyzing is not a valid PE file
     // 4.1 DOS header and determines acquisition is not a valid DOS file 
    DosHeader = (PIMAGE_DOS_HEADER) FileBase;
     IF (! DosHeader-> e_magic = IMAGE_DOS_SIGNATURE)
    {
        MessageBox (NULL, " is not a valid DOS file " , " tips " , MB_OK);
        system("pause"); exit(0);
    }

    // 4.2 NT header and determines acquisition is not a valid PE file 
    NtHeader = (PIMAGE_NT_HEADERS) (+ FileBase DosHeader-> e_lfanew which);
     IF (! NtHeader-> the Signature = named IMAGE_NT_SIGNATURE)
    {
        MessageBox (NULL, " not a valid PE file " , " tips " , MB_OK);
        system("pause"); exit(0);
    }

    // 4.3 Analyzing file is not a 32-bit 
    IF (NtHeader-> OptionalHeader.Magic! = 0x010B )
    {
        The MessageBox (NULL, " is not a valid 32-bit file " , " prompt " , MB_OK);
        system("pause"); exit(0);
    }

    CloseHandle(Handle);
}

// iterate relocation table 
VOID FixReloc ()
{
    DWORD base = NtHeader->OptionalHeader.ImageBase;

    // 1. Get the relocation table RVA 
    DWORD RelocRVA = NtHeader-> OptionalHeader.DataDirectory [ . 5 ] .VirtualAddress;

    // 2. Get the relocation table 
    Auto Reloc = (PIMAGE_BASE_RELOCATION) (+ FileBase RVAtoFOA (RelocRVA));

    // 3. traversing relocation block relocation table, 0 to end 
    the while (Reloc-> SizeOfBlock! = 0 )
    {
        // 3.1 paging group address output 
        the printf ( " PAGE_BASE:% 08X \ n- " , Reloc-> the VirtualAddress);
    
        // 3.2 relocation entries found 
        Auto Offset = (TypeOffset *) (+ Reloc . 1 );
        
        // number of 3.3 is calculated relocation entries
         // Reloc-> Saved SizeOfBlock relocation entire size of the block structure + relocation entry array
         // Reloc-> SizeOfBlock - the sizeof (IMAGE_BASE_RELOCATION) obtained array size
         // above results \ number, reason = 2 relocation entry is the size of the relocation entries is two bytes 
        DWORD = size (Reloc-> SizeOfBlock - the sizeof (IMAGE_BASE_RELOCATION)) / 2 ;

        // 3.4 traverse all relocation entries 
        for ( int I = 0 ; I <Size; ++ I)
        {
            // Get relocation type, only 3 of the type concerned 
            DWORD the Type = Offset [I] .Type;

            // Get relocation offset 
            DWORD pianyi = Offset [I] .offset;

            // Get RVA be relocated address is located: offset + VirtualAddress 
            DWORD RVA = pianyi Reloc- +> the VirtualAddress;

            // Get be relocated address is located FOA 
            DWORD FOA = RVAtoFOA (RVA);

            // Get be relocated address is located FA 
            DWORD = FA + FOA FileBase;

            // Get address to be relocated 
            DWORD * addr = (DWORD * ) FA;

            // Calculation data relocation: addr - oldbase + newbase 
            DWORD to new_addr = addr - Base + 0x1500000 ;

            // The relocation data write back buffer (file) 
            IF (Offset [I] .Type == . 3 )
                 * (DWORD *) FA = to new_addr;

            // printf("\tT(%d)%08X->%08X: %08X[%08X]\n", Type, rva, foa, addr, new_addr);
        }

        // find the next relocation block 
        Reloc = (PIMAGE_BASE_RELOCATION)
            ((DWORD)Reloc + Reloc->SizeOfBlock);
    }

    NtHeader->OptionalHeader.ImageBase = 0x1500000;

    // Open the file 
    HANDLE the Handle = CreateFileA ( " newfile.exe " , GENERIC_WRITE, NULL,
        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);


    // 3. writing file data 
    DWORD OperSize = 0 ;
    WriteFile(Handle, (LPVOID)FileBase, FileSize, &OperSize, NULL);

    CloseHandle(Handle);
}

VOID Import()
{
    // 1. From the index data directory table to find an entry for the RVA 
    DWORD RAV = NtHeader-> OptionalHeader.DataDirectory [ 1 ] .VirtualAddress;

    // 2. Locate the import table structure 
    Auto ImportTable = (PIMAGE_IMPORT_DESCRIPTOR) (RVAtoFOA (RAV) + FileBase);

    // 3. traversing the import table array, the array to the end of the all-zero 
    the while (ImportTable-> the Name)
    {
        // name corresponding to the output of the DLL 4 
        CHAR * DllName = (CHAR *) (RVAtoFOA (ImportTable-> the Name) + FileBase);
        printf("DLLName: %s\n", DllName);

        // 5. 找到 iat
        auto Iat = (PIMAGE_THUNK_DATA)(RVAtoFOA(ImportTable->FirstThunk) + FileBase);

        // 6. traversal iat, all 0s ends 
        the while (Iat-> u1.Ordinal! = 0 )
        {
            // 7. determine whether the name 
            IF (Iat-> u1.AddressOfData & 0x80000000 )
            {
                // number introduced directly outputs 
                the printf ( " \ T [% HD]: None \ n- " , the LOWORD (Iat-> u1.AddressOfData));
            }
            else
            {
                // find the name of the structure 
                Auto the Name = (PIMAGE_IMPORT_BY_NAME) (RVAtoFOA (Iat-> u1.AddressOfData) + FileBase);
                printf("\t[%hd]: %s\n", Name->Hint, Name->Name);
            }
            ++ Here;
        }

        // points to the next structure 
        ImportTable ++ ;
    }

}

VOID Export()
{
    // 1. From the index data directory table entry is found 0 RVA 
    DWORD RAV = NtHeader-> OptionalHeader.DataDirectory [ 0 ] .VirtualAddress;

    // 2. Locate the import table structure 
    Auto ExportTable = (PIMAGE_EXPORT_DIRECTORY) (RVAtoFOA (RAV) + FileBase);

    // 3. Get function with the name and number of the total number 
    DWORD NameCount = ExportTable-> NumberOfNames;
    DWORD FunctionCount = ExportTable->NumberOfFunctions;

    // 4. Get three tables, the table number is WORD 
    DWORD * address = (DWORD *) (RVAtoFOA (ExportTable-> the AddressOfFunctions) + FileBase);
    DWORD* 名称表 = (DWORD*)(RVAtoFOA(ExportTable->AddressOfNames) + FileBase);
    WORD* 序号表 = (WORD*)(RVAtoFOA(ExportTable->AddressOfNameOrdinals) + FileBase);
    
    // 5. traverses the address table 
    for ( int I = 0 ; I <FunctionCount; ++ I)
    {
        bool HaveName = FALSE;

        // 6 determines whether or not there is the name, it has a name, there will be the subscript number table 
        for ( int J = 0 ; J <NameCount; ++ J)
        {
            // There name 
            IF (I == number table [j])
            {
                HaveName = TRUE;
                 // corresponding to subject name table stored in the table is the name of the number 
                CHAR * Name = (CHAR *) (RVAtoFOA ( table name [J]) + FileBase);

                the printf ( " [HD%]:% P% S \ n- " , I + ExportTable-> Base, address [I], the Name);
                 BREAK ;
            }
        }

        // If you have not finished all looking for the name of 
        IF (HaveName == FALSE)
        {
            the printf ( " [% HD]: None P% \ n- " , I + ExportTable-> Base, address [I]);
        }

    }
}

int main ()
{
    OpenPeFile("test.dll");

    // FixReloc();
    // Import();
    // Export();

    return 0;
}

 

Guess you like

Origin www.cnblogs.com/ltyandy/p/11099355.html