Example #1
1
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	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;
}
PSYMBOL_ENTRY SympFindSymbol(IN PCHAR pszSymbolName)
{
	ASSERTMSG("Passed symbol name is NULL", pszSymbolName != NULL);
	ASSERTMSG("SymbolEngine must be initialized prior to this call", bIsSymEngineInitialized == TRUE);
	PLIST_ENTRY symbolListEntry = SymbolsListHead.Flink;

	// we are not at dispatch level yet, so getting length of the input string is allowed
	size_t nSymbolNameLength = 0;
	if(RtlStringCbLengthA(pszSymbolName, MAX_SYM_NAME, &nSymbolNameLength) == STATUS_INVALID_PARAMETER)
	{
		KdPrint(("[DEBUG] ERROR - Could not obtain the length of the symbol name\n"));
		return NULL;
	}

	// iterate through symbols list
	ASSERTMSG("Fast mutex acquire must occur at or below APC_LEVEL", KeGetCurrentIrql() <= APC_LEVEL);
	ExAcquireFastMutex(&SymbolsListMutex);
	while(symbolListEntry != &SymbolsListHead)
	{
		PSYMBOL_ENTRY pSymbolEntry = CONTAINING_RECORD(symbolListEntry, SYMBOL_ENTRY, ListEntry);
		// if this is the wanted entry
		if(RtlCompareMemory((PVOID) pszSymbolName, (PVOID)pSymbolEntry->Symbol.name, nSymbolNameLength) == nSymbolNameLength)
		{
			// return it to caller
			ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL);
			ExReleaseFastMutex(&SymbolsListMutex);
			return pSymbolEntry;
		}

		symbolListEntry = symbolListEntry->Flink;
	}

	// wanted symbol entry is not present in the list, return NULL
	ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL);
	ExReleaseFastMutex(&SymbolsListMutex);
	return NULL;
}
Example #3
0
NTSTATUS dumpEatEntriesToDefFile(PVOID pEatEntryList, ULONGLONG listBufferSize, PUCHAR pModuleName){
	OBJECT_ATTRIBUTES defFileAttr;
	UNICODE_STRING uDefFileName;
	IO_STATUS_BLOCK ioSb;

	NTSTATUS status, fatalStatus = STATUS_CLUSTER_NETINTERFACE_EXISTS;
	
	PCHAR pDefPreamble = NULL;
	///Keep it simple. We can't allocate less than 4 kB using NtXxx funcs anyway,
	///so just allocate 4 kB although we never will need that much.
	ULONGLONG defPreambleSize = PAGE_SIZE;
	HANDLE hDefFile = NULL;
	HANDLE hParentDir = NULL;
	///Quite some ugly hacking...
	char szDefPreamblePart[] = { 0x0D, 0x0A, 0x0D, 0x0A, 'E', 'X', 'P', 'O', 'R', 'T', 'S', 0x0D, 0x0A, 0x0 };

	status = NtAllocateVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, 0, &defPreambleSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
	if (status)
		return status;

	status = RtlStringCbPrintfA(pDefPreamble, defPreambleSize, "LIBRARY %s%s", pModuleName, szDefPreamblePart);
	if (status){
		fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
		if (fatalStatus)
			mydie(status, fatalStatus);

		return status;
	}

	status = RtlStringCbLengthA(pDefPreamble, defPreambleSize, &defPreambleSize);
	if (status){
		fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
		if (fatalStatus)
			mydie(status, fatalStatus);

		return status;
	}

	hParentDir = NtCurrentPeb()->ProcessParameters->CurrentDirectory.Handle;
	RtlInitUnicodeString(&uDefFileName, L"exports.def");
	InitializeObjectAttributes(&defFileAttr, &uDefFileName, OBJ_CASE_INSENSITIVE, hParentDir, NULL);
	status = NtCreateFile(&hDefFile, FILE_ALL_ACCESS | SYNCHRONIZE, &defFileAttr, &ioSb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
	if (status){
		fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
		if (fatalStatus)
			mydie(status, fatalStatus);

		return status;
	}

	status = NtWriteFile(hDefFile, NULL, NULL, NULL, &ioSb, pDefPreamble, (ULONG)defPreambleSize, NULL, NULL);
	if (!status)
		status = NtWriteFile(hDefFile, NULL, NULL, NULL, &ioSb, pEatEntryList, (ULONG)listBufferSize, NULL, NULL);

	fatalStatus = NtClose(hDefFile);
	if (fatalStatus)
		mydie(status, fatalStatus);

	fatalStatus = NtFreeVirtualMemory(INVALID_HANDLE_VALUE, &pDefPreamble, &defPreambleSize, MEM_RELEASE);
	if (fatalStatus)
		mydie(status, fatalStatus);

	return status;
}
Example #4
0
NTSTATUS
AFSDbgLogMsg( IN ULONG Subsystem,
              IN ULONG Level,
              IN PCCH Format,
              ...)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    va_list va_args;
    ULONG ulBytesWritten = 0;
    BOOLEAN bReleaseLock = FALSE;
    char    *pCurrentTrace = NULL;

    __Enter
    {

        if( AFSDbgBuffer == NULL)
        {

            try_return( ntStatus = STATUS_DEVICE_NOT_READY);
        }

        if( Subsystem > 0 &&
            (Subsystem & AFSTraceComponent) == 0)
        {

            //
            // Not tracing this subsystem
            //

            try_return( ntStatus);
        }

        if( Level > 0 &&
            Level > AFSTraceLevel)
        {

            //
            // Not tracing this level
            //

            try_return( ntStatus);
        }

        AFSAcquireExcl( &AFSDbgLogLock,
                        TRUE);

        bReleaseLock = TRUE;

        //
        // Check again under lock
        //

        if( AFSDbgBuffer == NULL)
        {

            try_return( ntStatus = STATUS_DEVICE_NOT_READY);
        }

        if( AFSDbgLogRemainingLength < 255)
        {

            AFSDbgLogRemainingLength = AFSDbgBufferLength;

            AFSDbgCurrentBuffer = AFSDbgBuffer;

            SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);
        }

        pCurrentTrace = AFSDbgCurrentBuffer;

        RtlStringCchPrintfA( AFSDbgCurrentBuffer,
                             10,
                             "%08lX:",
                             AFSDbgLogCounter++);

        AFSDbgCurrentBuffer += 9;

        AFSDbgLogRemainingLength -= 9;

        va_start( va_args, Format);

        ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer,
                                        AFSDbgLogRemainingLength,
                                        Format,
                                        va_args);

        if( ntStatus == STATUS_BUFFER_OVERFLOW)
        {

            RtlZeroMemory( AFSDbgCurrentBuffer,
                           AFSDbgLogRemainingLength);

            AFSDbgLogRemainingLength = AFSDbgBufferLength;

            AFSDbgCurrentBuffer = AFSDbgBuffer;

            SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED);

            pCurrentTrace = AFSDbgCurrentBuffer;

            RtlStringCchPrintfA( AFSDbgCurrentBuffer,
                                 10,
                                 "%08lX:",
                                 AFSDbgLogCounter++);

            AFSDbgCurrentBuffer += 9;

            AFSDbgLogRemainingLength -= 9;

            ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer,
                                            AFSDbgLogRemainingLength,
                                            Format,
                                            va_args);
        }

        if( NT_SUCCESS( ntStatus))
        {

            RtlStringCbLengthA( AFSDbgCurrentBuffer,
                                AFSDbgLogRemainingLength,
                                (size_t *)&ulBytesWritten);

            AFSDbgCurrentBuffer += ulBytesWritten;

            AFSDbgLogRemainingLength -= ulBytesWritten;
        }

        va_end( va_args);

        if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_TRACE_TO_DEBUGGER) &&
            pCurrentTrace != NULL)
        {

            DbgPrint( pCurrentTrace);
        }

try_exit:

        if( bReleaseLock)
        {

            AFSReleaseResource( &AFSDbgLogLock);
        }
    }

    return ntStatus;
}
Example #5
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	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;
}
Example #6
0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Description :
//		Parses received PIDs IOCTL from analyzer.py and adds ths PIDs in the hidden and monitored
//		lists.
//	Parameters :
//		IRP buffer data.
//	Return value :
//		NTSTATUS : STATUS_SUCCESS on success.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS parse_pids(PCHAR pids)
{
	PCHAR start = NULL, current = NULL, data = NULL;
	ULONG len, pid;
	BOOLEAN first_pid = TRUE;
	NTSTATUS status;
	
	if(pids == NULL)
		return STATUS_INVALID_PARAMETER;
	
	status = RtlStringCbLengthA(pids, MAXSIZE, &len);
	if(!NT_SUCCESS(status))
		return status;
	
	data = ExAllocatePoolWithTag(NonPagedPool, len+1, TEMP_TAG);
	if(data == NULL)
		return STATUS_NO_MEMORY;
	
	status = RtlStringCbPrintfA(data, len+1, "%s", pids);
	if(!NT_SUCCESS(status))
	{
		ExFreePool(data);
		return status;
	}
	
	start = data;
	current = data;
	
	while(*current != 0x00)
	{
		if(*current == '_' && current!=start)
		{
			*current = 0x00;
			status = RtlCharToInteger(start, 10, &pid);
			if(NT_SUCCESS(status) && pid!=0)
			{
				if(first_pid)
				{
					startMonitoringProcess(pid);
					first_pid=FALSE;
				}
				else
					addHiddenProcess(pid);
			}
			start = current+1;
		}
		current++;
	}
	
	if(start != current)
	{
		status = RtlCharToInteger(start, 10, &pid);
		if(NT_SUCCESS(status) && pid!=0)
		{
			if(first_pid)
				startMonitoringProcess(pid);
			else
				addHiddenProcess(pid);
		}	
	}	
	ExFreePool(data);
	
	return STATUS_SUCCESS;
}
Example #7
0
VOID
	MyThreadStart(__in PVOID  StartContext){
		HANDLE   handle;//Create File handle
		NTSTATUS ntstatus;
		NTSTATUS timerStatus;
		//IO_STATUS_BLOCK    ioStatusBlock;
		//OBJECT_ATTRIBUTES ObjAttr;
		//UNICODE_STRING path;
		LARGE_INTEGER timeout;
//#define  BUFFER_SIZE 30
	//	CHAR     buffer[BUFFER_SIZE];
		//size_t  cb;

		NTSTATUS Status;
		HANDLE hEvent;
		//OBJECT_ATTRIBUTES oa;
		//UNICODE_STRING us;
		int counter=20;
		SIZE_T BytesNUM;
		char* dataPtr;

		__debugbreak();
		dataPtr="123";
		BytesNUM=strlen(dataPtr)*sizeof(char);
		WriteToRingBuffer(&dataPtr, BytesNUM);
		FlushRingBuffre();
		RtlInitUnicodeString(
			&path,
			L"\\DosDevices\\C:\\MyLogger.txt");
		InitializeObjectAttributes(
			&ObjAttr,
			&path,  			//ObjectName
			OBJ_CASE_INSENSITIVE, 	//Attributes
			NULL,			//RootDirectory
			NULL);			//SecurityDescriptor
		// Do not try to perform any file operations at higher IRQL levels.
		// Instead, you may use a work item or a system worker thread to perform file operations.

		if(KeGetCurrentIrql() != PASSIVE_LEVEL)
			//  return STATUS_INVALID_DEVICE_STATE; 
			DbgPrint("STATUS_INVALID_DEVICE_STATE\n");

		ntstatus = ZwCreateFile(&handle,
			GENERIC_WRITE,
			&ObjAttr, &ioStatusBlock, NULL,
			FILE_ATTRIBUTE_NORMAL,
			0,
			FILE_OVERWRITE_IF, 
			FILE_SYNCHRONOUS_IO_NONALERT,
			NULL, 0);


		timeout.QuadPart = -5 * 1000000;

		RtlInitUnicodeString(
			&us,
			L"\\BaseNamedObjects\\TestEvent");

		InitializeObjectAttributes(
			&oa,
			&us,  			//ObjectName
			OBJ_CASE_INSENSITIVE, 	//Attributes
			NULL,			//RootDirectory
			NULL);			//SecurityDescriptor

		Status = ZwCreateEvent(&hEvent,
			EVENT_ALL_ACCESS,
			&oa,
			NotificationEvent,
			FALSE);

		if(NT_SUCCESS(Status)){
			DbgPrint("Event created");
		} else {
			DbgPrint("Event Not created");
		}

		Status = ObReferenceObjectByHandle(
			hEvent, 		//Handle
			EVENT_ALL_ACCESS,	//DesiredAccess
			NULL,			//ObjectType
			KernelMode,		//AccessMode
			&pEvent,		//Object
			NULL);			//HandleInformation

		if (!NT_SUCCESS(Status)) {
			ZwClose(hEvent);
			DbgPrint("Failed to reference event \n");
			//return Status;
		};

		while(counter!=0){



			timerStatus = KeWaitForSingleObject(
				pEvent,
				Executive,
				KernelMode,
				FALSE,
				&timeout
				);




			if(timerStatus == STATUS_TIMEOUT){
				if(NT_SUCCESS(ntstatus)) {
					ntstatus = RtlStringCbPrintfA(buffer, sizeof(buffer), "This is %d test\r\n", counter);
					if(NT_SUCCESS(ntstatus)) {
						ntstatus = RtlStringCbLengthA(buffer, sizeof(buffer), &cb);
						if(NT_SUCCESS(ntstatus)) {
							ntstatus = ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock,
								buffer, cb, NULL, NULL);
						}
					}
					//ZwClose(handle);
				}
			}
			counter--;
		}
		ZwClose(handle);
}