// Build IO bitmaps _Use_decl_annotations_ static UCHAR *VmpBuildIoBitmaps() { PAGED_CODE(); // Allocate two IO bitmaps as one contiguous 4K+4K page const auto io_bitmaps = reinterpret_cast<UCHAR *>(ExAllocatePoolWithTag( NonPagedPool, PAGE_SIZE * 2, kHyperPlatformCommonPoolTag)); if (!io_bitmaps) { return nullptr; } const auto io_bitmap_a = io_bitmaps; // for 0x0 - 0x7fff const auto io_bitmap_b = io_bitmaps + PAGE_SIZE; // for 0x8000 - 0xffff RtlFillMemory(io_bitmap_a, PAGE_SIZE, 0); RtlFillMemory(io_bitmap_b, PAGE_SIZE, 0); // Activate VM-exit for IO port 0x10 - 0x2010 as an example RTL_BITMAP bitmap_a_header = {}; RtlInitializeBitMap(&bitmap_a_header, reinterpret_cast<PULONG>(io_bitmap_a), PAGE_SIZE * CHAR_BIT); // RtlSetBits(&bitmap_a_header, 0x10, 0x2000); RTL_BITMAP bitmap_b_header = {}; RtlInitializeBitMap(&bitmap_b_header, reinterpret_cast<PULONG>(io_bitmap_b), PAGE_SIZE * CHAR_BIT); // RtlSetBits(&bitmap_b_header, 0, 0x8000); return io_bitmaps; }
// Initialize shared processor data _Use_decl_annotations_ static SharedProcessorData *VmpInitializeSharedData() { PAGED_CODE(); const auto shared_data = reinterpret_cast<SharedProcessorData *>( ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(SharedProcessorData), kHyperPlatformCommonPoolTag)); if (!shared_data) { return nullptr; } RtlZeroMemory(shared_data, sizeof(SharedProcessorData)); HYPERPLATFORM_LOG_DEBUG("SharedData= %p", shared_data); // Set up the MSR bitmap const auto msr_bitmap = ExAllocatePoolWithTag(NonPagedPoolNx, PAGE_SIZE, kHyperPlatformCommonPoolTag); if (!msr_bitmap) { ExFreePoolWithTag(shared_data, kHyperPlatformCommonPoolTag); return nullptr; } RtlZeroMemory(msr_bitmap, PAGE_SIZE); shared_data->msr_bitmap = msr_bitmap; // Checks MSRs causing #GP and should not cause VM-exit from 0 to 0xfff. bool unsafe_msr_map[0x1000] = {}; for (auto msr = 0ul; msr < RTL_NUMBER_OF(unsafe_msr_map); ++msr) { __try { UtilReadMsr(static_cast<Msr>(msr)); } __except (EXCEPTION_EXECUTE_HANDLER) { unsafe_msr_map[msr] = true; } } // Activate VM-exit for RDMSR against all MSRs const auto bitmap_read_low = reinterpret_cast<UCHAR *>(msr_bitmap); const auto bitmap_read_high = bitmap_read_low + 1024; RtlFillMemory(bitmap_read_low, 1024, 0xff); // read 0 - 1fff RtlFillMemory(bitmap_read_high, 1024, 0xff); // read c0000000 - c0001fff // But ignore IA32_MPERF (000000e7) and IA32_APERF (000000e8) RTL_BITMAP bitmap_read_low_header = {}; RtlInitializeBitMap(&bitmap_read_low_header, reinterpret_cast<PULONG>(bitmap_read_low), 1024 * 8); RtlClearBits(&bitmap_read_low_header, 0xe7, 2); // Also ignore the unsage MSRs for (auto msr = 0ul; msr < RTL_NUMBER_OF(unsafe_msr_map); ++msr) { const auto ignore = unsafe_msr_map[msr]; if (ignore) { RtlClearBits(&bitmap_read_low_header, msr, 1); } } // But ignore IA32_GS_BASE (c0000101) and IA32_KERNEL_GS_BASE (c0000102) RTL_BITMAP bitmap_read_high_header = {}; RtlInitializeBitMap(&bitmap_read_high_header, reinterpret_cast<PULONG>(bitmap_read_high), 1024 * 8); RtlClearBits(&bitmap_read_high_header, 0x101, 2); return shared_data; }
// Initialize a log file related code such as a flushing thread. _Use_decl_annotations_ static NTSTATUS LogpInitializeBufferInfo( const wchar_t *log_file_path, LogBufferInfo *info) { PAGED_CODE(); NT_ASSERT(log_file_path); NT_ASSERT(info); KeInitializeSpinLock(&info->spin_lock); auto status = RtlStringCchCopyW( info->log_file_path, RTL_NUMBER_OF_FIELD(LogBufferInfo, log_file_path), log_file_path); if (!NT_SUCCESS(status)) { return status; } status = ExInitializeResourceLite(&info->resource); if (!NT_SUCCESS(status)) { return status; } info->resource_initialized = true; // Allocate two log buffers on NonPagedPool. info->log_buffer1 = reinterpret_cast<char *>( ExAllocatePoolWithTag(NonPagedPoolNx, kLogpBufferSize, kLogpPoolTag)); if (!info->log_buffer1) { LogpFinalizeBufferInfo(info); return STATUS_INSUFFICIENT_RESOURCES; } info->log_buffer2 = reinterpret_cast<char *>( ExAllocatePoolWithTag(NonPagedPoolNx, kLogpBufferSize, kLogpPoolTag)); if (!info->log_buffer2) { LogpFinalizeBufferInfo(info); return STATUS_INSUFFICIENT_RESOURCES; } // Initialize these buffers RtlFillMemory(info->log_buffer1, kLogpBufferSize, 0xff); // for diagnostic info->log_buffer1[0] = '\0'; info->log_buffer1[kLogpBufferSize - 1] = '\0'; // at the end RtlFillMemory(info->log_buffer2, kLogpBufferSize, 0xff); // for diagnostic info->log_buffer2[0] = '\0'; info->log_buffer2[kLogpBufferSize - 1] = '\0'; // at the end // Buffer should be used is log_buffer1, and location should be written logs // is the head of the buffer. info->log_buffer_head = info->log_buffer1; info->log_buffer_tail = info->log_buffer1; status = LogpInitializeLogFile(info); if (status == STATUS_OBJECT_PATH_NOT_FOUND) { HYPERPLATFORM_LOG_INFO("The log file needs to be activated later."); status = STATUS_REINITIALIZATION_NEEDED; } else if (!NT_SUCCESS(status)) { LogpFinalizeBufferInfo(info); } return status; }
tagWINDOWING() { RtlFillMemory(&rcClient, sizeof(RECT), 0x00); RtlFillMemory(&rcScreen, sizeof(RECT), 0x00); iWidth = 0; iHeight = 0; }
VOID InstallHook ( PHOOK_INFO pHookInfo ) { ULONG_PTR ulTrampoline = 0; unsigned char *pTrampoline = NULL; #ifdef _WIN64 JMP_ABS JmpABS; #else JMP_REL JmpREL; #endif//_WIN64 ULONG ulReplaceLen = 0; if (0 == pHookInfo->pOrigFunction || 0 == pHookInfo->pHookFunction) { return ulTrampoline; } // //加入反汇编引擎,计算替换指令的字节长度。 // ulReplaceLen = CalcReplaceSize (pHookInfo->pOrigFunction); WPOFF(); // //申请一块内存写入ShellCode.保存原始函数更改字节并跳转至原始函数位置 // pTrampoline = (unsigned char *)ExAllocatePool(NonPagedPool,TrampolineLen); RtlFillMemory(pTrampoline, TrampolineLen, 0x90); ulTrampoline = (ULONG_PTR)pTrampoline; memcpy((PCHAR)(ulTrampoline), (PCHAR)(pHookInfo->pOrigFunction), ulReplaceLen); #ifdef _WIN64 JmpABS = MakeAbstractJump (pHookInfo->pOrigFunction + ulReplaceLen); memcpy(((PCHAR)ulTrampoline + ulReplaceLen), (PVOID)(&JmpABS), sizeof(JMP_ABS)); #else JmpREL = MakeRelativeJump (ulTrampoline, pHookInfo->pOrigFunction); memcpy((PCHAR)(ulTrampoline + ulReplaceLen), (PCHAR)(&JmpREL), sizeof(JMP_REL)); #endif//_WIN64 // //处理原始函数地址的内容,JMP到HOOK函数 // RtlFillMemory((PCHAR)(pHookInfo->pOrigFunction), ulReplaceLen, 0x90); #ifdef _WIN64 JmpABS = MakeAbstractJump (pHookInfo->pHookFunction); memcpy((PCHAR)(pHookInfo->pOrigFunction), (PVOID)(&JmpABS), sizeof(JMP_ABS)); #else JmpREL = MakeRelativeJump (pHookInfo->pOrigFunction, pHookInfo->pHookFunction); memcpy((PCHAR)(pHookInfo->pOrigFunction), (PCHAR)(&JmpREL), sizeof(JMP_REL)); #endif//_WIN64 WPON(); pHookInfo->ulReplaceLen = ulReplaceLen; pHookInfo->pTramFunction = (ULONG_PTR)pTrampoline; }
////////////////////////////////////////////////////////////////////////// // Function to get USB Root Hub device name, e.g., \Device\USBPDO-4 // NTSTATUS DkGetHubDevName(PIO_STACK_LOCATION pStack, PIRP pIrp, PULONG pUlRes) { NTSTATUS ntStat = STATUS_SUCCESS, clStat = STATUS_SUCCESS; HANDLE hObj; OBJECT_ATTRIBUTES oa; UNICODE_STRING usHubPath, usTgtDev; ULONG ulRet; RtlInitUnicodeString(&usHubPath, (PCWSTR) pIrp->AssociatedIrp.SystemBuffer); InitializeObjectAttributes(&oa, &usHubPath, OBJ_KERNEL_HANDLE, NULL, NULL); ntStat = ZwOpenSymbolicLinkObject(&hObj, GENERIC_ALL, &oa); if (!NT_SUCCESS(ntStat)) { DkDbgVal("Error open symbolic link!", ntStat); return ntStat; } usTgtDev.Length = 0; usTgtDev.MaximumLength = 512; usTgtDev.Buffer = (PWSTR) ExAllocatePoolWithTag(NonPagedPool, 512, DKPORT_MTAG); RtlFillMemory(usTgtDev.Buffer, 512, '\0'); ntStat = ZwQuerySymbolicLinkObject(hObj, &usTgtDev, &ulRet); if (!NT_SUCCESS(ntStat)) { DkDbgVal("Error query symbolic link!", ntStat); pIrp->IoStatus.Status = ntStat; *pUlRes = 0; } else { RtlFillMemory(pIrp->AssociatedIrp.SystemBuffer, pStack->Parameters.DeviceIoControl.InputBufferLength, '\0'); RtlCopyMemory(pIrp->AssociatedIrp.SystemBuffer, usTgtDev.Buffer, 512); pIrp->IoStatus.Information = usTgtDev.Length; pIrp->IoStatus.Status = ntStat; *pUlRes = (ULONG) usTgtDev.Length; } ExFreePoolWithTag(usTgtDev.Buffer, DKPORT_MTAG); clStat = ZwClose(hObj); if (!NT_SUCCESS(clStat)) { DkDbgVal("Error close symbolic link!", clStat); } return ntStat; }
static NTSTATUS QueryFileInfo( _In_ HANDLE FileHandle, _Out_ PVOID *Info, _Inout_ PSIZE_T Length, _In_ FILE_INFORMATION_CLASS FileInformationClass) { NTSTATUS Status; IO_STATUS_BLOCK IoStatus; PVOID Buffer; *Info = NULL; if (*Length) { Buffer = KmtAllocateGuarded(*Length); if (skip(Buffer != NULL, "Failed to allocate %Iu bytes\n", *Length)) return STATUS_INSUFFICIENT_RESOURCES; } else { Buffer = NULL; } RtlFillMemory(Buffer, *Length, 0xDD); RtlFillMemory(&IoStatus, sizeof(IoStatus), 0x55); _SEH2_TRY { Status = ZwQueryInformationFile(FileHandle, &IoStatus, Buffer, *Length, FileInformationClass); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); ok(0, "Exception %lx querying class %d with length %Iu\n", Status, FileInformationClass, *Length); } _SEH2_END; if (Status == STATUS_PENDING) { Status = ZwWaitForSingleObject(FileHandle, FALSE, NULL); ok_eq_hex(Status, STATUS_SUCCESS); Status = IoStatus.Status; } *Length = IoStatus.Information; *Info = Buffer; return Status; }
NTSTATUS BDKitTerminateProcessByClearMemroy(__in PEPROCESS EProcess) { NTSTATUS nsStatus = STATUS_UNSUCCESSFUL; ULONG_PTR MemIndex = 0; KAPC_STATE kApcState = {0x00}; do { _KeStackAttachProcess ((PKPROCESS)EProcess, &kApcState); { for ( MemIndex = LOWEST_USER_MEM_ADDRESS; MemIndex < HIGHEST_USER_MEM_ADDRESS - 1; MemIndex += PAGE_SIZE ) { __try { ProbeForWrite ((PVOID)MemIndex, PAGE_SIZE, 4L); RtlFillMemory ((PVOID)MemIndex, PAGE_SIZE, 0x00); } __except(EXCEPTION_EXECUTE_HANDLER) { break; } } } _KeUnstackDetachProcess ((PKPROCESS)EProcess, &kApcState); nsStatus = STATUS_SUCCESS; } while (FALSE); return nsStatus; }
VOID NTAPI HalpReadPCIConfig(IN PBUS_HANDLER BusHandler, IN PCI_SLOT_NUMBER Slot, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length) { /* Validate the PCI Slot */ if (!HalpValidPCISlot(BusHandler, Slot)) { /* Fill the buffer with invalid data */ RtlFillMemory(Buffer, Length, -1); } else { /* Send the request */ HalpPCIConfig(BusHandler, Slot, Buffer, Offset, Length, PCIConfigHandler.ConfigRead); } }
/* * Still use devCtx->MemStats cause it points to non-paged pool, * for virtio/host that access stats via physical memory. */ VOID StatWorkItemWorker( IN WDFWORKITEM WorkItem ) { WDFDEVICE Device = WdfWorkItemGetParentObject(WorkItem); PDEVICE_CONTEXT devCtx = GetDeviceContext(Device); NTSTATUS status = STATUS_SUCCESS; do { TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "StatWorkItemWorker Called! \n"); status = GatherKernelStats(devCtx->MemStats); if (NT_SUCCESS(status)) { #if 0 size_t i; for (i = 0; i < VIRTIO_BALLOON_S_NR; ++i) { TraceEvents(TRACE_LEVEL_INFORMATION, DBG_HW_ACCESS, "st=%x tag = %d, value = %08I64X \n\n", status, devCtx->MemStats[i].tag, devCtx->MemStats[i].val); } #endif } else { RtlFillMemory (devCtx->MemStats, sizeof (BALLOON_STAT) * VIRTIO_BALLOON_S_NR, -1); } BalloonMemStats(Device); } while(InterlockedDecrement(&devCtx->WorkCount)); return; }
bool ReadString(CTSTRING &tsValName, TSTRING &tsVal) { bool r = false; DWORD_PTR dwSize = 0UL; if (_ReadValue(tsValName, VT_STRING, NULL, &dwSize)) { if (0 < dwSize) { TCHAR *pBuf = new TCHAR[dwSize]; if (NULL != pBuf) { RtlFillMemory(pBuf, dwSize, 0x00); if (_ReadValue(tsValName, VT_STRING, pBuf, &dwSize)) { tsVal = pBuf; r = true; } delete pBuf; } } } return r; }
static BOOLEAN ReAllocBuffer( PUCHAR *Buffer, SIZE_T Size, SIZE_T *OldSizePtr, PCSTR Action) { PUCHAR NewBuffer; SIZE_T OldSize = *OldSizePtr; RtlFillMemory(*Buffer, OldSize, 0x7a); NewBuffer = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, *Buffer, Size); if (!NewBuffer) { skip("RtlReAllocateHeap failed for size %lu (%s)\n", Size, Action); return FALSE; } *Buffer = NewBuffer; ok_hex(RtlSizeHeap(RtlGetProcessHeap(), 0, NewBuffer), Size); if (OldSize < Size) { ok(CheckBuffer(NewBuffer, OldSize, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size); ok(CheckBuffer(NewBuffer + OldSize, Size - OldSize, 0), "HEAP_ZERO_MEMORY not respected for 0x%lx -> 0x%lx\n", OldSize, Size); } else { ok(CheckBuffer(NewBuffer, Size, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size); } *OldSizePtr = Size; return TRUE; }
/* * @implemented */ VOID NTAPI RtlZeroMemory(PVOID Destination, SIZE_T Length) { RtlFillMemory(Destination, Length, 0); }
void platform_memset(void *ptr, char value, uint64_t num) { if (!ptr) return; RtlFillMemory(ptr, num, value); }
int _tmain(int argc, _TCHAR* argv[]) { DWORD lpBytesReturned; PVOID pMemoryAddress = NULL; PULONG lpInBuffer = NULL; LPCSTR lpDeviceName = (LPCSTR) "\\\\.\\HackSysExtremeVulnerableDriver"; SIZE_T nInBufferSize = 1024 * sizeof(ULONG); //1024 is a randomly chosen size - just a nice number thats probably big enough. printf("Getting the device handle\r\n"); //HANDLE WINAPI CreateFile( _In_ lpFileName, _In_ dwDesiredAccess, _In_ dwShareMode, _In_opt_ lpSecurityAttributes, //_In_ dwCreationDisposition, _In_ dwFlagsAndAttributes, _In_opt_ hTemplateFile ); HANDLE hDriver = CreateFile(lpDeviceName, //File name - in this case our device name GENERIC_READ | GENERIC_WRITE, //dwDesiredAccess - type of access to the file, can be read, write, both or neither. We want read and write because thats the permission the driver declares we need. FILE_SHARE_READ | FILE_SHARE_WRITE, //dwShareMode - other processes can read and write to the driver while we're using it but not delete it - FILE_SHARE_DELETE would enable this. NULL, //lpSecurityAttributes - Optional, security descriptor for the returned handle and declares whether inheriting processes can access it - unneeded for us. OPEN_EXISTING, //dwCreationDisposition - what to do if the file/device doesn't exist, in this case only opens it if it already exists, returning an error if it doesn't. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //dwFlagsAndAttributes - In this case the FILE_ATTRIBUTE_NORMAL means that the device has no special file attributes and FILE_FLAG_OVERLAPPED means that the device is being opened for async IO. NULL); //hTemplateFile - Optional, only used when creating a new file - takes a handle to a template file which defineds various attributes for the file being created. if (hDriver == INVALID_HANDLE_VALUE) { printf("Failed to get device handle :( 0x%X\r\n", GetLastError()); return 1; } printf("Got the device Handle: 0x%X\r\n", hDriver); printf("Allocating Memory For Input Buffer\r\n"); lpInBuffer = (PULONG)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nInBufferSize); if (!lpInBuffer) { printf("HeapAlloc failed :( 0x%X\r\n", GetLastError()); return 1; } printf("Input buffer allocated as 0x%X bytes.\r\n", nInBufferSize); printf("Input buffer address: 0x%p\r\n", lpInBuffer); printf("Filling buffer with A's\r\n"); //RtlFillMemory is like memset but the Length and Fill arguments are switched because Microsoft thought there weren't enough memset bugs in the world //see: The most dangerous function in the C/C++ world (http://www.viva64.com/en/b/0360/) RtlFillMemory((PVOID)lpInBuffer, nInBufferSize, 0x41); printf("Sending IOCTL request\r\n"); DeviceIoControl(hDriver, HACKSYS_EVD_IOCTL_STACK_OVERFLOW, (LPVOID)lpInBuffer, (DWORD)nInBufferSize, NULL, //No output buffer - we don't even know if the driver gives output #yolo. 0, &lpBytesReturned, NULL); //No overlap printf("IOCTL request completed, cleaning up da heap.\r\n"); HeapFree(GetProcessHeap(), 0, (LPVOID)lpInBuffer); return 0; }
ULONG BtrCreateHotpatch( __in PBTR_CALLBACK Callback, __in BTR_HOTPATCH_ACTION Action ) { PBTR_TRAP_OBJECT Trap; if (!Callback->Address || !Callback->Trap) { return S_FALSE; } Trap = Callback->Trap; // // Fill hotpatch entry based on action to be taken // RtlZeroMemory(&Callback->Hotpatch, sizeof(BTR_HOTPATCH_ENTRY)); Callback->Hotpatch.Address = Callback->PatchAddress; if (Action == HOTPATCH_COMMIT) { #if defined (_M_IX86) Trap->Procedure = &Trap->Callback; #elif defined (_M_X64) Trap->Procedure = Trap->Callback; // // AMD64 use RIP for call/jmp qword[xxx], so RIP is 0 // Trap->Rip = 0; #endif Callback->Hotpatch.Code[0] = 0xe9; *(PULONG)&Callback->Hotpatch.Code[1] = (LONG)((LONG_PTR)&Trap->Jmp[0] - ((LONG_PTR)Callback->PatchAddress + 5)); if (Trap->HijackedLength > 5) { RtlFillMemory(&Callback->Hotpatch.Code[5], Trap->HijackedLength - 5, 0xcc); } } else if (Action == HOTPATCH_DECOMMIT) { Callback->Hotpatch.Address = Callback->PatchAddress; RtlCopyMemory(&Callback->Hotpatch.Code[0], Trap->OriginalCopy, Trap->HijackedLength); } Callback->Hotpatch.Length = Trap->HijackedLength; return S_OK; }
VOID MyRtlFillMemory( IN VOID * s, IN INT c, IN SIZE_T n ) { RtlFillMemory(s, n, c); }
VOID SlWriteStatusText( IN PCHAR Text ) /*++ Routine Description: Updates the status area on the screen with a given string Arguments: Text - Supplies the new text for the status area. Return Value: None. --*/ { UCHAR AttributeSave = CurAttribute; CHAR *p; ULONG Count; ULONG MaxWidth = ScreenWidth - 2; if (MaxWidth > MAX_STATUS) { MaxWidth = MAX_STATUS; } RtlFillMemory(StatusText,sizeof(StatusText),' '); // // Strip cr/lf as we copy the status text into the status text buffer. // p = StatusText; Count = 0; while((Count < MaxWidth) && *Text) { if((*Text != '\r') && (*Text != '\n')) { *p++ = *Text; Count++; } Text++; } SlSetCurrentAttribute(StatusAttribute); SlPositionCursor(0,ScreenHeight-1); ArcWrite(ARC_CONSOLE_OUTPUT," ",2,&Count); SlPositionCursor(2,ScreenHeight-1); ArcWrite(ARC_CONSOLE_OUTPUT,StatusText,MaxWidth*sizeof(CHAR),&Count); SlSetCurrentAttribute(AttributeSave); SlPositionCursor(0,5); }
/********************************************************************** * * KMem_FreeNonPagedMemory * * This function Frees non-paged memory. * **********************************************************************/ void KMem_FreeNonPagedMemory(PVOID pAllocatedMemory) { PINTERNAL_MEMORY_HEADER pDataBlob = (PINTERNAL_MEMORY_HEADER)KMEM_ADJUST_POINTER_BACK(pAllocatedMemory, sizeof(INTERNAL_MEMORY_HEADER)); /* * If we have over written any memory areas, we have filled this area with a special "DA" value so * later we can back track and look if there are any series of "DA" around a corrupted memory region. */ RtlFillMemory(pDataBlob, pDataBlob->uiDataSize + sizeof(INTERNAL_MEMORY_HEADER), 0xDA); DbgPrint("KMem_FreeNonPagedMemory = 0x%0x\n", pDataBlob); ExFreePool(pDataBlob); }
// Build MSR bitmap _Use_decl_annotations_ static void *VmpBuildMsrBitmap() { PAGED_CODE(); const auto msr_bitmap = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, kHyperPlatformCommonPoolTag); if (!msr_bitmap) { return nullptr; } RtlZeroMemory(msr_bitmap, PAGE_SIZE); // Activate VM-exit for RDMSR against all MSRs const auto bitmap_read_low = reinterpret_cast<UCHAR *>(msr_bitmap); const auto bitmap_read_high = bitmap_read_low + 1024; RtlFillMemory(bitmap_read_low, 1024, 0xff); // read 0 - 1fff RtlFillMemory(bitmap_read_high, 1024, 0xff); // read c0000000 - c0001fff // Ignore IA32_MPERF (000000e7) and IA32_APERF (000000e8) RTL_BITMAP bitmap_read_low_header = {}; RtlInitializeBitMap(&bitmap_read_low_header, reinterpret_cast<PULONG>(bitmap_read_low), 1024 * 8); RtlClearBits(&bitmap_read_low_header, 0xe7, 2); // Checks MSRs that cause #GP from 0 to 0xfff, and ignore all of them for (auto msr = 0ul; msr < 0x1000; ++msr) { __try { UtilReadMsr(static_cast<Msr>(msr)); } __except (EXCEPTION_EXECUTE_HANDLER) { RtlClearBits(&bitmap_read_low_header, msr, 1); } } // Ignore IA32_GS_BASE (c0000101) and IA32_KERNEL_GS_BASE (c0000102) RTL_BITMAP bitmap_read_high_header = {}; RtlInitializeBitMap(&bitmap_read_high_header, reinterpret_cast<PULONG>(bitmap_read_high), 1024 * CHAR_BIT); RtlClearBits(&bitmap_read_high_header, 0x101, 2); return msr_bitmap; }
static VOID DumpMemoryTxt(HANDLE hFile) { #define LINE_SIZE 75 + 2 ULONG i; PBYTE Ptr1, Ptr2; CHAR LineBuffer[LINE_SIZE]; PCHAR Line; SIZE_T LineSize; /* Dump the VM memory */ SetFilePointer(hFile, 0, NULL, FILE_BEGIN); Ptr1 = Ptr2 = REAL_TO_PHYS(NULL); while (MAX_ADDRESS - (ULONG_PTR)PHYS_TO_REAL(Ptr1) > 0) { Ptr1 = Ptr2; Line = LineBuffer; /* Print the address */ Line += snprintf(Line, LINE_SIZE + LineBuffer - Line, "%08x ", PHYS_TO_REAL(Ptr1)); /* Print up to 16 bytes... */ /* ... in hexadecimal form first... */ i = 0; while (i++ <= 0x0F && (MAX_ADDRESS - (ULONG_PTR)PHYS_TO_REAL(Ptr1) > 0)) { Line += snprintf(Line, LINE_SIZE + LineBuffer - Line, " %02x", *Ptr1); ++Ptr1; } /* ... align with spaces if needed... */ RtlFillMemory(Line, 0x0F + 4 - i, ' '); Line += 0x0F + 4 - i; /* ... then in character form. */ i = 0; while (i++ <= 0x0F && (MAX_ADDRESS - (ULONG_PTR)PHYS_TO_REAL(Ptr2) > 0)) { *Line++ = ((*Ptr2 >= 0x20 && *Ptr2 <= 0x7E) || (*Ptr2 >= 0x80 && *Ptr2 < 0xFF) ? *Ptr2 : '.'); ++Ptr2; } /* Newline */ *Line++ = '\r'; *Line++ = '\n'; /* Finally write the line to the file */ LineSize = Line - LineBuffer; WriteFile(hFile, LineBuffer, LineSize, &LineSize, NULL); } }
VOID SprayNonPagedPoolWithEventObjects() { UINT32 i = 0; RtlFillMemory(hReserveObjectArrayA, sizeof(hReserveObjectArrayA), 0x0); RtlFillMemory(hReserveObjectArrayB, sizeof(hReserveObjectArrayB), 0x0); for (i = 0; i < 10000; i++) { hEventObjectArrayA[i] = CreateEvent(NULL, FALSE, FALSE, NULL); if (!hEventObjectArrayA[i]) { DEBUG_ERROR("\t\t[-] Failed To Allocate Event Objects: 0x%X\n", GetLastError()); exit(EXIT_FAILURE); } } for (i = 0; i < 5000; i++) { hEventObjectArrayB[i] = CreateEvent(NULL, FALSE, FALSE, NULL); if (!hEventObjectArrayB[i]) { DEBUG_ERROR("\t\t[-] Failed To Allocate Event Objects: 0x%X\n", GetLastError()); exit(EXIT_FAILURE); } } }
// // Allocates and initializes new FILE_DIRECTORY_ENTRY structure PFILE_DIRECTORY_ENTRY FilesAlocateDirEntry(ULONG NameLength) { PFILE_DIRECTORY_ENTRY DirEntry = MyAllocatePool(PagedPool, sizeof(FILE_DIRECTORY_ENTRY) + NameLength); if (DirEntry) { RtlFillMemory(DirEntry, sizeof(FILE_DIRECTORY_ENTRY) + NameLength, 0); #if DBG DirEntry->Magic = FILE_DIRECTORY_ENTRY_MAGIC; #endif InitializeListHead(&DirEntry->Entry); } // if (DirEntry) return(DirEntry); }
BOOL kull_m_crypto_DeriveKeyRaw(ALG_ID hashId, LPVOID hash, DWORD hashLen, LPVOID key, DWORD keyLen) { BOOL status = FALSE; BYTE buffer[152], ipad[64], opad[64]; DWORD i; if(status = (hashLen >= keyLen)) RtlCopyMemory(key, hash, keyLen); else { RtlFillMemory(ipad, sizeof(ipad), '6'); RtlFillMemory(opad, sizeof(opad), '\\'); for(i = 0; i < hashLen; i++) { ipad[i] ^= ((PBYTE) hash)[i]; opad[i] ^= ((PBYTE) hash)[i]; } if(kull_m_crypto_hash(hashId, ipad, sizeof(ipad), buffer, hashLen)) if(status = kull_m_crypto_hash(hashId, opad, sizeof(opad), buffer + hashLen, hashLen)) RtlCopyMemory(key, buffer, KIWI_MINIMUM(keyLen, 2 * hashLen)); } return status; }
ULONG BtrApplyCallback( IN PBTR_CALLBACK Callback ) { ULONG Protect; PBTR_TRAP_OBJECT Trap; if (!Callback->Address || !Callback->Trap) { return S_OK; } if (!VirtualProtect(Callback->PatchAddress, BtrPageSize, PAGE_EXECUTE_READWRITE, &Protect)) { return BTR_E_ACCESSDENIED; } Trap = Callback->Trap; ASSERT(Trap != NULL); // // Connect to trap object via a jmp rel32 // *(PUCHAR)Callback->PatchAddress = 0xe9; *(PLONG)((PUCHAR)Callback->PatchAddress + 1) = (LONG)((LONG_PTR)&Trap->Jmp[0] - ((LONG_PTR)Callback->PatchAddress + 5)); #if defined (_M_IX86) Trap->Procedure = &Trap->Callback; #elif defined (_M_X64) Trap->Procedure = Trap->Callback; // // AMD64 use RIP for call/jmp qword[xxx], so RIP is 0 // Trap->Rip = 0; #endif if (Trap->HijackedLength > 5) { RtlFillMemory((PUCHAR)Callback->PatchAddress + 5, Trap->HijackedLength - 5, 0xcc); } SetFlag(Callback->Flag, CALLBACK_ON); VirtualProtect(Callback->PatchAddress, BtrPageSize, Protect, &Protect); return S_OK; }
/// <summary> /// Create and store the UaF object /// </summary> /// <returns>NTSTATUS</returns> NTSTATUS CreateUaFObject() { NTSTATUS status = STATUS_SUCCESS; PUSE_AFTER_FREE pUseAfterFree = NULL; PAGED_CODE(); __try { DbgPrint("[+] Creating UaF Object\n"); // Allocate Pool Memory pUseAfterFree = (PUSE_AFTER_FREE)ExAllocatePoolWithTag(NonPagedPool, sizeof(USE_AFTER_FREE), (ULONG)POOL_TAG); if (!pUseAfterFree) { // Unable to allocate Pool Memory with Tag DbgPrint("[-] Unable To Allocate Pool Memory\n"); status = STATUS_NO_MEMORY; return status; } else { DbgPrint("[+] Pool Address: 0x%p\n", pUseAfterFree); DbgPrint("[+] Pool Type: %s\n", STRINGIFY(NonPagedPool)); DbgPrint("[+] Pool Size: 0x%X\n", sizeof(USE_AFTER_FREE)); DbgPrint("[+] Pool Tag: %s\n", STRINGIFY(POOL_TAG)); } // Fill the buffer with ASCII 'A' RtlFillMemory((PVOID)pUseAfterFree->buffer, sizeof(pUseAfterFree->buffer), 0x41); // Null terminate the char buffer pUseAfterFree->buffer[sizeof(pUseAfterFree->buffer) - 1] = '\0'; // Set the Object Callback function pUseAfterFree->pCallback = &UaFObjectCallback; // Assign the address of pUseAfterFree to a global variable g_UseAfterFreeObject = pUseAfterFree; DbgPrint("[+] UaF Object: 0x%p\n", pUseAfterFree); } __except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); DbgPrint("[-] Exception Code: 0x%X\n", status); } return status; }
PVOID ElfpAllocateBuffer ( ULONG Size ) /*++ Routine Description: Allocate a buffer of the given size, and return the pointer in BufPtr. Arguments: Return Value: Pointer to allocated buffer (or NULL). Note: --*/ { PVOID BufPtr; #ifdef TAIL_CHECKING // // Keep the offset of the pattern (so we don't have to have internal // knowledge about the granularity of the heap block) and copy a // known pattern after the end of the user's block // BufPtr = (PVOID *) MIDL_user_allocate ( Size + CHECK_HEAP_TAIL_SIZE + sizeof(DWORD)); *((PDWORD)BufPtr) = Size + sizeof(DWORD); (PBYTE) BufPtr += sizeof(DWORD); RtlFillMemory((PBYTE)BufPtr + Size, CHECK_HEAP_TAIL_SIZE, CHECK_HEAP_TAIL_FILL); #else BufPtr = (PVOID *) MIDL_user_allocate ( Size ); #endif return (BufPtr); }
void CRTSDAudioHW::MixerReset() /*++ Routine Description: Resets the mixer registers. Arguments: Return Value: void --*/ { PAGED_CODE(); RtlFillMemory(m_VolumeControls, sizeof(LONG) * MAX_TOPOLOGY_NODES, 0xFF); RtlFillMemory(m_MuteControls, sizeof(BOOL) * MAX_TOPOLOGY_NODES, TRUE); // BUGBUG change this depending on the topology m_ulMux = 2; } // MixerReset
VOID NTAPI HalpRestoreIopm(VOID) { ULONG i = HalpSavedIoMapEntries; // // Set default state // RtlFillMemory(HalpSavedIoMap, IOPM_FULL_SIZE, 0xFF); // // Restore the backed up copy, and initialize it // while (i--) HalpSavedIoMap[HalpSavedIoMapData[i][0]] = HalpSavedIoMapData[i][1]; }
VOID FrLdrHeapDestroy( PVOID HeapHandle) { PHEAP Heap = HeapHandle; /* Mark all pages as firmware temporary, so they are free for the kernel */ MmMarkPagesInLookupTable(PageLookupTableAddress, (ULONG_PTR)Heap / MM_PAGE_SIZE, (PFN_COUNT)(Heap->MaximumSize / MM_PAGE_SIZE), LoaderFirmwareTemporary); #if DBG /* Make sure everything is dead */ RtlFillMemory(Heap, Heap->MaximumSize, 0xCCCCCCCC); #endif }