/* * @implemented */ BOOL APIENTRY NtGdiEngAlphaBlend(IN SURFOBJ *psoDest, IN SURFOBJ *psoSource, IN CLIPOBJ *ClipRegion, IN XLATEOBJ *ColorTranslation, IN PRECTL upDestRect, IN PRECTL upSourceRect, IN BLENDOBJ *BlendObj) { RECTL DestRect; RECTL SourceRect; _SEH2_TRY { ProbeForRead(upDestRect, sizeof(RECTL), 1); RtlCopyMemory(&DestRect,upDestRect, sizeof(RECTL)); ProbeForRead(upSourceRect, sizeof(RECTL), 1); RtlCopyMemory(&SourceRect, upSourceRect, sizeof(RECTL)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { _SEH2_YIELD(return FALSE); } _SEH2_END; return EngAlphaBlend(psoDest, psoSource, ClipRegion, ColorTranslation, &DestRect, &SourceRect, BlendObj); }
HANDLE FASTCALL renderBITMAPfromDIB(LPBYTE pDIB) { HDC hdc; HBITMAP hbitmap; PBITMAPINFO pBmi, pConvertedBmi = NULL; NTSTATUS Status ; UINT offset = 0; /* Stupid compiler */ pBmi = (BITMAPINFO*)pDIB; //hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE); /* Probe it */ _SEH2_TRY { ProbeForRead(&pBmi->bmiHeader.biSize, sizeof(DWORD), 1); ProbeForRead(pBmi, pBmi->bmiHeader.biSize, 1); ProbeForRead(pBmi, DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS), 1); pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS); if(!pConvertedBmi) { Status = STATUS_INVALID_PARAMETER; } else { offset = DIB_BitmapInfoSize((BITMAPINFO*)pBmi, DIB_RGB_COLORS); ProbeForRead(pDIB + offset, pConvertedBmi->bmiHeader.biSizeImage, 1); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END if(!NT_SUCCESS(Status)) { UserReleaseDC(ClipboardWindow, hdc, FALSE); return NULL; } hbitmap = GreCreateDIBitmapInternal(hdc, pConvertedBmi->bmiHeader.biWidth, pConvertedBmi->bmiHeader.biHeight, CBM_INIT, pDIB+offset, pConvertedBmi, DIB_RGB_COLORS, 0, 0); //UserReleaseDC(NULL, hdc, FALSE); UserReleaseDC(ClipboardWindow, hdc, FALSE); DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi); return hbitmap; }
/* * @implemented */ NTSTATUS NTAPI NtRequestWaitReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply) { PORT_MESSAGE LocalLpcRequest; ULONG NumberOfDataEntries; PLPCP_PORT_OBJECT Port, QueuePort, ReplyPort, ConnectionPort = NULL; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); NTSTATUS Status; PLPCP_MESSAGE Message; PETHREAD Thread = PsGetCurrentThread(); BOOLEAN Callback; PKSEMAPHORE Semaphore; ULONG MessageType; PLPCP_DATA_INFO DataInfo; PAGED_CODE(); LPCTRACE(LPC_SEND_DEBUG, "Handle: %p. Messages: %p/%p. Type: %lx\n", PortHandle, LpcRequest, LpcReply, LpcpGetMessageType(LpcRequest)); /* Check if the thread is dying */ if (Thread->LpcExitThreadCalled) return STATUS_THREAD_IS_TERMINATING; /* Check for user mode access */ if (PreviousMode != KernelMode) { _SEH2_TRY { /* Probe the full request message and copy the base structure */ ProbeForRead(LpcRequest, sizeof(*LpcRequest), sizeof(ULONG)); ProbeForRead(LpcRequest, LpcRequest->u1.s1.TotalLength, sizeof(ULONG)); LocalLpcRequest = *LpcRequest; /* Probe the reply message for write */ ProbeForWrite(LpcReply, sizeof(*LpcReply), sizeof(ULONG)); /* Make sure the data entries in the request message are valid */ Status = LpcpVerifyMessageDataInfo(LpcRequest, &NumberOfDataEntries); if (!NT_SUCCESS(Status)) { DPRINT1("LpcpVerifyMessageDataInfo failed\n"); return Status; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { DPRINT1("Got exception\n"); return _SEH2_GetExceptionCode(); } _SEH2_END; }
NTSTATUS KspEnableEvent( IN PIRP Irp, IN ULONG EventSetsCount, IN const KSEVENT_SET* EventSet, IN OUT PLIST_ENTRY EventsList OPTIONAL, IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, IN PVOID EventsLock OPTIONAL, IN PFNKSALLOCATOR Allocator OPTIONAL, IN ULONG EventItemSize OPTIONAL) { PIO_STACK_LOCATION IoStack; NTSTATUS Status; KSEVENT Event; PKSEVENT_ITEM EventItem, FoundEventItem; PKSEVENTDATA EventData; const KSEVENT_SET *FoundEventSet; PKSEVENT_ENTRY EventEntry; ULONG Index, SubIndex, Size; PVOID Object; KSEVENT_CTX Ctx; LPGUID Guid; /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSEVENT)) { /* invalid parameter */ return STATUS_NOT_SUPPORTED; } if (Irp->RequestorMode == UserMode) { _SEH2_TRY { ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT), sizeof(UCHAR)); ProbeForRead(Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, sizeof(UCHAR)); RtlMoveMemory(&Event, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT)); Status = STATUS_SUCCESS; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Exception, get the error code */ Status = _SEH2_GetExceptionCode(); } _SEH2_END; /* check for success */ if (!NT_SUCCESS(Status)) { /* failed to probe parameters */ return Status; } }
NTSTATUS NTAPI SepCaptureSid(IN PSID InputSid, IN KPROCESSOR_MODE AccessMode, IN POOL_TYPE PoolType, IN BOOLEAN CaptureIfKernel, OUT PSID *CapturedSid) { ULONG SidSize = 0; PISID NewSid, Sid = (PISID)InputSid; NTSTATUS Status; PAGED_CODE(); if (AccessMode != KernelMode) { _SEH2_TRY { ProbeForRead(Sid, FIELD_OFFSET(SID, SubAuthority), sizeof(UCHAR)); SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); ProbeForRead(Sid, SidSize, sizeof(UCHAR)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Return the exception code */ _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; /* allocate a SID and copy it */ NewSid = ExAllocatePool(PoolType, SidSize); if (NewSid != NULL) { _SEH2_TRY { RtlCopyMemory(NewSid, Sid, SidSize); *CapturedSid = NewSid; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Free the SID and return the exception code */ ExFreePoolWithTag(NewSid, TAG_SID); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; }
HDC APIENTRY NtGdiOpenDCW( PUNICODE_STRING pustrDevice, DEVMODEW *pdmInit, PUNICODE_STRING pustrLogAddr, ULONG iType, BOOL bDisplay, HANDLE hspool, VOID *pDriverInfo2, VOID *pUMdhpdev) { UNICODE_STRING ustrDevice; WCHAR awcDevice[CCHDEVICENAME]; DEVMODEW dmInit; PVOID dhpdev; HDC hdc; /* Only if a devicename is given, we need any data */ if (pustrDevice) { /* Initialize destination string */ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); _SEH2_TRY { /* Probe the UNICODE_STRING and the buffer */ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); /* Copy the string */ RtlCopyUnicodeString(&ustrDevice, pustrDevice); if (pdmInit) { /* FIXME: could be larger */ ProbeForRead(pdmInit, sizeof(DEVMODEW), 1); RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW)); } if (pUMdhpdev) { ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); _SEH2_YIELD(return NULL); } _SEH2_END } else {
NTSTATUS NTAPI SepCaptureAcl(IN PACL InputAcl, IN KPROCESSOR_MODE AccessMode, IN POOL_TYPE PoolType, IN BOOLEAN CaptureIfKernel, OUT PACL *CapturedAcl) { PACL NewAcl; ULONG AclSize = 0; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); if (AccessMode != KernelMode) { _SEH2_TRY { ProbeForRead(InputAcl, sizeof(ACL), sizeof(ULONG)); AclSize = InputAcl->AclSize; ProbeForRead(InputAcl, AclSize, sizeof(ULONG)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Return the exception code */ _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; NewAcl = ExAllocatePoolWithTag(PoolType, AclSize, TAG_ACL); if (NewAcl != NULL) { _SEH2_TRY { RtlCopyMemory(NewAcl, InputAcl, AclSize); *CapturedAcl = NewAcl; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Free the ACL and return the exception code */ ExFreePoolWithTag(NewAcl, TAG_ACL); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; }
BOOL APIENTRY NtGdiEngStretchBlt( IN SURFOBJ *psoDest, IN SURFOBJ *psoSource, IN SURFOBJ *Mask, IN CLIPOBJ *ClipRegion, IN XLATEOBJ *ColorTranslation, IN COLORADJUSTMENT *pca, IN POINTL *BrushOrigin, IN RECTL *prclDest, IN RECTL *prclSrc, IN POINTL *MaskOrigin, IN ULONG Mode) { COLORADJUSTMENT ca; POINTL lBrushOrigin; RECTL rclDest; RECTL rclSrc; POINTL lMaskOrigin; _SEH2_TRY { if (pca) { ProbeForRead(pca, sizeof(COLORADJUSTMENT), 1); RtlCopyMemory(&ca,pca, sizeof(COLORADJUSTMENT)); pca = &ca; } ProbeForRead(BrushOrigin, sizeof(POINTL), 1); RtlCopyMemory(&lBrushOrigin, BrushOrigin, sizeof(POINTL)); ProbeForRead(prclDest, sizeof(RECTL), 1); RtlCopyMemory(&rclDest, prclDest, sizeof(RECTL)); ProbeForRead(prclSrc, sizeof(RECTL), 1); RtlCopyMemory(&rclSrc, prclSrc, sizeof(RECTL)); ProbeForRead(MaskOrigin, sizeof(POINTL), 1); RtlCopyMemory(&lMaskOrigin, MaskOrigin, sizeof(POINTL)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { _SEH2_YIELD(return FALSE); } _SEH2_END; return EngStretchBlt(psoDest, psoSource, Mask, ClipRegion, ColorTranslation, pca, &lBrushOrigin, &rclDest, &rclSrc, &lMaskOrigin, Mode); }
NTSTATUS NTAPI KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN BOOLEAN SearchFrames) { KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); CONTEXT LocalContext; EXCEPTION_RECORD LocalExceptionRecord; ULONG ParameterCount, Size; /* Check if we need to probe */ if (PreviousMode != KernelMode) { /* Set up SEH */ _SEH2_TRY { /* Probe the context */ ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG)); /* Probe the Exception Record */ ProbeForRead(ExceptionRecord, FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) + sizeof(ULONG), sizeof(ULONG)); /* Validate the maximum parameters */ if ((ParameterCount = ExceptionRecord->NumberParameters) > EXCEPTION_MAXIMUM_PARAMETERS) { /* Too large */ _SEH2_YIELD(return STATUS_INVALID_PARAMETER); } /* Probe the entire parameters now*/ Size = (sizeof(EXCEPTION_RECORD) - ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG))); ProbeForRead(ExceptionRecord, Size, sizeof(ULONG)); /* Now make copies in the stack */ RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT)); RtlCopyMemory(&LocalExceptionRecord, ExceptionRecord, Size); Context = &LocalContext; ExceptionRecord = &LocalExceptionRecord; /* Update the parameter count */ ExceptionRecord->NumberParameters = ParameterCount; }
//保护对象 //InputBuffer[0] == Object //InputBuffer[1] == 是否删除 NTSTATUS DispatchProtectObject(PVOID InputBuffer, ULONG InputLength, PVOID OutputBuffer, ULONG OutputLength, PULONG Information) { PVOID object; BOOLEAN remove; NTSTATUS status; *Information = 0; if(InputBuffer == NULL || InputLength != sizeof(ULONG) * 2) { KdPrint(("DispatchProtectObject Param length mismatch\n")); return STATUS_INVALID_PARAMETER; } try { ProbeForRead(InputBuffer, sizeof(ULONG) * 2, 1); object = *(PVOID*)InputBuffer; remove = (BOOLEAN)(*(PULONG)((ULONG)InputBuffer + 4)); status = STATUS_SUCCESS; } except(EXCEPTION_CONTINUE_EXECUTION) { status = STATUS_ACCESS_VIOLATION; } if(!NT_SUCCESS(status)) return status; ProtectAddObject(object, remove); return status; }
//卸载Process进程中的指定模块 //InputBuffer[0] == Process PEPROCESS指针 //InputBuffer[1] == BaseAddress 模块起始地址 NTSTATUS DispatchUnmapProcessModule(PVOID InputBuffer, ULONG InputLength, PVOID OutputBuffer, ULONG OutputLength, PULONG Information) { PEPROCESS process; PVOID baseAddress; NTSTATUS status; BOOLEAN bRet; *Information = 0; if(InputBuffer == NULL || InputLength != sizeof(ULONG) * 2) { KdPrint(("DispatchUnmapProcessModule Param length mismatch\n")); return STATUS_INVALID_PARAMETER; } try { ProbeForRead(InputBuffer, sizeof(ULONG) * 2, 1); process = *(PEPROCESS*)InputBuffer; baseAddress = *(PVOID*)((ULONG)InputBuffer + 4); status = STATUS_SUCCESS; } except(EXCEPTION_CONTINUE_EXECUTION) { status = STATUS_ACCESS_VIOLATION; } if(!NT_SUCCESS(status)) return status; bRet = UnmapProcessModule(process, baseAddress); return STATUS_SUCCESS; }
//初始化APC //InputBuffer[0] == ThreadHandle NTSTATUS DispatchSpecialInitialize(PVOID InputBuffer, ULONG InputLength, PVOID OutputBuffer, ULONG OutputLength, PULONG Information) { HANDLE threadHandle; NTSTATUS status; //验证 if(InputBuffer == NULL || InputLength != sizeof(HANDLE)) return STATUS_INVALID_PARAMETER; *Information = 0; status = STATUS_SUCCESS; try{ ProbeForRead(InputBuffer, 4, 1); threadHandle = *(HANDLE*)(InputBuffer); }except(EXCEPTION_CONTINUE_EXECUTION){ status = STATUS_ACCESS_VIOLATION; } if(!NT_SUCCESS(status)) return status; if(!EnviromentSpecialInitialize(threadHandle, NULL, TRUE)) return STATUS_UNSUCCESSFUL; return STATUS_SUCCESS; }
/* * @implemented */ BOOL APIENTRY NtUserClipCursor( RECTL *prcl) { RECTL rclLocal; BOOL bResult; if (prcl) { _SEH2_TRY { /* Probe and copy rect */ ProbeForRead(prcl, sizeof(RECTL), 1); rclLocal = *prcl; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { EngSetLastError(ERROR_INVALID_PARAMETER); _SEH2_YIELD(return FALSE;) } _SEH2_END prcl = &rclLocal; } UserEnterExclusive(); /* Call the internal function */ bResult = UserClipCursor(prcl); UserLeave(); return bResult; }
HANDLE APIENTRY NtUserSetClipboardData(UINT fmt, HANDLE hData, PSETCLIPBDATA pUnsafeScd) { SETCLIPBDATA scd; HANDLE hRet; TRACE("NtUserSetClipboardData(%x %p %p)\n", fmt, hData, pUnsafeScd); _SEH2_TRY { ProbeForRead(pUnsafeScd, sizeof(*pUnsafeScd), 1); RtlCopyMemory(&scd, pUnsafeScd, sizeof(scd)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); _SEH2_YIELD(return NULL;) } _SEH2_END UserEnterExclusive(); /* Call internal function */ hRet = UserSetClipboardData(fmt, hData, &scd); UserLeave(); return hRet; }
/** * Opens a process. * * \param ProcessHandle A variable which receives the process handle. * \param DesiredAccess The desired access to the process. * \param ClientId The identifier of a process or thread. If \a UniqueThread * is present, the process of the identified thread will be opened. If * \a UniqueProcess is present, the identified process will be opened. * \param AccessMode The mode in which to perform access checks. */ NTSTATUS KpiOpenProcess( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in PCLIENT_ID ClientId, __in KPROCESSOR_MODE AccessMode ) { NTSTATUS status; CLIENT_ID clientId; PEPROCESS process; PETHREAD thread; HANDLE processHandle; PAGED_CODE(); if (AccessMode != KernelMode) { __try { ProbeForWrite(ProcessHandle, sizeof(HANDLE), sizeof(HANDLE)); ProbeForRead(ClientId, sizeof(CLIENT_ID), sizeof(ULONG)); clientId = *ClientId; } __except (EXCEPTION_EXECUTE_HANDLER) { return GetExceptionCode(); } }
HANDLE APIENTRY NtGdiCreateColorSpace( IN PLOGCOLORSPACEEXW pLogColorSpace) { LOGCOLORSPACEEXW Safelcs; NTSTATUS Status = STATUS_SUCCESS; _SEH2_TRY { ProbeForRead( pLogColorSpace, sizeof(LOGCOLORSPACEEXW), 1); RtlCopyMemory(&Safelcs, pLogColorSpace, sizeof(LOGCOLORSPACEEXW)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; if (!NT_SUCCESS(Status)) { SetLastNtError(Status); return NULL; } return IntGdiCreateColorSpace(&Safelcs); }
DWORD APIENTRY NtGdiGetFontData( HDC hDC, DWORD Table, DWORD Offset, LPVOID Buffer, DWORD Size) { PDC Dc; PDC_ATTR pdcattr; HFONT hFont; PTEXTOBJ TextObj; PFONTGDI FontGdi; DWORD Result = GDI_ERROR; NTSTATUS Status = STATUS_SUCCESS; if (Buffer && Size) { _SEH2_TRY { ProbeForRead(Buffer, Size, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END }
/* * @implemented */ NTSTATUS NTAPI NtReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ReplyMessage) { NTSTATUS Status; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); PORT_MESSAGE CapturedReplyMessage; PLPCP_PORT_OBJECT Port; PLPCP_MESSAGE Message; PETHREAD Thread = PsGetCurrentThread(), WakeupThread; PAGED_CODE(); LPCTRACE(LPC_REPLY_DEBUG, "Handle: %p. Message: %p.\n", PortHandle, ReplyMessage); /* Check if the call comes from user mode */ if (PreviousMode != KernelMode) { _SEH2_TRY { ProbeForRead(ReplyMessage, sizeof(*ReplyMessage), sizeof(ULONG)); CapturedReplyMessage = *(volatile PORT_MESSAGE*)ReplyMessage; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; }
/* * @implemented */ NTSTATUS NTAPI NtReplyPort(IN HANDLE PortHandle, IN PPORT_MESSAGE ReplyMessage) { PLPCP_PORT_OBJECT Port; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); NTSTATUS Status; PLPCP_MESSAGE Message; PETHREAD Thread = PsGetCurrentThread(), WakeupThread; //PORT_MESSAGE CapturedReplyMessage; PAGED_CODE(); LPCTRACE(LPC_REPLY_DEBUG, "Handle: %p. Message: %p.\n", PortHandle, ReplyMessage); if (KeGetPreviousMode() == UserMode) { _SEH2_TRY { ProbeForRead(ReplyMessage, sizeof(PORT_MESSAGE), sizeof(ULONG)); /*RtlCopyMemory(&CapturedReplyMessage, ReplyMessage, sizeof(PORT_MESSAGE)); ReplyMessage = &CapturedReplyMessage;*/ } _SEH2_EXCEPT(ExSystemExceptionFilter()) { DPRINT1("SEH crash [1]\n"); DbgBreakPoint(); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; }
PVOID MuLocateCharacteristicCode ( PVOID ImageBase, ULONG ImageSize, PUCHAR VerifyCode, PUCHAR VerifyMask, ULONG CodeLength ) { ULONG i, Found = 0; PUCHAR ImageNow = (PUCHAR)ImageBase; PVOID Offset; g_DebugValue += 1000; __try { if ((ULONG)ImageBase + ImageSize < (ULONG)MmHighestUserAddress) ProbeForRead((PUCHAR)ImageBase, ImageSize, 1); while ((ULONG)ImageNow < (ULONG)ImageBase + ImageSize) { for (i = 0 ; i < CodeLength ; i++) { if (!VerifyMask[i]) { if (*ImageNow++ != VerifyCode[i]) break; } else { ImageNow++; } if ((ULONG)ImageNow >= (ULONG)ImageBase + ImageSize) break; } if (i == CodeLength) { Offset = (PVOID)((ULONG)ImageNow - CodeLength); Found++; break; // BUGBUG } } } __except (1) { } if (Found != 1) { MuWriteDebugLog(g_DebugValue + (Found * 100)); } return Found == 1 ? Offset : NULL; }
/// <summary> /// Trigger the Arbitrary Overwrite Vulnerability /// </summary> /// <param name="UserWriteWhatWhere">The pointer to WRITE_WHAT_WHERE structure</param> /// <returns>NTSTATUS</returns> NTSTATUS TriggerArbitraryOverwrite(IN PWRITE_WHAT_WHERE UserWriteWhatWhere) { PULONG_PTR What = NULL; PULONG_PTR Where = NULL; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); __try { // Verify if the buffer resides in user mode ProbeForRead((PVOID)UserWriteWhatWhere, sizeof(WRITE_WHAT_WHERE), (ULONG)__alignof(WRITE_WHAT_WHERE)); What = UserWriteWhatWhere->What; Where = UserWriteWhatWhere->Where; DbgPrint("[+] UserWriteWhatWhere: 0x%p\n", UserWriteWhatWhere); DbgPrint("[+] WRITE_WHAT_WHERE Size: 0x%X\n", sizeof(WRITE_WHAT_WHERE)); DbgPrint("[+] UserWriteWhatWhere->What: 0x%p\n", What); DbgPrint("[+] UserWriteWhatWhere->Where: 0x%p\n", Where); #ifdef SECURE // Secure Note: This is secure because the developer is properly validating if address // pointed by 'Where' and 'What' value resides in User mode by calling ProbeForRead() // routine before performing the write operation ProbeForRead((PVOID)Where, sizeof(PULONG_PTR), (ULONG)__alignof(PULONG_PTR)); ProbeForRead((PVOID)What, sizeof(PULONG_PTR), (ULONG)__alignof(PULONG_PTR)); *(Where) = *(What); #else DbgPrint("[+] Triggering Arbitrary Overwrite\n"); // Vulnerability Note: This is a vanilla Arbitrary Memory Overwrite vulnerability // because the developer is writing the value pointed by 'What' to memory location // pointed by 'Where' without properly validating if the values pointed by 'Where' // and 'What' resides in User mode *(Where) = *(What); #endif } __except (EXCEPTION_EXECUTE_HANDLER) { Status = GetExceptionCode(); DbgPrint("[-] Exception Code: 0x%X\n", Status); } return Status; }
/* * io_control_set_process_info * * Arguments: * irp * io_stack_irp * input_buffer * setProcessInfo * output_buffer */ NTSTATUS io_control_set_process_info( PIRP irp, PIO_STACK_LOCATION io_stack_irp, unsigned char * input_buffer, unsigned char * output_buffer ) { NTSTATUS function_result = STATUS_SUCCESS; setProcessInfo * processInfo = (setProcessInfo *)input_buffer; UNREFERENCED_PARAMETER(irp); UNREFERENCED_PARAMETER(output_buffer); try { ProbeForRead( input_buffer, io_stack_irp->Parameters.DeviceIoControl.InputBufferLength, sizeof( char ) ); } except (EXCEPTION_EXECUTE_HANDLER) { KdPrint(( "Oregano: io_control_set_process_info: Failed to read buffer\r\n" )); function_result = STATUS_DATA_ERROR; goto IO_CONTROL_SET_PROCESS_ID_INVALID_ARG; } if (0 != targetProcessId) { if (0 == processInfo->processId) { /* Clearing the target process */ KdPrint( ("Oregano: io_control_set_process_info: Clearing process info\r\n") ); stopTracing(); goto IO_CONTROL_SET_PROCESS_ID_DONE; } else if (targetProcessId != (HANDLE)processInfo->processId) { /* Currently I can log only one process at a time */ KdPrint( ("Oregano: io_control_set_process_info: You must stop tracing befor setting a new target process!\r\n") ); function_result = STATUS_INVALID_PARAMETER_1; goto IO_CONTROL_SET_PROCESS_ID_INVALID_ARG; } } targetProcessId = (HANDLE)processInfo->processId; targetThreadId = (HANDLE)processInfo->threadId; targetEProcess = NULL; target_process = NULL; function_result = PsLookupProcessByProcessId( targetProcessId, (PEPROCESS *)(&targetEProcess) ); if (NT_SUCCESS(function_result) && (NULL != targetEProcess)) { target_process = *(void **)(targetEProcess + offsets->eprocess.DirectoryTableBase); } else { KdPrint(("Oregano: io_control_set_process_info: Failed to query target process %p\r\n", targetProcessId)); } IO_CONTROL_SET_PROCESS_ID_INVALID_ARG: IO_CONTROL_SET_PROCESS_ID_DONE: return function_result; }
//枚举进程 //InputBuffer[0] == 是否显示Deleting进程 //OutputBuffer ObjectIdTable缓冲 NTSTATUS DispatchProcessEnum(PVOID InputBuffer, ULONG InputLength, PVOID OutputBuffer, ULONG OutputLength, PULONG Information) { BOOLEAN showDeleting; NTSTATUS status; PObjectIdTable objIdTable; *Information = 0; //首先验证用户参数 if(InputBuffer == NULL || InputLength != sizeof(BOOLEAN) || OutputBuffer == NULL || OutputLength != sizeof(ObjectIdTable)) { KdPrint(("DispatchProcessEnum Param mismatch: InputLength == %lu(should be %lu), OutputLength == %lu(should be %lu)", InputLength, sizeof(BOOLEAN), OutputLength, sizeof(ObjectIdTable))); return STATUS_INVALID_PARAMETER; } status = STATUS_SUCCESS; try{ ProbeForRead(InputBuffer, InputLength, 1); showDeleting = *(BOOLEAN*)InputBuffer; }except(EXCEPTION_CONTINUE_EXECUTION){ KdPrint(("DispatchProcessEnum ACCESS_VIOLATION read.\n")); status = STATUS_ACCESS_VIOLATION; } if(!NT_SUCCESS(status)) return status; //枚举进程信息 objIdTable = ProcessEnum(showDeleting); if(!objIdTable) { status = STATUS_UNSUCCESSFUL; return status; } //拷贝到用户控件 try{ ProbeForWrite(OutputBuffer, OutputLength, 1); RtlCopyMemory(OutputBuffer, objIdTable, OutputLength); status = STATUS_SUCCESS; }except(EXCEPTION_CONTINUE_EXECUTION){ KdPrint(("DispatchProcessEnum ACCESS_VIOLATION write.\n")); status = STATUS_ACCESS_VIOLATION; } ExFreePool(objIdTable); if(NT_SUCCESS(status)) *Information = OutputLength; return status; }
static NTSTATUS WmipCaptureGuidObjectAttributes( _In_ POBJECT_ATTRIBUTES GuidObjectAttributes, _Out_ POBJECT_ATTRIBUTES CapuredObjectAttributes, _Out_ PUNICODE_STRING CapturedObjectName, _Out_ PWSTR ObjectNameBuffer, _In_ KPROCESSOR_MODE AccessMode) { ASSERT(AccessMode != KernelMode); _SEH2_TRY { /* Probe and copy the object attributes structure */ ProbeForRead(GuidObjectAttributes, sizeof(OBJECT_ATTRIBUTES), sizeof(PVOID)); *CapuredObjectAttributes = *GuidObjectAttributes; /* Probe and copy the object name UNICODE_STRING */ ProbeForRead(CapuredObjectAttributes->ObjectName, sizeof(UNICODE_STRING), sizeof(PVOID)); *CapturedObjectName = *CapuredObjectAttributes->ObjectName; /* Check if the object name has the expected length */ if (CapturedObjectName->Length != 45 * sizeof(WCHAR)) { _SEH2_YIELD(return STATUS_INVALID_PARAMETER); } /* Probe and copy the object name buffer */ ProbeForRead(CapturedObjectName->Buffer, CapturedObjectName->Length, sizeof(WCHAR)); RtlCopyMemory(ObjectNameBuffer, CapturedObjectName->Buffer, CapturedObjectName->Length); /* Fix pointers */ CapturedObjectName->Buffer = ObjectNameBuffer; GuidObjectAttributes->ObjectName = CapturedObjectName; }
NTSTATUS CUsbDkRedirectorStrategy::IoInCallerContextRWControlTransfer(CRedirectorRequest &WdfRequest, const USB_DK_TRANSFER_REQUEST &TransferRequest) { NTSTATUS status; PUSBDK_REDIRECTOR_REQUEST_CONTEXT context = WdfRequest.Context(); __try { #pragma warning(push) #pragma warning(disable:4244) //Unsafe conversions on 32 bit ProbeForRead(static_cast<PVOID>(TransferRequest.buffer), sizeof(WDF_USB_CONTROL_SETUP_PACKET), 1); context->SetupPacket = *static_cast<PWDF_USB_CONTROL_SETUP_PACKET>(TransferRequest.buffer); #pragma warning(pop) } __except (EXCEPTION_EXECUTE_HANDLER) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! ProbeForRead failed!"); return STATUS_ACCESS_VIOLATION; } size_t bufferLength = static_cast<size_t>(TransferRequest.bufferLength) - sizeof(WDF_USB_CONTROL_SETUP_PACKET); if (bufferLength > 0) { if (context->SetupPacket.Packet.bm.Request.Dir == BMREQUEST_HOST_TO_DEVICE) // write { #pragma warning(push) #pragma warning(disable:4244) //Unsafe conversions on 32 bit status = WdfRequest.LockUserBufferForRead(static_cast<PVOID>(static_cast<PWDF_USB_CONTROL_SETUP_PACKET>(TransferRequest.buffer) + 1), bufferLength, context->LockedBuffer); #pragma warning(pop) if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! LockUserBufferForRead failed %!STATUS!", status); } } else // read { #pragma warning(push) #pragma warning(disable:4244) //Unsafe conversions on 32 bit status = WdfRequest.LockUserBufferForWrite(static_cast<PVOID>(static_cast<PWDF_USB_CONTROL_SETUP_PACKET>(TransferRequest.buffer) + 1), bufferLength, context->LockedBuffer); #pragma warning(pop) if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, TRACE_REDIRECTOR, "%!FUNC! LockUserBufferForWrite failed %!STATUS!", status); } } } else { context->LockedBuffer = WDF_NO_HANDLE; status = STATUS_SUCCESS; } return status; }
/* * io_control_init_oregano * * Arguments: * irp * io_stack_irp * input_buffer * Some unexported system services indexes in the KeServiceDescriptorTable * output_buffer */ NTSTATUS io_control_init_oregano( PIRP irp, PIO_STACK_LOCATION io_stack_irp, unsigned char * input_buffer, unsigned char * output_buffer ) { NTSTATUS function_result = STATUS_SUCCESS; unsigned int * APIsInfo = (unsigned int *)input_buffer; unsigned int numberOfAPIs = 0; UNREFERENCED_PARAMETER(irp); UNREFERENCED_PARAMETER(output_buffer); try { ProbeForRead( input_buffer, io_stack_irp->Parameters.DeviceIoControl.InputBufferLength, sizeof( char ) ); } except (EXCEPTION_EXECUTE_HANDLER) { KdPrint(( "Oregano: io_control_init_oregano: Failed to read buffer\r\n" )); return STATUS_DATA_ERROR; } function_result = find_SystemServiceTable((ADDRESS *)(&KeServiceDescriptorTable)); if (FALSE == NT_SUCCESS(function_result)) { KdPrint(( "Oregano: io_control_init_oregano: find_SystemServiceTable failed\r\n" )); return function_result; } numberOfAPIs = *APIsInfo; if (numberOfAPIs != (sizeof(systemServices) / sizeof(systemServiceInfo))) { KdPrint(( "Oregano: io_control_init_oregano: Not enough APIs info\r\n" )); return STATUS_DATA_NOT_ACCEPTED; } systemServices.NtSuspendProcess.index = *(APIsInfo + 1); systemServices.NtResumeProcess.index = *(APIsInfo + 2); systemServices.NtSuspendThread.index = *(APIsInfo + 3); systemServices.NtResumeThread.index = *(APIsInfo + 4); KdPrint(( "Oregano: io_control_init_oregano: keServiceDescriptorTable address is %p\r\n", &KeServiceDescriptorTable )); systemServices.NtSuspendProcess.ptr = ((ADDRESS *)KeServiceDescriptorTable->ServiceTable[0].TableBase)[ systemServices.NtSuspendProcess.index]; systemServices.NtResumeProcess.ptr = ((ADDRESS *)KeServiceDescriptorTable->ServiceTable[0].TableBase)[ systemServices.NtResumeProcess.index]; systemServices.NtSuspendThread.ptr = ((ADDRESS *)KeServiceDescriptorTable->ServiceTable[0].TableBase)[ systemServices.NtSuspendThread.index]; systemServices.NtResumeThread.ptr = ((ADDRESS *)KeServiceDescriptorTable->ServiceTable[0].TableBase)[ systemServices.NtResumeThread.index]; KdPrint(( "Oregano: io_control_init_oregano: Set \r\n\tNtSuspendProcess to 0x%p\r\n\tNtResumeProcess to 0x%p\r\n\tNtSuspendThread to 0x%p\r\n\tNtResuemThread to 0x%p\r\n", systemServices.NtSuspendProcess.ptr, systemServices.NtResumeProcess.ptr, systemServices.NtSuspendThread.ptr, systemServices.NtResumeThread.ptr )); return function_result; }
//获取进程的模块信息 //InputBuffer[0] == PEPROCESS指针 //InputBuffer[1] == LdrData指针 //OutputBuffer ModuleInfo缓冲 NTSTATUS DispatchQueryProcessModuleInfo(PVOID InputBuffer, ULONG InputLength, PVOID OutputBuffer, ULONG OutputLength, PULONG Information) { NTSTATUS status; PEPROCESS process; PVOID ldrData; PModuleInfo modInfo; *Information = 0; if(InputBuffer == NULL || InputLength != sizeof(PEPROCESS) + sizeof(PVOID)|| OutputBuffer == NULL || OutputLength != sizeof(ModuleInfo)) { KdPrint(("DispatchQueryProcessModuleInfo Param mismatch: InputLength == %lu(should be %lu), OutputLength == %lu(should be %lu)", InputLength, sizeof(PEPROCESS) + sizeof(PVOID), OutputLength, sizeof(ModuleInfo))); return STATUS_INVALID_PARAMETER; } try{ ProbeForRead(InputBuffer, InputLength, 1); process = *(PEPROCESS*)InputBuffer; ldrData = *(PVOID*)((ULONG)InputBuffer + 4); status = STATUS_SUCCESS; }except(EXCEPTION_CONTINUE_EXECUTION){ status = STATUS_ACCESS_VIOLATION; } if(!NT_SUCCESS(status)) { KdPrint(("DispatchQueryProcessModuleInfo ACCESS_VIOLATION read.\n")); return status; } modInfo = QueryModuleInfo(process, ldrData); if(modInfo == NULL) return STATUS_UNSUCCESSFUL; try{ ProbeForWrite(OutputBuffer, OutputLength, 1); RtlCopyMemory(OutputBuffer, modInfo, OutputLength); status = STATUS_SUCCESS; }except(EXCEPTION_CONTINUE_EXECUTION){ KdPrint(("DispatchQueryProcessModuleInfo ACCESS_VIOLATION write.\n")); status = STATUS_ACCESS_VIOLATION; } if(NT_SUCCESS(status)) *Information = OutputLength; ExFreePool(modInfo); return status; }
BOOL APIENTRY NtGdiSetDeviceGammaRamp(HDC hDC, LPVOID Ramp) { BOOL Ret; PDC dc; NTSTATUS Status = STATUS_SUCCESS; PGAMMARAMP SafeRamp; if (!Ramp) return FALSE; dc = DC_LockDc(hDC); if (!dc) { EngSetLastError(ERROR_INVALID_HANDLE); return FALSE; } SafeRamp = ExAllocatePoolWithTag(PagedPool, sizeof(GAMMARAMP), GDITAG_ICM); if (!SafeRamp) { DC_UnlockDc(dc); EngSetLastError(STATUS_NO_MEMORY); return FALSE; } _SEH2_TRY { ProbeForRead( Ramp, sizeof(PVOID), 1); RtlCopyMemory( SafeRamp, Ramp, sizeof(GAMMARAMP)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; if (!NT_SUCCESS(Status)) { DC_UnlockDc(dc); ExFreePoolWithTag(SafeRamp, GDITAG_ICM); SetLastNtError(Status); return FALSE; } Ret = IntSetDeviceGammaRamp((HDEV)dc->ppdev, SafeRamp, TRUE); DC_UnlockDc(dc); ExFreePoolWithTag(SafeRamp, GDITAG_ICM); return Ret; }
//获取线程信息 //InputBuffer[0] == PETHREAD指针 //OutputBuffer threadInfo缓冲 NTSTATUS DispatchQueryThreadInfo(PVOID InputBuffer, ULONG InputLength, PVOID OutputBuffer, ULONG OutputLength, PULONG Information) { NTSTATUS status; PETHREAD thread; PThreadInfo threadInfo; *Information = 0; if(InputBuffer == NULL || InputLength != sizeof(PETHREAD) || OutputBuffer == NULL || OutputLength != sizeof(ThreadInfo)) { KdPrint(("DispatchQueryThreadInfo Param mismatch: InputLength == %lu(should be %lu), OutputLength == %lu(should be %lu)", InputLength, sizeof(PETHREAD), OutputLength, sizeof(ThreadInfo))); return STATUS_INVALID_PARAMETER; } try{ ProbeForRead(InputBuffer, InputLength, 1); thread = *(PETHREAD*)(InputBuffer); status = STATUS_SUCCESS; }except(EXCEPTION_CONTINUE_EXECUTION){ status = STATUS_ACCESS_VIOLATION; } if(!NT_SUCCESS(status)) { KdPrint(("DispatchQueryThreadInfo ACCESS_VIOLATION read.\n")); return status; } threadInfo = QueryThreadInfo(thread); if(threadInfo == NULL) return STATUS_UNSUCCESSFUL; try{ ProbeForWrite(OutputBuffer, OutputLength, 1); RtlCopyMemory(OutputBuffer, threadInfo, OutputLength); status = STATUS_SUCCESS; }except(EXCEPTION_CONTINUE_EXECUTION){ KdPrint(("DispatchQueryThreadInfo ACCESS_VIOLATION write.\n")); status = STATUS_ACCESS_VIOLATION; } if(NT_SUCCESS(status)) *Information = OutputLength; ExFreePool(threadInfo); return status; }
NTSTATUS NTAPI SeCaptureLuidAndAttributesArray(PLUID_AND_ATTRIBUTES Src, ULONG PrivilegeCount, KPROCESSOR_MODE PreviousMode, PLUID_AND_ATTRIBUTES AllocatedMem, ULONG AllocatedLength, POOL_TYPE PoolType, BOOLEAN CaptureIfKernel, PLUID_AND_ATTRIBUTES *Dest, PULONG Length) { ULONG BufferSize; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); if (PrivilegeCount == 0) { *Dest = 0; *Length = 0; return STATUS_SUCCESS; } if (PreviousMode == KernelMode && !CaptureIfKernel) { *Dest = Src; return STATUS_SUCCESS; } /* FIXME - check PrivilegeCount for a valid number so we don't cause an integer overflow or exhaust system resources! */ BufferSize = PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES); *Length = ROUND_UP(BufferSize, 4); /* round up to a 4 byte alignment */ /* probe the buffer */ if (PreviousMode != KernelMode) { _SEH2_TRY { ProbeForRead(Src, BufferSize, sizeof(ULONG)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Return the exception code */ _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; }