hackedteam/vector-dropper

View on GitHub
RCSDropper/ResourceDirectory.cpp

Summary

Maintainability
Test Coverage
#include "ResourceDirectory.h"
#include "ResourceDirectoryEntry.h"
#include "ResourceDataEntry.h"

#include <iostream>

ResourceDirectory::ResourceDirectory( PIMAGE_RESOURCE_DIRECTORY prd ) 
    : _rdDir(*prd), writtenAt(0)
{
    _rdDir.NumberOfIdEntries = 0;
    _rdDir.NumberOfNamedEntries = 0;
}

void ResourceDirectory::AddEntry( ResourceDirectoryEntry* entry )
{
    int i = 0;
    
    if (entry->HasName()) {
        WCHAR* entryName = entry->GetName();
        
#if 0
        cout << "Adding entry \"" << entryName << "\" ";
#endif        

        for (i = 0; i < _rdDir.NumberOfNamedEntries; i++) {
            WCHAR* name = _entries[i]->GetName();
            int cmp = wcscmp(name, entryName);
            delete [] name;
            if (cmp == 0) {
                delete [] entryName;
                return;
            }
            if (cmp > 0)
                break;
        }
        delete [] entryName;
        _rdDir.NumberOfNamedEntries++;
        
    } else {
        
#if 0
        cout << "Adding entry " << entry->GetId() << " ";
#endif        

        for (i = _rdDir.NumberOfNamedEntries; i < _rdDir.NumberOfNamedEntries + _rdDir.NumberOfIdEntries; i++)
        {
            if (_entries[i]->GetId() == entry->GetId())
                return;
            if (_entries[i]->GetId() > entry->GetId())
                break;
        }
        _rdDir.NumberOfIdEntries++;
    }
    
    //cout << "at position " << i << endl;
    
    _entries.insert(_entries.begin() + i, entry);
}

int ResourceDirectory::Find( WCHAR* name )
{
    if (IS_INTRESOURCE(name))
        return Find((WORD)(DWORD)name);
    else
        if (name[0] == '#')
            return Find(WORD(atoi((PCHAR)name + 1)));
    
    for (UINT i = 0; i < _entries.size(); i++)
    {
        if (_entries[i]->HasName())
            continue;

        WCHAR* entryName = _entries[i]->GetName();
        int cmp = wcscmp(name, entryName);
        delete [] entryName;

        if (!cmp)
            return i;
    }

    return -1;
}

int ResourceDirectory::Find( WORD Id )
{
    for (UINT i = 0; i < _entries.size(); i++)
    {
        if (_entries[i]->HasName())
            continue;

        if (Id == _entries[i]->GetId())
            return i;
    }
    return -1;
}

DWORD ResourceDirectory::GetSize()
{
    DWORD size = sizeof(IMAGE_RESOURCE_DIRECTORY);
    for (UINT i = 0; i < _entries.size(); i++) {
        size += sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);
        if (_entries[i]->HasName())
            size += sizeof(IMAGE_RESOURCE_DIR_STRING_U) + (_entries[i]->GetNameLength() + 1) * sizeof(WCHAR);
        if (_entries[i]->IsDataDirectory())
            size += _entries[i]->GetSubDirectory()->GetSize();
        else {
            DWORD aligned = _entries[i]->GetDataEntry()->GetSize();
            ALIGN(aligned, 8);
            size += sizeof(IMAGE_RESOURCE_DATA_ENTRY) + aligned;
        }
    }
    
    return size;
}

void ResourceDirectory::Destroy()
{
    for (UINT i = 0; i < _entries.size(); i++) {
        if (_entries[i]->IsDataDirectory()) {
            _entries[i]->GetSubDirectory()->Destroy();
            delete _entries[i]->GetSubDirectory();
        } else {
            delete _entries[i]->GetDataEntry();
        }
    }
}