////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Generates a message using "pid", "message" and "parameter" and sends it back to userland throught // a filter communication port. // Parameters : // _in_opt_ ULONG pid : Process ID from which the logs are produced. // _in_opt_ PWCHAR message : Message (function name most of the time). // _in_opt_ PWCHAR parameter : Function args. // Return value : // NTSTATUS : FltSendMessage return value. // Process : // - Retrieves the process name from the pid and saves the whole data into an ANSI string. // - Generates an ANSI string with the message, with the process name, pid, and function name, and the // - generic "parameter" parameter. The resulting output will basically follow this scheme: // "pid","proces_name","function_name","FAILED/SUCCESS(0/1)","return_value","number_of_arguments","argument1->value","argument2->value"... // - Uses the "mutex" mutex to avoid concurrency when using the FltSendMessage() function. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS sendLogs(ULONG pid, PWCHAR message, PWCHAR parameter) { NTSTATUS status = STATUS_SUCCESS; CHAR buf[MAXSIZE]; UNICODE_STRING processName; ULONG sizeBuf; LARGE_INTEGER timeout; timeout.QuadPart = -((LONGLONG)0.5*10*1000*1000); if(message == NULL) return STATUS_INVALID_PARAMETER; #ifdef DEBUG DbgPrint("SendLogs\n"); #endif processName.Length = 0; processName.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR); processName.Buffer = ExAllocatePoolWithTag(NonPagedPool, processName.MaximumLength, PROCNAME_TAG); if(!processName.Buffer) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); return STATUS_NO_MEMORY; } status = getProcNameByPID(pid, &processName); if(!NT_SUCCESS(status)) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } status = RtlStringCbPrintfA(buf, MAXSIZE, "%d,%wZ,%ws,%ws\n", pid, &processName, message, parameter); if(!NT_SUCCESS(status) || status == STATUS_BUFFER_OVERFLOW) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } status = RtlStringCbLengthA(buf, MAXSIZE, &sizeBuf); if(!NT_SUCCESS(status)) { KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, &timeout); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); #ifdef DEBUG DbgPrint("\tmsg : %s\n", buf); #endif status = FltSendMessage(filter, &clientPort, buf, sizeBuf, NULL, 0, NULL); if(status == STATUS_TIMEOUT) DbgPrint("STATUS_TIMEOUT !!\n"); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); #ifdef DEBUG if(!NT_SUCCESS(status)) DbgPrint("return : 0x%08x\n", status); #endif DEBUG return status; }
/* kd> kb ChildEBP RetAddr Args to Child f8afdaa8 805c62ae f8afdcf0 00000000 f8afdb44 DrvHide!LoadImageNotify+0x10 f8afdac8 805a4159 f8afdcf0 00000000 f8afdb44 nt!PsCallImageNotifyRoutines+0x36 f8afdc6c 80576483 f8afdcf0 00000000 00000000 nt!MmLoadSystemImage+0x9e5 f8afdd4c 8057688f 80000378 00000001 00000000 nt!IopLoadDriver+0x371 f8afdd74 80534c02 80000378 00000000 823c63c8 nt!IopLoadUnloadDriver+0x45 f8afddac 805c6160 b286ecf4 00000000 00000000 nt!ExpWorkerThread+0x100 f8afdddc 80541dd2 80534b02 00000001 00000000 nt!PspSystemThreadStartup+0x34 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 */ VOID LoadImageNotify( PUNICODE_STRING FullImageName, HANDLE ProcessId, // where image is mapped PIMAGE_INFO ImageInfo) { KeWaitForMutexObject(&m_GlobalMutex, Executive, KernelMode, FALSE, NULL); // check for kernel driver if (ProcessId == 0 && ImageInfo->SystemModeImage && !m_bFreeAreaFound && IsKnownDriver(FullImageName)) { PVOID TargetImageBase = ImageInfo->ImageBase; ULONG TargetImageSize = ImageInfo->ImageSize; DbgMsg( __FILE__, __LINE__, "%d '%wZ' is at "IFMT", size: %d\n", PsGetCurrentProcessId(), FullImageName, TargetImageBase, TargetImageSize ); // check for free area at the image discardable sections if (m_bFreeAreaFound = CheckForFreeArea(TargetImageBase, &m_FreeAreaRVA, &m_FreeAreaLength)) { m_FreeAreaVA = RVATOVA(TargetImageBase, m_FreeAreaRVA); DbgMsg(__FILE__, __LINE__, "Free area found!\n"); // hook image entry point HookImageEntry(TargetImageBase); } } KeReleaseMutex(&m_GlobalMutex, FALSE); }
void co_os_mutex_acquire(co_os_mutex_t mutex) { NTSTATUS status; status = KeWaitForMutexObject(&mutex->mutex, UserRequest, KernelMode, FALSE, NULL); }
//-------------------------------------------------------------------------------------- void DbgOpenPipe(void) { OBJECT_ATTRIBUTES ObjAttr; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING usPipeName; RtlInitUnicodeString(&usPipeName, L"\\Device\\NamedPipe\\" DBG_PIPE_NAME); InitializeObjectAttributes(&ObjAttr, &usPipeName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); KeWaitForMutexObject(&DbgMutex, Executive, KernelMode, FALSE, NULL); // open data pipe by name NTSTATUS status = ZwCreateFile( &hDbgPipe, FILE_WRITE_DATA | SYNCHRONIZE, &ObjAttr, &IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if (!NT_SUCCESS(status)) { DbgMsg(__FILE__, __LINE__, "ZwCreateFile() fails; status: 0x%.8x\n", status); } KeReleaseMutex(&DbgMutex, FALSE); }
//-------------------------------------------------------------------------------------- void DbgOpenLogFile(void) { OBJECT_ATTRIBUTES ObjAttr; IO_STATUS_BLOCK StatusBlock; UNICODE_STRING usFileName; RtlInitUnicodeString(&usFileName, DBG_LOGFILE_NAME); InitializeObjectAttributes(&ObjAttr, &usFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE , NULL, NULL); KeWaitForMutexObject(&DbgMutex, Executive, KernelMode, FALSE, NULL); NTSTATUS status = ZwCreateFile( &hDbgLogFile, FILE_ALL_ACCESS | SYNCHRONIZE, &ObjAttr, &StatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if (!NT_SUCCESS(status)) { DbgMsg(__FILE__, __LINE__, "ZwCreateFile() fails; status: 0x%.8x\n", status); } KeReleaseMutex(&DbgMutex, FALSE); }
static void AcquireBufferPoolMutex (EncryptedIoQueue *queue) { NTSTATUS status; status = KeWaitForMutexObject (&queue->BufferPoolMutex, Executive, KernelMode, FALSE, NULL); if (!NT_SUCCESS (status)) TC_BUG_CHECK (status); }
int down_read_trylock( struct rw_semaphore *sem) { NTSTATUS nts = KeWaitForMutexObject( ( KMUTEX *)sem->mutex, Executive, KernelMode, FALSE, 0); if ( nts == STATUS_SUCCESS) { sem->reader_count++; KeReleaseMutex( ( KMUTEX *)sem->mutex, FALSE); } return nts != STATUS_SUCCESS; }
PGPUInt32 PGPdiskMutex::Enter(PGPUInt32 timeout, PGPBoolean alertable) { pgpAssertAddrValid(mMutexPointer, KMUTEX); if (timeout == INFINITE) { return KeWaitForMutexObject(mMutexPointer, Executive, KernelMode, alertable, NULL); } else { LARGE_INTEGER largeTimeout; largeTimeout.QuadPart = timeout; return KeWaitForMutexObject(mMutexPointer, Executive, KernelMode, alertable, &largeTimeout); } }
//-------------------------------------------------------------------------------------- void DbgClosePipe(void) { KeWaitForMutexObject(&DbgMutex, Executive, KernelMode, FALSE, NULL); if (hDbgPipe) { ZwClose(hDbgPipe); hDbgPipe = NULL; } KeReleaseMutex(&DbgMutex, FALSE); }
NTSTATUS DrvFilter_LockMutex () { NTSTATUS nStatus ; LARGE_INTEGER liTimeOut ; // verify that this module is initialized ASSERT (g_data.bInitialized) ; liTimeOut.QuadPart = - 5000 * 10000 ; // 5 sec nStatus = KeWaitForMutexObject (&g_data.mutex, Executive, KernelMode, FALSE, &liTimeOut) ; if( nStatus==STATUS_TIMEOUT ) { TRACE_WARNING (TEXT("Waiting for ProcList mutex for more than 5 seconds, will fail in %d secondes.\n"), LOCK_TIMEOUT) ; liTimeOut.QuadPart = - LOCK_TIMEOUT * 1000 * 10000 ; nStatus = KeWaitForMutexObject (&g_data.mutex, Executive, KernelMode, FALSE, &liTimeOut) ; } if( nStatus != STATUS_SUCCESS ) { DrvStatus_Trace() ; TRACE_BREAK (TEXT("KeWaitForMutexObject failed (0x%08X)\n"), nStatus) ; } return nStatus ; }
NTSTATUS ScanCache_Lock () { NTSTATUS nStatus ; LARGE_INTEGER liTimeOut ; ASSERT (g_data.bInitialized) ; liTimeOut.QuadPart = - 5000 * 10000 ; nStatus = KeWaitForMutexObject (&g_data.mutex, Executive, KernelMode, FALSE, &liTimeOut) ; if( nStatus==STATUS_TIMEOUT ) { TRACE_WARNING (TEXT("Waiting for ScanCache mutex for more than 5 seconds, will fail in %d secondes.\n"), LOCK_TIMEOUT) ; liTimeOut.QuadPart = - LOCK_TIMEOUT * 1000 * 10000 ; nStatus = KeWaitForMutexObject (&g_data.mutex, Executive, KernelMode, FALSE, &liTimeOut) ; } if( nStatus!=STATUS_SUCCESS ) { DrvStatus_Trace() ; TRACE_BREAK (TEXT("KeWaitForMutexObject failed (status=0x%08X)\n"), nStatus) ; } return nStatus ; }
/* * This helper runs a program from the driver service. * Connection is estabilished with named pipe. */ void run_process(DWORD i, WCHAR *pwcProg) { DbgPrint("Runing %ls...\r\n", pwcProg); while (!NT_SUCCESS(KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL))); LARGE_INTEGER delay = RtlConvertUlongToLargeInteger(300000l); NTSTATUS status; HANDLE pipe; OBJECT_ATTRIBUTES fattrs; UNICODE_STRING pipe_name; IO_STATUS_BLOCK io_stat_block; RtlInitUnicodeString(&pipe_name, L"\\??\\pipe\\drvtest"); InitializeObjectAttributes(&fattrs, &pipe_name, OBJ_CASE_INSENSITIVE | 0x0200/*OBJ_KERNEL_HANDLE*/, 0, NULL); status = ZwCreateFile(&pipe, FILE_WRITE_DATA | FILE_READ_DATA | SYNCHRONIZE, &fattrs, &io_stat_block, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x, 0x%0.8x\r\n", status, io_stat_block.Status); example_ioctl_data out_data = { code: MCODE_SPAWN }; wcscpy(out_data.rprog, pwcProg); status = ZwWriteFile(pipe, NULL, NULL, NULL, &io_stat_block, &out_data, sizeof(out_data), NULL, NULL); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x\r\n", status); DWORD pid; do { status = ZwReadFile(pipe, NULL, NULL, NULL, &io_stat_block, &pid, sizeof(DWORD), NULL, NULL); if (!NT_SUCCESS(status)) KeDelayExecutionThread(KernelMode, FALSE, &delay); } while(STATUS_PENDING == status); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x\r\n", status); DbgPrint("PID: %d\r\n", pid); g_proc_table[i].sl_pid = pid; ZwClose(pipe); KeReleaseMutex(&mutex, FALSE); return; /* return proc_infn.dwProcessId; */ }
BOOLEAN KMutexAquire(KMUTEX * mutex) { NTSTATUS s = STATUS_SUCCESS; s = KeWaitForMutexObject( mutex, Executive, KernelMode, FALSE, NULL); if (NT_SUCCESS(s)) return TRUE; return FALSE; }
NTSTATUS STDCALL my_ioctl(PDEVICE_OBJECT deviceObject, PIRP Irp) { NTSTATUS status = STATUS_SUCCESS; BOOLEAN mutexHeld = FALSE; DbgPrint("my_ioctl called\n"); DbgPrint("Attached device: 0x%08X\n", deviceObject->AttachedDevice); device_context_t* context = (device_context_t*) deviceObject->DeviceExtension; status = KeWaitForMutexObject(&(context->mutex), Executive, KernelMode, FALSE, NULL); if(status != STATUS_SUCCESS) { DbgPrint("Mutex problem\n"); goto cleanup; } mutexHeld = TRUE; PIO_STACK_LOCATION pIoStackIrp = IoGetCurrentIrpStackLocation(Irp); if(!pIoStackIrp) { DbgPrint("No I/O stack location\n"); status = STATUS_UNSUCCESSFUL; goto cleanup; } DbgPrint("IOCTL = 0x%08X\n", pIoStackIrp->Parameters.DeviceIoControl.IoControlCode); switch (pIoStackIrp->Parameters.DeviceIoControl.IoControlCode) { case MY_IOCTL_PUSH: status = my_ioctl_push(context, Irp); break; case MY_IOCTL_POP: status = my_ioctl_pop(context, Irp); break; default: status = STATUS_NOT_SUPPORTED; break; } cleanup: if (mutexHeld) { KeReleaseMutex(&(context->mutex), FALSE); } IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
void terminate_process(DWORD dwProcessId) { if (!dwProcessId) return; DbgPrint("Killing %d...\r\n", dwProcessId); while (!NT_SUCCESS(KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL))); LARGE_INTEGER delay = RtlConvertUlongToLargeInteger(300000l); NTSTATUS status; HANDLE pipe; OBJECT_ATTRIBUTES fattrs; UNICODE_STRING pipe_name; IO_STATUS_BLOCK io_stat_block; RtlInitUnicodeString(&pipe_name, L"\\??\\pipe\\drvtest"); InitializeObjectAttributes(&fattrs, &pipe_name, OBJ_CASE_INSENSITIVE | 0x0200/*OBJ_KERNEL_HANDLE*/, 0, NULL); for (int i = 0; i < 10; ++i) { status = ZwCreateFile(&pipe, FILE_WRITE_DATA | SYNCHRONIZE, &fattrs, &io_stat_block, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0); if (!NT_SUCCESS(status)) KeDelayExecutionThread(KernelMode, FALSE, &delay); else break; } if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x, 0x%0.8x\r\n", status, io_stat_block.Status); example_ioctl_data out_data = { code: MCODE_TERM, pid: dwProcessId }; status = ZwWriteFile(pipe, NULL, NULL, NULL, &io_stat_block, &out_data, sizeof(out_data), NULL, NULL); if (!NT_SUCCESS(status)) DbgPrint("Alert! 0x%0.8x\r\n", status); ZwClose(pipe); KeReleaseMutex(&mutex, FALSE); return; }
NTSTATUS WatchObjs_Lock () { NTSTATUS nStatus ; LARGE_INTEGER liTimeOut ; // verify that this module is initialized ASSERT (g_data.bInitialized) ; liTimeOut.QuadPart = - 10000 * 10000 ; nStatus = KeWaitForMutexObject (&g_data.mutex, Executive, KernelMode, FALSE, &liTimeOut) ; if( nStatus != STATUS_SUCCESS ) TRACE_ERROR (TEXT("KeWaitForMutexObject failed (0x%08X)\n"), nStatus) ; return nStatus ; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Generates a message using "pid", "message" and "parameter" and sends it back to userland throught // a filter communication port. // Parameters : // _in_opt_ ULONG pid : Process ID from which the logs are produced. // _in_opt_ PWCHAR message : Message (function name most of the time). // _in_opt_ PWCHAR parameter : Function args. // Return value : // NTSTATUS : FltSendMessage return value. // Process : // - Retrieves the process name from the pid and saves the whole data into an ANSI string. // - Generates an ANSI string with the message, with the process name, pid, and function name, and the // - generic "parameter" parameter. The resulting output will basically follow this scheme: // "pid","process_name","function_name","FAILED/SUCCESS/BLOCKED(0/1/2)","return_value","number_of_arguments","argument1->value","argument2->value"... // - Uses the "mutex" mutex to avoid concurrency when using the FltSendMessage() function. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// NTSTATUS sendLogs(ULONG pid, PWCHAR message, PWCHAR parameter) { NTSTATUS status = STATUS_SUCCESS; CHAR buf[MAXSIZE]; UNICODE_STRING processName; ULONG sizeBuf; if(message == NULL) return STATUS_INVALID_PARAMETER; processName.Length = 0; processName.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR); processName.Buffer = ExAllocatePoolWithTag(NonPagedPool, processName.MaximumLength, PROCNAME_TAG); if(!processName.Buffer) { DbgPrint("ProcessName.Buffer error\n"); KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, NULL); KeReleaseMutex(&mutex, FALSE); return STATUS_NO_MEMORY; } status = getProcNameByPID(pid, &processName); if(!NT_SUCCESS(status)) { DbgPrint("getProcNameByPID() error\n"); KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, NULL); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } status = RtlStringCbPrintfA(buf, MAXSIZE, "%d,%wZ,%ws,%ws\n", pid, &processName, message, parameter); if(!NT_SUCCESS(status) || status == STATUS_BUFFER_OVERFLOW) { DbgPrint("RtlStringCbPrintfA() error\n"); KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, NULL); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } status = RtlStringCbLengthA(buf, MAXSIZE, &sizeBuf); if(!NT_SUCCESS(status)) { DbgPrint("RtlStringCbLengthA() error\n"); KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, "0,error,error,error\n", 20, NULL, 0, NULL); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; } KeWaitForMutexObject(&mutex, Executive, KernelMode, FALSE, NULL); status = FltSendMessage(filter, &clientPort, buf, sizeBuf, NULL, 0, NULL); KeReleaseMutex(&mutex, FALSE); ExFreePool(processName.Buffer); return status; }
//-------------------------------------------------------------------------------------- void DbgMsg(char *lpszFile, int Line, char *lpszMsg, ...) { va_list mylist; char *lpszBuff = (char *)M_ALLOC(DBGMSG_BUFF_SIZE); if (lpszBuff == NULL) { return; } char *lpszOutBuff = (char *)M_ALLOC(DBGMSG_BUFF_SIZE); if (lpszOutBuff == NULL) { M_FREE(lpszBuff); return; } va_start(mylist, lpszMsg); vsprintf(lpszBuff, lpszMsg, mylist); va_end(mylist); sprintf(lpszOutBuff, "%s(%d) : %s", GetNameFromFullPath(lpszFile), Line, lpszBuff); #ifdef DBGMSG DbgPrint(lpszOutBuff); #endif #if defined(DBGPIPE) || defined(DBGLOGFILE) if (KeGetCurrentIrql() == PASSIVE_LEVEL) { KeWaitForMutexObject(&DbgMutex, Executive, KernelMode, FALSE, NULL); if (hDbgPipe) { // write debug message into pipe IO_STATUS_BLOCK IoStatusBlock; ULONG Len = (ULONG)strlen(lpszOutBuff) + 1; ZwWriteFile(hDbgPipe, 0, NULL, NULL, &IoStatusBlock, (PVOID)&Len, sizeof(Len), NULL, NULL); ZwWriteFile(hDbgPipe, 0, NULL, NULL, &IoStatusBlock, lpszOutBuff, Len, NULL, NULL); } if (hDbgLogFile) { // write debug message into logfile IO_STATUS_BLOCK IoStatusBlock; ULONG Len = (ULONG)strlen(lpszOutBuff); ZwWriteFile(hDbgLogFile, 0, NULL, NULL, &IoStatusBlock, lpszOutBuff, Len, NULL, NULL); } KeReleaseMutex(&DbgMutex, FALSE); } #endif // DBGPIPE/DBGLOGFILE M_FREE(lpszBuff); M_FREE(lpszOutBuff); }
int down_write_trylock( struct rw_semaphore *sem) { NTSTATUS nts = KeWaitForMutexObject( ( KMUTEX *)sem->mutex, Executive, KernelMode, FALSE, 0); return nts != STATUS_SUCCESS; }
void down_write( struct rw_semaphore *sem) { KeWaitForMutexObject( ( KMUTEX *)sem->mutex, Executive, KernelMode, FALSE, NULL); }
void up_read( struct rw_semaphore *sem) { KeWaitForMutexObject( ( KMUTEX *)sem->mutex, Executive, KernelMode, FALSE, NULL); sem->reader_count--; KeReleaseMutex( ( KMUTEX *)sem->mutex, FALSE); }