示例#1
0
文件: gdipool.c 项目: RPG-7/reactos
static
VOID
GdiPoolDeleteSection(PGDI_POOL pPool, PGDI_POOL_SECTION pSection)
{
    NTSTATUS status;
    SIZE_T cjSize = 0;

    /* Should not have any allocations */
    if (pSection->cAllocCount != 0)
    {
        DPRINT1("There are %lu allocations left, section=%p, pool=%p\n",
                pSection->cAllocCount, pSection, pPool);
        DBG_DUMP_EVENT_LIST(&pPool->slhLog);
        ASSERT(FALSE);
    }

    /* Release the virtual memory */
    status = ZwFreeVirtualMemory(NtCurrentProcess(),
                                 &pSection->pvBaseAddress,
                                 &cjSize,
                                 MEM_RELEASE);
    ASSERT(NT_SUCCESS(status));

    /* Free the section object */
    EngFreeMem(pSection);
}
示例#2
0
NTSTATUS
RtlpFreeStack(
    IN HANDLE Process,
    IN PINITIAL_TEB InitialTeb
    )
{
    NTSTATUS Status;
    SIZE_T Zero;

    Zero = 0;
    Status = ZwFreeVirtualMemory( Process,
                                  &InitialTeb->StackAllocationBase,
                                  &Zero,
                                  MEM_RELEASE
                                );
    if ( !NT_SUCCESS( Status ) ) {
#if DBG
        DbgPrint( "NTRTL: RtlpFreeStack( %lx ) failed.  Stack DeCommit Status == %X\n",
                  Process,
                  Status
                );
#endif // DBG
        return( Status );
        }

    RtlZeroMemory( InitialTeb, sizeof( *InitialTeb ) );
    return( STATUS_SUCCESS );
}
示例#3
0
文件: heapdbg.c 项目: GYGit/reactos
BOOLEAN NTAPI
RtlDebugDestroyHeap(HANDLE HeapPtr)
{
    SIZE_T Size = 0;
    PHEAP Heap = (PHEAP)HeapPtr;

    if (Heap == RtlGetCurrentPeb()->ProcessHeap)
    {
        DPRINT1("HEAP: It's forbidden delete process heap!");
        return FALSE;
    }

    if (Heap->Signature != HEAP_SIGNATURE)
    {
        DPRINT1("HEAP: Invalid heap %p signature 0x%x\n", Heap, Heap->Signature);
        return FALSE;
    }

    if (!RtlpValidateHeap(Heap, FALSE)) return FALSE;

    /* Make heap invalid by zeroing its signature */
    Heap->Signature = 0;

    /* Free validate headers copy if it was existing */
    if (Heap->HeaderValidateCopy)
    {
        ZwFreeVirtualMemory(NtCurrentProcess(),
                            &Heap->HeaderValidateCopy,
                            &Size,
                            MEM_RELEASE);
    }

    return TRUE;
}
示例#4
0
文件: lsa.c 项目: hoangduit/reactos
/*
 * @implemented
 */
NTSTATUS
NTAPI
LsaFreeReturnBuffer(PVOID Buffer)
{
    SIZE_T Size = 0;
    return ZwFreeVirtualMemory(NtCurrentProcess(),
                               &Buffer,
                               &Size,
                               MEM_RELEASE);
}
示例#5
0
/// <summary>
/// Allocate/Free process memory
/// </summary>
/// <param name="pAllocFree">Request params.</param>
/// <param name="pResult">Allocated region info.</param>
/// <returns>Status code</returns>
NTSTATUS BBAllocateFreeMemory( IN PALLOCATE_FREE_MEMORY pAllocFree, OUT PALLOCATE_FREE_MEMORY_RESULT pResult )
{
    NTSTATUS status = STATUS_SUCCESS;
    PEPROCESS pProcess = NULL;

    ASSERT( pResult != NULL );
    if (pResult == NULL)
        return STATUS_INVALID_PARAMETER;

    status = PsLookupProcessByProcessId( (HANDLE)pAllocFree->pid, &pProcess );
    if (NT_SUCCESS( status ))
    {
        KAPC_STATE apc;
        PVOID base = (PVOID)pAllocFree->base;
        ULONG_PTR size = pAllocFree->size;

        KeStackAttachProcess( pProcess, &apc );

        if (pAllocFree->allocate)
        {
            if (pAllocFree->physical != FALSE)
            {
                status = BBAllocateFreePhysical( pProcess, pAllocFree, pResult );
            }
            else
            {
                status = ZwAllocateVirtualMemory( ZwCurrentProcess(), &base, 0, &size, pAllocFree->type, pAllocFree->protection );
                pResult->address = (ULONGLONG)base;
                pResult->size = size;
            }
        }
        else
        {
            MI_VAD_TYPE vadType = VadNone;
            BBGetVadType( pProcess, pAllocFree->base, &vadType );

            if (vadType == VadDevicePhysicalMemory)
                status = BBAllocateFreePhysical( pProcess, pAllocFree, pResult );
            else
                status = ZwFreeVirtualMemory( ZwCurrentProcess(), &base, &size, pAllocFree->type );
        }

        KeUnstackDetachProcess( &apc );        
    }
    else
        DPRINT( "BlackBone: %s: PsLookupProcessByProcessId failed with status 0x%X\n", __FUNCTION__, status );

    if (pProcess)
        ObDereferenceObject( pProcess );

    return status;
}
示例#6
0
文件: int10.c 项目: GYGit/reactos
VP_STATUS NTAPI
IntInt10AllocateBuffer(
   IN PVOID Context,
   OUT PUSHORT Seg,
   OUT PUSHORT Off,
   IN OUT PULONG Length)
{
   PVOID MemoryAddress;
   NTSTATUS Status;
   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
   KAPC_STATE ApcState;

   TRACE_(VIDEOPRT, "IntInt10AllocateBuffer\n");

   IntAttachToCSRSS(&CallingProcess, &ApcState);

   MemoryAddress = (PVOID)0x20000;
   Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &MemoryAddress, 0,
      Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

   if (!NT_SUCCESS(Status))
   {
      WARN_(VIDEOPRT, "- ZwAllocateVirtualMemory failed\n");
      IntDetachFromCSRSS(&CallingProcess, &ApcState);
      return ERROR_NOT_ENOUGH_MEMORY;
   }

   if (MemoryAddress > (PVOID)(0x100000 - *Length))
   {
      ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, Length,
         MEM_RELEASE);
      WARN_(VIDEOPRT, "- Unacceptable memory allocated\n");
      IntDetachFromCSRSS(&CallingProcess, &ApcState);
      return ERROR_NOT_ENOUGH_MEMORY;
   }

   *Seg = (USHORT)((ULONG)MemoryAddress >> 4);
   *Off = (USHORT)((ULONG)MemoryAddress & 0xF);

   INFO_(VIDEOPRT, "- Segment: %x\n", (ULONG)MemoryAddress >> 4);
   INFO_(VIDEOPRT, "- Offset: %x\n", (ULONG)MemoryAddress & 0xF);
   INFO_(VIDEOPRT, "- Length: %x\n", *Length);

   IntDetachFromCSRSS(&CallingProcess, &ApcState);

   return NO_ERROR;
}
示例#7
0
NTSTATUS
NTAPI
RtlpFreeUserStack(IN HANDLE Process,
                  IN PINITIAL_TEB InitialTeb)
{
    SIZE_T Dummy = 0;
    NTSTATUS Status;

    /* Free the Stack */
    Status = ZwFreeVirtualMemory(Process,
                                 &InitialTeb->AllocatedStackBase,
                                 &Dummy,
                                 MEM_RELEASE);

    /* Clear the initial TEB */
    RtlZeroMemory(InitialTeb, sizeof(INITIAL_TEB));
    return Status;
}
示例#8
0
文件: int10.c 项目: GYGit/reactos
VP_STATUS NTAPI
IntInt10FreeBuffer(
   IN PVOID Context,
   IN USHORT Seg,
   IN USHORT Off)
{
   PVOID MemoryAddress = (PVOID)((Seg << 4) | Off);
   NTSTATUS Status;
   PKPROCESS CallingProcess = (PKPROCESS)PsGetCurrentProcess();
   KAPC_STATE ApcState;
   SIZE_T Size = 0;

   TRACE_(VIDEOPRT, "IntInt10FreeBuffer\n");
   INFO_(VIDEOPRT, "- Segment: %x\n", Seg);
   INFO_(VIDEOPRT, "- Offset: %x\n", Off);

   IntAttachToCSRSS(&CallingProcess, &ApcState);
   Status = ZwFreeVirtualMemory(NtCurrentProcess(), &MemoryAddress, &Size,
      MEM_RELEASE);
   IntDetachFromCSRSS(&CallingProcess, &ApcState);

   return Status;
}
示例#9
0
/*
 * FUNCTION: Terminates the current thread
 * See "Windows Internals" - Chapter 13, Page 50-53
 */
VOID
NTAPI
PspExitThread(IN NTSTATUS ExitStatus)
{
    CLIENT_DIED_MSG TerminationMsg;
    NTSTATUS Status;
    PTEB Teb;
    PEPROCESS CurrentProcess;
    PETHREAD Thread, OtherThread, PreviousThread = NULL;
    PVOID DeallocationStack;
    SIZE_T Dummy;
    BOOLEAN Last = FALSE;
    PTERMINATION_PORT TerminationPort, NextPort;
    PLIST_ENTRY FirstEntry, CurrentEntry;
    PKAPC Apc;
    PTOKEN PrimaryToken;
    PAGED_CODE();
    PSTRACE(PS_KILL_DEBUG, "ExitStatus: %d\n", ExitStatus);

    /* Get the Current Thread and Process */
    Thread = PsGetCurrentThread();
    CurrentProcess = Thread->ThreadsProcess;
    ASSERT((Thread) == PsGetCurrentThread());

    /* Can't terminate a thread if it attached another process */
    if (KeIsAttachedProcess())
    {
        /* Bugcheck */
        KeBugCheckEx(INVALID_PROCESS_ATTACH_ATTEMPT,
                     (ULONG_PTR)CurrentProcess,
                     (ULONG_PTR)Thread->Tcb.ApcState.Process,
                     (ULONG_PTR)Thread->Tcb.ApcStateIndex,
                     (ULONG_PTR)Thread);
    }

    /* Lower to Passive Level */
    KeLowerIrql(PASSIVE_LEVEL);

    /* Can't be a worker thread */
    if (Thread->ActiveExWorker)
    {
        /* Bugcheck */
        KeBugCheckEx(ACTIVE_EX_WORKER_THREAD_TERMINATION,
                     (ULONG_PTR)Thread,
                     0,
                     0,
                     0);
    }

    /* Can't have pending APCs */
    if (Thread->Tcb.CombinedApcDisable != 0)
    {
        /* Bugcheck */
        KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
                     0,
                     Thread->Tcb.CombinedApcDisable,
                     0,
                     1);
    }

    /* Lock the thread */
    ExWaitForRundownProtectionRelease(&Thread->RundownProtect);

    /* Cleanup the power state */
    PopCleanupPowerState((PPOWER_STATE)&Thread->Tcb.PowerState);

    /* Call the WMI Callback for Threads */
    //WmiTraceThread(Thread, NULL, FALSE);

    /* Run Thread Notify Routines before we desintegrate the thread */
    PspRunCreateThreadNotifyRoutines(Thread, FALSE);

    /* Lock the Process before we modify its thread entries */
    KeEnterCriticalRegion();
    ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);

    /* Decrease the active thread count, and check if it's 0 */
    if (!(--CurrentProcess->ActiveThreads))
    {
        /* Set the delete flag */
        InterlockedOr((PLONG)&CurrentProcess->Flags, PSF_PROCESS_DELETE_BIT);

        /* Remember we are last */
        Last = TRUE;

        /* Check if this termination is due to the thread dying */
        if (ExitStatus == STATUS_THREAD_IS_TERMINATING)
        {
            /* Check if the last thread was pending */
            if (CurrentProcess->ExitStatus == STATUS_PENDING)
            {
                /* Use the last exit status */
                CurrentProcess->ExitStatus = CurrentProcess->
                                             LastThreadExitStatus;
            }
        }
        else
        {
            /* Just a normal exit, write the code */
            CurrentProcess->ExitStatus = ExitStatus;
        }

        /* Loop all the current threads */
        FirstEntry = &CurrentProcess->ThreadListHead;
        CurrentEntry = FirstEntry->Flink;
        while (FirstEntry != CurrentEntry)
        {
            /* Get the thread on the list */
            OtherThread = CONTAINING_RECORD(CurrentEntry,
                                            ETHREAD,
                                            ThreadListEntry);

            /* Check if it's a thread that's still alive */
            if ((OtherThread != Thread) &&
                !(KeReadStateThread(&OtherThread->Tcb)) &&
                (ObReferenceObjectSafe(OtherThread)))
            {
                /* It's a live thread and we referenced it, unlock process */
                ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
                KeLeaveCriticalRegion();

                /* Wait on the thread */
                KeWaitForSingleObject(OtherThread,
                                      Executive,
                                      KernelMode,
                                      FALSE,
                                      NULL);

                /* Check if we had a previous thread to dereference */
                if (PreviousThread) ObDereferenceObject(PreviousThread);

                /* Remember the thread and re-lock the process */
                PreviousThread = OtherThread;
                KeEnterCriticalRegion();
                ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
            }

            /* Go to the next thread */
            CurrentEntry = CurrentEntry->Flink;
        }
    }
    else if (ExitStatus != STATUS_THREAD_IS_TERMINATING)
    {
        /* Write down the exit status of the last thread to get killed */
        CurrentProcess->LastThreadExitStatus = ExitStatus;
    }

    /* Unlock the Process */
    ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
    KeLeaveCriticalRegion();

    /* Check if we had a previous thread to dereference */
    if (PreviousThread) ObDereferenceObject(PreviousThread);

    /* Check if the process has a debug port and if this is a user thread */
    if ((CurrentProcess->DebugPort) && !(Thread->SystemThread))
    {
        /* Notify the Debug API. */
        Last ? DbgkExitProcess(CurrentProcess->ExitStatus) :
               DbgkExitThread(ExitStatus);
    }

    /* Check if this is a Critical Thread */
    if ((KdDebuggerEnabled) && (Thread->BreakOnTermination))
    {
        /* Break to debugger */
        PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
                              Thread,
                              CurrentProcess->ImageFileName);
    }

    /* Check if it's the last thread and this is a Critical Process */
    if ((Last) && (CurrentProcess->BreakOnTermination))
    {
        /* Check if a debugger is here to handle this */
        if (KdDebuggerEnabled)
        {
            /* Break to debugger */
            PspCatchCriticalBreak("Critical  process 0x%p (in %s) exited\n",
                                  CurrentProcess,
                                  CurrentProcess->ImageFileName);
        }
        else
        {
            /* Bugcheck, we can't allow this */
            KeBugCheckEx(CRITICAL_PROCESS_DIED,
                         (ULONG_PTR)CurrentProcess,
                         0,
                         0,
                         0);
        }
    }

    /* Sanity check */
    ASSERT(Thread->Tcb.CombinedApcDisable == 0);

    /* Process the Termination Ports */
    TerminationPort = Thread->TerminationPort;
    if (TerminationPort)
    {
        /* Setup the message header */
        TerminationMsg.h.u2.ZeroInit = 0;
        TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
        TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
        TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
                                            sizeof(PORT_MESSAGE);

        /* Loop each port */
        do
        {
            /* Save the Create Time */
            TerminationMsg.CreateTime = Thread->CreateTime;

            /* Loop trying to send message */
            while (TRUE)
            {
                /* Send the LPC Message */
                Status = LpcRequestPort(TerminationPort->Port,
                                        &TerminationMsg.h);
                if ((Status == STATUS_NO_MEMORY) ||
                    (Status == STATUS_INSUFFICIENT_RESOURCES))
                {
                    /* Wait a bit and try again */
                    KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
                    continue;
                }
                break;
            }

            /* Dereference this LPC Port */
            ObDereferenceObject(TerminationPort->Port);

            /* Move to the next one */
            NextPort = TerminationPort->Next;

            /* Free the Termination Port Object */
            ExFreePoolWithTag(TerminationPort, '=TsP');

            /* Keep looping as long as there is a port */
            TerminationPort = NextPort;
        } while (TerminationPort);
    }
    else if (((ExitStatus == STATUS_THREAD_IS_TERMINATING) &&
              (Thread->DeadThread)) ||
             !(Thread->DeadThread))
    {
        /*
         * This case is special and deserves some extra comments. What
         * basically happens here is that this thread doesn't have a termination
         * port, which means that it died before being fully created. Since we
         * still have to notify an LPC Server, we'll use the exception port,
         * which we know exists. However, we need to know how far the thread
         * actually got created. We have three possibilities:
         *
         *  - NtCreateThread returned an error really early: DeadThread is set.
         *  - NtCreateThread managed to create the thread: DeadThread is off.
         *  - NtCreateThread was creating the thread (with DeadThread set,
         *    but the thread got killed prematurely: STATUS_THREAD_IS_TERMINATING
         *    is our exit code.)
         *
         * For the 2 & 3rd scenarios, the thread has been created far enough to
         * warrant notification to the LPC Server.
         */

        /* Setup the message header */
        TerminationMsg.h.u2.ZeroInit = 0;
        TerminationMsg.h.u2.s2.Type = LPC_CLIENT_DIED;
        TerminationMsg.h.u1.s1.TotalLength = sizeof(TerminationMsg);
        TerminationMsg.h.u1.s1.DataLength = sizeof(TerminationMsg) -
                                            sizeof(PORT_MESSAGE);

        /* Make sure the process has an exception port */
        if (CurrentProcess->ExceptionPort)
        {
            /* Save the Create Time */
            TerminationMsg.CreateTime = Thread->CreateTime;

            /* Loop trying to send message */
            while (TRUE)
            {
                /* Send the LPC Message */
                Status = LpcRequestPort(CurrentProcess->ExceptionPort,
                                        &TerminationMsg.h);
                if ((Status == STATUS_NO_MEMORY) ||
                    (Status == STATUS_INSUFFICIENT_RESOURCES))
                {
                    /* Wait a bit and try again */
                    KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
                    continue;
                }
                break;
            }
        }
    }

    /* Rundown Win32 Thread if there is one */
    if (Thread->Tcb.Win32Thread) PspW32ThreadCallout(Thread,
                                                     PsW32ThreadCalloutExit);

    /* If we are the last thread and have a W32 Process */
    if ((Last) && (CurrentProcess->Win32Process))
    {
        /* Run it down too */
        PspW32ProcessCallout(CurrentProcess, FALSE);
    }

    /* Make sure Stack Swap is enabled */
    if (!Thread->Tcb.EnableStackSwap)
    {
        /* Stack swap really shouldn't be disabled during exit! */
        KeBugCheckEx(KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
    }

    /* Cancel I/O for the thread. */
    IoCancelThreadIo(Thread);

    /* Rundown Timers */
    ExTimerRundown();

    /* FIXME: Rundown Registry Notifications (NtChangeNotify)
    CmNotifyRunDown(Thread); */

    /* Rundown Mutexes */
    KeRundownThread();

    /* Check if we have a TEB */
    Teb = Thread->Tcb.Teb;
    if (Teb)
    {
        /* Check if the thread is still alive */
        if (!Thread->DeadThread)
        {
            /* Check if we need to free its stack */
            if (Teb->FreeStackOnTermination)
            {
                /* Set the TEB's Deallocation Stack as the Base Address */
                Dummy = 0;
                DeallocationStack = Teb->DeallocationStack;

                /* Free the Thread's Stack */
                ZwFreeVirtualMemory(NtCurrentProcess(),
                                    &DeallocationStack,
                                    &Dummy,
                                    MEM_RELEASE);
            }

            /* Free the debug handle */
            if (Teb->DbgSsReserved[1]) ObCloseHandle(Teb->DbgSsReserved[1],
                                                     UserMode);
        }

        /* Decommit the TEB */
        MmDeleteTeb(CurrentProcess, Teb);
        Thread->Tcb.Teb = NULL;
    }

    /* Free LPC Data */
    LpcExitThread(Thread);

    /* Save the exit status and exit time */
    Thread->ExitStatus = ExitStatus;
    KeQuerySystemTime(&Thread->ExitTime);

    /* Sanity check */
    ASSERT(Thread->Tcb.CombinedApcDisable == 0);

    /* Check if this is the final thread or not */
    if (Last)
    {
        /* Set the process exit time */
        CurrentProcess->ExitTime = Thread->ExitTime;

        /* Exit the process */
        PspExitProcess(TRUE, CurrentProcess);

        /* Get the process token and check if we need to audit */
        PrimaryToken = PsReferencePrimaryToken(CurrentProcess);
        if (SeDetailedAuditingWithToken(PrimaryToken))
        {
            /* Audit the exit */
            SeAuditProcessExit(CurrentProcess);
        }

        /* Dereference the process token */
        ObFastDereferenceObject(&CurrentProcess->Token, PrimaryToken);

        /* Check if this is a VDM Process and rundown the VDM DPCs if so */
        if (CurrentProcess->VdmObjects) { /* VdmRundownDpcs(CurrentProcess); */ }

        /* Kill the process in the Object Manager */
        ObKillProcess(CurrentProcess);

        /* Check if we have a section object */
        if (CurrentProcess->SectionObject)
        {
            /* Dereference and clear the Section Object */
            ObDereferenceObject(CurrentProcess->SectionObject);
            CurrentProcess->SectionObject = NULL;
        }

        /* Check if the process is part of a job */
        if (CurrentProcess->Job)
        {
            /* Remove the process from the job */
            PspExitProcessFromJob(CurrentProcess->Job, CurrentProcess);
        }
    }

    /* Disable APCs */
    KeEnterCriticalRegion();

    /* Disable APC queueing, force a resumption */
    Thread->Tcb.ApcQueueable = FALSE;
    KeForceResumeThread(&Thread->Tcb);

    /* Re-enable APCs */
    KeLeaveCriticalRegion();

    /* Flush the User APCs */
    FirstEntry = KeFlushQueueApc(&Thread->Tcb, UserMode);
    if (FirstEntry)
    {
        /* Start with the first entry */
        CurrentEntry = FirstEntry;
        do
        {
           /* Get the APC */
           Apc = CONTAINING_RECORD(CurrentEntry, KAPC, ApcListEntry);

           /* Move to the next one */
           CurrentEntry = CurrentEntry->Flink;

           /* Rundown the APC or de-allocate it */
           if (Apc->RundownRoutine)
           {
              /* Call its own routine */
              Apc->RundownRoutine(Apc);
           }
           else
           {
              /* Do it ourselves */
              ExFreePool(Apc);
           }
        }
        while (CurrentEntry != FirstEntry);
    }

    /* Clean address space if this was the last thread */
    if (Last) MmCleanProcessAddressSpace(CurrentProcess);

    /* Call the Lego routine */
    if (Thread->Tcb.LegoData) PspRunLegoRoutine(&Thread->Tcb);

    /* Flush the APC queue, which should be empty */
    FirstEntry = KeFlushQueueApc(&Thread->Tcb, KernelMode);
    if ((FirstEntry) || (Thread->Tcb.CombinedApcDisable != 0))
    {
        /* Bugcheck time */
        KeBugCheckEx(KERNEL_APC_PENDING_DURING_EXIT,
                     (ULONG_PTR)FirstEntry,
                     Thread->Tcb.CombinedApcDisable,
                     KeGetCurrentIrql(),
                     0);
    }

    /* Signal the process if this was the last thread */
    if (Last) KeSetProcess(&CurrentProcess->Pcb, 0, FALSE);

    /* Terminate the Thread from the Scheduler */
    KeTerminateThread(0);
}
示例#10
0
BOOL CProcess::HideProcess()
{
	EnableDebugPriv(SE_DEBUG_NAME);
	(InitializeFunction());

	//进程信息及长度
	PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
	DWORD buflen=0x10000,needlen=0;
	ULONG  uObjCnt = 0;
	NTSTATUS  status;
	BOOL bRet;
	HANDLE hProcess;

	//通过打开进程获取进程句柄
	hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,GetCurrentProcessId());

	//获得进程对象的地址
	PBYTE pBuf = NULL;
	do
	{
		//申请查询句柄信息所需的内存
		ZwAllocateVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,0,&buflen,MEM_COMMIT,PAGE_READWRITE);
		if (pBuf == NULL) return FALSE;
		//查询系统句柄信息
		status=NtQuerySystemInformation(SystemHandleInformation,(PVOID)pBuf,buflen,&needlen);
		if (NT_SUCCESS(status)) break;
		//不成功,则释放内存
		//这里只要一块大内存够放这些内容就行,或者直接申请一块足够大的也可以
		//返回的needlen可以做为参考
		ZwFreeVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE);
		//然后把要申请的内存大小乘2,直至成功为止
		buflen *= 2;
		pBuf = NULL;
	} while(TRUE);

	uObjCnt = (ULONG)*(ULONG*)pBuf;
	DWORD dwEPROCESS;
	//ULONG dwCurrentPID;
	pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)(pBuf+sizeof(ULONG));
	if(NT_SUCCESS(status))
	{
		for(int i=0;i<(int)uObjCnt;i++)
		{
			( Out(Dbg,"pHandleInfo->Handle:%d pHandleInfo->ProcessID:%d \n",pHandleInfo->Handle,pHandleInfo->ProcessID));			
			if(pHandleInfo->Handle==(USHORT)hProcess && pHandleInfo->ProcessID==(ULONG)GetCurrentProcessId())/*pHandleInfo->ProcessID==dwPID && pHandleInfo->Handle==(USHORT)GetProcessHand()*/
			{

				dwEPROCESS = (DWORD)pHandleInfo->Object;
				Out(Dbg,"dwEPROCESS: 0x%x",(ULONG)dwEPROCESS);
				//dwCurrentPID = pHandleInfo->ProcessID;
				break;
			}
			pHandleInfo++;
		}
		//在拿到当前进程的EPROCESS基址后,释放掉内存
		ZwFreeVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE);
		//关闭句柄
		CloseHandle(hProcess);
		bRet = TRUE;
	}

	//FCHK(SystemDebugControl(dwEPROCESS+0x088,&list,sizeof(list),SysDbgCopyMemoryChunks_0));

	//FCHK(SystemDebugControl((ULONG)(list.Blink)+0x4,&list.Blink,sizeof(list.Blink),SysDbgCopyMemoryChunks_1));

	//FCHK(SystemDebugControl((ULONG)(list.Blink),&list.Flink,sizeof(list.Flink),SysDbgCopyMemoryChunks_1));
	MEMORY_CHUNKS datas;
	datas.Address = dwEPROCESS+0x088;
	LIST_ENTRY list = {0};
	datas.Data =&list;
	datas.Length = sizeof(list);
	OperateSystemMemory(datas,SysDbgCopyMemoryChunks_0);
	datas.Address = (ULONG)(list.Blink)+0x4;
	datas.Data =&list.Blink;
	datas.Length = sizeof(list.Blink);
	OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
	datas.Address = (ULONG)(list.Blink);
	datas.Data =&list.Flink;
	datas.Length = sizeof(list.Flink);
	OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
	return TRUE;
}
示例#11
0
文件: rmmain.c 项目: conioh/os-design
NTSTATUS
SepRmCallLsa(
    PSEP_WORK_ITEM SepWorkItem
    )
/*++

Routine Description:

    This function sends a command to the LSA via the LSA Reference Monitor
    Server Command LPC Port.  If the command has parameters, they will be
    copied directly into a message structure and sent via LPC, therefore,
    the supplied parameters may not contain any absolute pointers.  A caller
    must remove pointers by "marshalling" them into the buffer CommandParams.

    This function will create a queue of requests.  This is in order to allow
    greater throughput for the majority if its callers.  If a thread enters
    this routine and finds the queue empty, it is the responsibility of that
    thread to service all requests that come in while it is working until the
    queue is empty again.  Other threads that enter will simply hook their work
    item onto the queue and exit.


    To implement a new LSA command, do the following:
    ================================================

    (1)  If the command takes no parameters, just call this routine directly
         and provide an LSA worker routine called Lsap<command>Wrkr.  See
         file lsa\server\lsarm.c for examples

    (2)  If the command takes parameters, provide a routine called
         SepRmSend<command>Command that takes the parameters in unmarshalled
         form and calls SepRmCallLsa() with the command id, marshalled
         parameters, length  of marshalled parameters and pointer to
         optional reply message.  The marshalled parameters are free format:
         the only restriction is that there must be no absolute address
         pointers.  These parameters are all placed in the passed LsaWorkItem
         structure.

    (3)  In file private\inc\ntrmlsa.h, append a command name  to the
         enumerated type LSA_COMMAND_NUMBER defined in file
         private\inc\ntrmlsa.h.  Change the #define for LsapMaximumCommand
         to reference the new command.

    (4)  Add the Lsap<command>Wrkr to the command dispatch table structure
         LsapCommandDispatch[] in file lsarm.c.

    (5)  Add function prototypes to lsap.h and sep.h.


Arguments:

    LsaWorkItem - Supplies a pointer to an SE_LSA_WORK_ITEM containing the
        information to be passed to LSA.  This structure will be freed
        asynchronously by some invocation of this routine, not necessarily
        in the current context.

        !THIS PARAMETER MUST BE ALLOCATED OUT OF NONPAGED POOL!

Return Value:

    NTSTATUS - Result Code.  This is either a result code returned from
        trying to send the command/receive the reply, or a status code
        from the command itself.

--*/

{
    NTSTATUS Status = STATUS_SUCCESS;
    LSA_COMMAND_MESSAGE CommandMessage;
    LSA_REPLY_MESSAGE ReplyMessage;
    PSEP_LSA_WORK_ITEM WorkQueueItem;
    ULONG LocalListLength = 0;
    SIZE_T RegionSize;
    PVOID CopiedCommandParams = NULL;
    PVOID LsaViewCopiedCommandParams = NULL;

    PAGED_CODE();

#if 0
  DbgPrint("Entering SepRmCallLsa\n");
#endif

    WorkQueueItem = SepWorkListHead();

    KeAttachProcess( &SepRmLsaCallProcess->Pcb );

    while ( WorkQueueItem ) {

#if 0
      DbgPrint("Got a work item from head of queue, processing\n");
#endif

        //
        // Construct a message for LPC.  First, fill in the message header
        // fields for LPC, specifying the message type and data sizes for
        // the outgoing CommandMessage and the incoming ReplyMessage.
        //

        CommandMessage.MessageHeader.u2.ZeroInit = 0;
        CommandMessage.MessageHeader.u1.s1.TotalLength =
            ((CSHORT) RM_COMMAND_MESSAGE_HEADER_SIZE +
            (CSHORT) WorkQueueItem->CommandParamsLength);
        CommandMessage.MessageHeader.u1.s1.DataLength =
            CommandMessage.MessageHeader.u1.s1.TotalLength -
            (CSHORT) sizeof(PORT_MESSAGE);

        ReplyMessage.MessageHeader.u2.ZeroInit = 0;
        ReplyMessage.MessageHeader.u1.s1.DataLength = (CSHORT) WorkQueueItem->ReplyBufferLength;
        ReplyMessage.MessageHeader.u1.s1.TotalLength =
            ReplyMessage.MessageHeader.u1.s1.DataLength +
            (CSHORT) sizeof(PORT_MESSAGE);

        //
        // Next, fill in the header info needed by the LSA.
        //

        CommandMessage.CommandNumber = WorkQueueItem->CommandNumber;
        ReplyMessage.ReturnedStatus = STATUS_SUCCESS;

        //
        // Set up the Command Parameters either in the LPC Command Message
        // itself, in the preallocated Lsa shared memory block, or in a
        // specially allocated block.  The parameters are either
        // immediate (i.e. in the WorkQueueItem itself, or are in a buffer
        // pointed to by the address in the WorkQueueItem.
        //

        switch (WorkQueueItem->CommandParamsMemoryType) {

        case SepRmImmediateMemory:

            //
            // The Command Parameters are in the CommandParams buffer
            // in the Work Queue Item.  Just copy them to the corresponding
            // buffer in the CommandMessage buffer.
            //

            CommandMessage.CommandParamsMemoryType = SepRmImmediateMemory;

            RtlCopyMemory(
                CommandMessage.CommandParams,
                &WorkQueueItem->CommandParams,
                WorkQueueItem->CommandParamsLength
                );

            break;

        case SepRmPagedPoolMemory:
        case SepRmUnspecifiedMemory:

            //
            // The Command Parameters are contained in paged pool memory.
            // Since this memory is is not accessible by the LSA, we must
            // copy of them either to the LPC Command Message Block, or
            // into LSA shared memory.
            //

            if (WorkQueueItem->CommandParamsLength <= LSA_MAXIMUM_COMMAND_PARAM_SIZE) {

                //
                // Parameters will fit into the LPC Command Message block.
                //

                CopiedCommandParams = CommandMessage.CommandParams;

                RtlCopyMemory(
                    CopiedCommandParams,
                    WorkQueueItem->CommandParams.BaseAddress,
                    WorkQueueItem->CommandParamsLength
                    );

                CommandMessage.CommandParamsMemoryType = SepRmImmediateMemory;

            } else {

                //
                // Parameters too large for LPC Command Message block.
                // If possible, copy them to the preallocated Lsa Shared
                // Memory block.  If they are too large to fit, copy them
                // to an individually allocated chunk of Shared Virtual
                // Memory.
                //

                if (WorkQueueItem->CommandParamsLength <= SEP_RM_LSA_SHARED_MEMORY_SIZE) {

                    RtlCopyMemory(
                        SepRmState.RmViewPortMemory,
                        WorkQueueItem->CommandParams.BaseAddress,
                        WorkQueueItem->CommandParamsLength
                        );

                    LsaViewCopiedCommandParams = SepRmState.LsaViewPortMemory;
                    CommandMessage.CommandParamsMemoryType = SepRmLsaCommandPortSharedMemory;

                } else {

                    Status = SepAdtCopyToLsaSharedMemory(
                                 SepLsaHandle,
                                 WorkQueueItem->CommandParams.BaseAddress,
                                 WorkQueueItem->CommandParamsLength,
                                 &LsaViewCopiedCommandParams
                                 );

                    if (!NT_SUCCESS(Status)) {

                        //
                        // An error occurred, most likely in allocating
                        // shared virtual memory.  For now, just ignore
                        // the error and discard the Audit Record.  Later,
                        // we may consider generating a warning record
                        // indicating some records lost.
                        //

                        break;

                    }

                    CommandMessage.CommandParamsMemoryType = SepRmLsaCustomSharedMemory;
                }

                //
                // Buffer has been successfully copied to a shared Lsa
                // memory buffer.  Place the address of the buffer valid in
                // the LSA's process context in the Command Message.
                //

                *((PVOID *) CommandMessage.CommandParams) =
                    LsaViewCopiedCommandParams;

                CommandMessage.MessageHeader.u1.s1.TotalLength =
                    ((CSHORT) RM_COMMAND_MESSAGE_HEADER_SIZE +
                    (CSHORT) sizeof( LsaViewCopiedCommandParams ));
                CommandMessage.MessageHeader.u1.s1.DataLength =
                    CommandMessage.MessageHeader.u1.s1.TotalLength -
                    (CSHORT) sizeof(PORT_MESSAGE);
            }

            //
            // Free input command params buffer if Paged Pool.
            //

            if (WorkQueueItem->CommandParamsMemoryType == SepRmPagedPoolMemory) {

                ExFreePool( WorkQueueItem->CommandParams.BaseAddress );
            }

            break;

        default:

            Status = STATUS_INVALID_PARAMETER;
            break;
        }

        if (NT_SUCCESS(Status)) {

            //
            // Send Message to the LSA via the LSA Server Command LPC Port.
            // This must be done in the process in which the handle was created.
            //

            Status = ZwRequestWaitReplyPort(
                         SepRmState.LsaCommandPortHandle,
                         (PPORT_MESSAGE) &CommandMessage,
                         (PPORT_MESSAGE) &ReplyMessage
                         );

            //
            // If the command was successful, copy the data back to the output
            // buffer.
            //

            if (NT_SUCCESS(Status)) {

                //
                // Move output from command (if any) to buffer.  Note that this
                // is done even if the command returns status, because some status
                // values are not errors.
                //

                if (ARGUMENT_PRESENT(WorkQueueItem->ReplyBuffer)) {

                    RtlCopyMemory(
                        WorkQueueItem->ReplyBuffer,
                        ReplyMessage.ReplyBuffer,
                        WorkQueueItem->ReplyBufferLength
                        );
                }

                //
                // Return status from command.
                //

                Status = ReplyMessage.ReturnedStatus;

                if (!NT_SUCCESS(Status)) {
                    KdPrint(("Security: Command sent from RM to LSA returned 0x%lx\n",
                        Status));
                }

            } else {

                KdPrint(("Security: Sending Command RM to LSA failed 0x%lx\n", Status));
            }

            //
            // On return from the LPC call to the LSA, we expect the called
            // LSA worker routine to have copied the Command Parameters
            // buffer (if any).  If a custom shared memory boffer was allocated,
            // free it now.
            //

            if (CommandMessage.CommandParamsMemoryType == SepRmLsaCustomSharedMemory) {

                RegionSize = 0;

                Status = ZwFreeVirtualMemory(
                             SepLsaHandle,
                             (PVOID *) &CommandMessage.CommandParams,
                             &RegionSize,
                             MEM_RELEASE
                             );

                ASSERT(NT_SUCCESS(Status));
            }

        }


        //
        // Clean up.  We must call the cleanup functions on its parameter
        // and then free the used WorkQueueItem itself.
        //

        if ( ARGUMENT_PRESENT( WorkQueueItem->CleanupFunction)) {

            (WorkQueueItem->CleanupFunction)(WorkQueueItem->CleanupParameter);
        }

        //
        // Determine if there is more work to do on this list
        //

        WorkQueueItem = SepDequeueWorkItem();
#if 0
      if ( WorkQueueItem ) {
            DbgPrint("Got another item from list, going back\n");
      } else {
          DbgPrint("List is empty, leaving\n");
      }
#endif


    }

    KeDetachProcess();

    if ( LocalListLength > SepLsaQueueLength ) {
        SepLsaQueueLength = LocalListLength;
    }

    return Status;
}
示例#12
0
文件: stubs.c 项目: mingpen/OpenNT
SECURITY_STATUS SEC_ENTRY
AcceptSecurityContext(
    PCredHandle                 phCredential,       // Cred to base context
    PCtxtHandle                 phContext,          // Existing context (OPT)
    PSecBufferDesc              pInput,             // Input buffer
    unsigned long               fContextReq,        // Context Requirements
    unsigned long               TargetDataRep,      // Target Data Rep
    PCtxtHandle                 phNewContext,       // (out) New context handle
    PSecBufferDesc              pOutput,            // (inout) Output buffers
    unsigned long SEC_FAR *     pfContextAttr,      // (out) Context attributes
    PTimeStamp                  ptsExpiry           // (out) Life span (OPT)
    )
{
    SECURITY_STATUS scRet;
    NTSTATUS SubStatus;
    PAUTHENTICATE_MESSAGE AuthenticateMessage;
    ULONG AuthenticateMessageSize;
    PNTLM_AUTHENTICATE_MESSAGE NtlmAuthenticateMessage;
    ULONG NtlmAuthenticateMessageSize;
    PNTLM_ACCEPT_RESPONSE NtlmAcceptResponse = NULL;
    PMSV1_0_LM20_LOGON LogonBuffer = NULL;
    ULONG LogonBufferSize;
    PMSV1_0_LM20_LOGON_PROFILE LogonProfile = NULL;
    ULONG LogonProfileSize;
    PSecBuffer AcceptResponseToken = NULL;
    PClient Client = NULL;
    ANSI_STRING SourceName;
    LUID LogonId;
    LUID UNALIGNED * TempLogonId;
    LARGE_INTEGER UNALIGNED * TempKickoffTime;
    HANDLE TokenHandle = NULL;
    QUOTA_LIMITS Quotas;
    PUCHAR Where;
    STRING DomainName;
    STRING UserName;
    STRING Workstation;
    STRING NtChallengeResponse;
    STRING LmChallengeResponse;
    ULONG EffectivePackageId;


    RtlInitString(
        &SourceName,
        NULL
        );

    PAGED_CODE();

    //
    // Check for valid sizes, pointers, etc.:
    //


    if (!phCredential)
    {
        return(SEC_E_INVALID_HANDLE);
    }


    //
    // Check that we can indeed call the LSA and get the client
    // handle to it.
    //

    scRet = IsOkayToExec(&Client);
    if (!NT_SUCCESS(scRet))
    {
        return(scRet);
    }

    //
    // Locate the buffers with the input data
    //

    if (!GetTokenBuffer(
            pInput,
            0,          // get the first security token
            (PVOID *) &AuthenticateMessage,
            &AuthenticateMessageSize,
            TRUE        // may be readonly
            ) ||
        (!GetTokenBuffer(
            pInput,
            1,          // get the second security token
            (PVOID *) &NtlmAuthenticateMessage,
            &NtlmAuthenticateMessageSize,
            TRUE        // may be readonly
            )))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Get the output tokens
    //

    if (!GetSecurityToken(
            pOutput,
            0,
            &AcceptResponseToken ) )
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Make sure the sizes are o.k.
    //

    if ((AuthenticateMessageSize < sizeof(AUTHENTICATE_MESSAGE)) ||
        (NtlmAuthenticateMessageSize < sizeof(NTLM_AUTHENTICATE_MESSAGE)))
    {
        scRet = SEC_E_INVALID_TOKEN;
    }

    //
    // Make sure the caller does not want us to allocate memory:
    //

    if (fContextReq & ISC_REQ_ALLOCATE_MEMORY)
    {
        scRet = SEC_E_UNSUPPORTED_FUNCTION;
        goto Cleanup;
    }

    if (AcceptResponseToken->cbBuffer < sizeof(NTLM_ACCEPT_RESPONSE))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }


    //
    // Verify the validity of the Authenticate message.
    //

    if (strncmp(
            AuthenticateMessage->Signature,
            NTLMSSP_SIGNATURE,
            sizeof(NTLMSSP_SIGNATURE)))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    if (AuthenticateMessage->MessageType != NtLmAuthenticate)
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Fixup the buffer pointers
    //

    UserName = AuthenticateMessage->UserName;
    UserName.Buffer =  UserName.Buffer + (ULONG) AuthenticateMessage;

    DomainName = AuthenticateMessage->DomainName;
    DomainName.Buffer =  DomainName.Buffer + (ULONG) AuthenticateMessage;

    Workstation = AuthenticateMessage->Workstation;
    Workstation.Buffer =  Workstation.Buffer + (ULONG) AuthenticateMessage;

    NtChallengeResponse = AuthenticateMessage->NtChallengeResponse;
    NtChallengeResponse.Buffer =  NtChallengeResponse.Buffer + (ULONG) AuthenticateMessage;

    LmChallengeResponse = AuthenticateMessage->LmChallengeResponse;
    LmChallengeResponse.Buffer =  LmChallengeResponse.Buffer + (ULONG) AuthenticateMessage;

    //
    // Allocate a buffer to pass into LsaLogonUser
    //

    LogonBufferSize = sizeof(MSV1_0_LM20_LOGON) +
                        UserName.Length +
                        DomainName.Length +
                        Workstation.Length +
                        LmChallengeResponse.Length +
                        NtChallengeResponse.Length;

    scRet = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &LogonBuffer,
                0L,
                &LogonBufferSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    //
    // Fill in the fixed-length portions
    //

    LogonBuffer->MessageType = MsV1_0NetworkLogon;

    RtlCopyMemory(
        LogonBuffer->ChallengeToClient,
        NtlmAuthenticateMessage->ChallengeToClient,
        MSV1_0_CHALLENGE_LENGTH
        );

    //
    // Fill in the variable length pieces
    //

    Where = (PUCHAR) (LogonBuffer + 1);

    PutString(
        (PSTRING) &LogonBuffer->LogonDomainName,
        &DomainName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->UserName,
        &UserName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->Workstation,
        &Workstation,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->CaseSensitiveChallengeResponse,
        &NtChallengeResponse,
        0,
        &Where
        );

    PutString(
        (PSTRING) &LogonBuffer->CaseInsensitiveChallengeResponse,
        &LmChallengeResponse,
        0,
        &Where
        );

    LogonBuffer->ParameterControl = MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
                                     NtlmAuthenticateMessage->ParameterControl;

    scRet = RtlUnicodeStringToAnsiString(
                &SourceName,
                (PUNICODE_STRING) &Workstation,
                TRUE
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    if ( fContextReq & ASC_REQ_LICENSING )
    {
        EffectivePackageId = PackageId | LSA_CALL_LICENSE_SERVER ;
    }
    else
    {
        EffectivePackageId = PackageId ;
    }

    scRet = LsaLogonUser(
                Client->hPort,
                &SourceName,
                Network,
                EffectivePackageId,
                LogonBuffer,
                LogonBufferSize,
                NULL,               // token groups
                &KsecTokenSource,
                (PVOID *) &LogonProfile,
                &LogonProfileSize,
                &LogonId,
                &TokenHandle,
                &Quotas,
                &SubStatus
                );

    if (scRet == STATUS_ACCOUNT_RESTRICTION)
    {
        scRet = SubStatus;
    }
    if (!NT_SUCCESS(scRet))
    {
        //
        // LsaLogonUser returns garbage for the token if it fails,
        // so zero it now so we don't try to close it later.
        //

        TokenHandle = NULL;
        goto Cleanup;
    }

    //
    // Create the kernel context
    //

    scRet = NtlmInitKernelContext(
                LogonProfile->UserSessionKey,
                LogonProfile->LanmanSessionKey,
                TokenHandle,
                phNewContext
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    TokenHandle = NULL;

    //
    // Allocate the return buffer.
    //


    NtlmAcceptResponse = (PNTLM_ACCEPT_RESPONSE) AcceptResponseToken->pvBuffer;
    if (NtlmAcceptResponse == NULL)
    {
        scRet = SEC_E_INSUFFICIENT_MEMORY;
        goto Cleanup;
    }

    TempLogonId = (LUID UNALIGNED *) &NtlmAcceptResponse->LogonId;
    *TempLogonId = LogonId;
    NtlmAcceptResponse->UserFlags = LogonProfile->UserFlags;

    RtlCopyMemory(
        NtlmAcceptResponse->UserSessionKey,
        LogonProfile->UserSessionKey,
        MSV1_0_USER_SESSION_KEY_LENGTH
        );

    RtlCopyMemory(
        NtlmAcceptResponse->LanmanSessionKey,
        LogonProfile->LanmanSessionKey,
        MSV1_0_LANMAN_SESSION_KEY_LENGTH
        );

    TempKickoffTime = (LARGE_INTEGER UNALIGNED *) &NtlmAcceptResponse->KickoffTime;
    *TempKickoffTime = LogonProfile->KickOffTime;

    AcceptResponseToken->cbBuffer = sizeof(NTLM_ACCEPT_RESPONSE);

    if ( fContextReq & ASC_REQ_LICENSING )
    {
        *pfContextAttr = ASC_RET_ALLOCATED_MEMORY | ASC_RET_LICENSING ;
    }
    else
    {
        *pfContextAttr = ASC_RET_ALLOCATED_MEMORY;
    }

    *ptsExpiry = LogonProfile->LogoffTime;
    scRet = SEC_E_OK;


Cleanup:
    if (SourceName.Buffer != NULL)
    {
        RtlFreeAnsiString(&SourceName);
    }

    if (LogonBuffer != NULL)
    {
        ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &LogonBuffer,
            &LogonBufferSize,
            MEM_RELEASE
            );
    }

    if (LogonProfile != NULL)
    {
        LsaFreeReturnBuffer(LogonProfile);
    }


    if (TokenHandle != NULL)
    {
        NtClose(TokenHandle);
    }

    return(scRet);

}
示例#13
0
文件: stubs.c 项目: mingpen/OpenNT
SECURITY_STATUS SEC_ENTRY
InitializeSecurityContextW(
    PCredHandle                 phCredential,       // Cred to base context
    PCtxtHandle                 phContext,          // Existing context (OPT)
    PSECURITY_STRING            pssTargetName,      // Name of target
    unsigned long               fContextReq,        // Context Requirements
    unsigned long               Reserved1,          // Reserved, MBZ
    unsigned long               TargetDataRep,      // Data rep of target
    PSecBufferDesc              pInput,             // Input Buffers
    unsigned long               Reserved2,          // Reserved, MBZ
    PCtxtHandle                 phNewContext,       // (out) New Context handle
    PSecBufferDesc              pOutput,            // (inout) Output Buffers
    unsigned long SEC_FAR *     pfContextAttr,      // (out) Context attrs
    PTimeStamp                  ptsExpiry           // (out) Life span (OPT)
    )
{
    SECURITY_STATUS scRet;
    PMSV1_0_GETCHALLENRESP_REQUEST ChallengeRequest = NULL;
    ULONG ChallengeRequestSize;
    PMSV1_0_GETCHALLENRESP_RESPONSE ChallengeResponse = NULL;
    ULONG ChallengeResponseSize;
    PCHALLENGE_MESSAGE ChallengeMessage = NULL;
    ULONG ChallengeMessageSize;
    PNTLM_CHALLENGE_MESSAGE NtlmChallengeMessage = NULL;
    ULONG NtlmChallengeMessageSize;
    PAUTHENTICATE_MESSAGE AuthenticateMessage = NULL;
    ULONG AuthenticateMessageSize;
    PNTLM_INITIALIZE_RESPONSE NtlmInitializeResponse = NULL;
    PClient Client = NULL;
    UNICODE_STRING PasswordToUse;
    UNICODE_STRING UserNameToUse;
    UNICODE_STRING DomainNameToUse;
    ULONG ParameterControl = USE_PRIMARY_PASSWORD |
                                RETURN_PRIMARY_USERNAME |
                                RETURN_PRIMARY_LOGON_DOMAINNAME;

    NTSTATUS FinalStatus = STATUS_SUCCESS;
    PUCHAR Where;
    PSecBuffer AuthenticationToken = NULL;
    PSecBuffer InitializeResponseToken = NULL;
    BOOLEAN UseSuppliedCreds = FALSE;


    PAGED_CODE();

    RtlInitUnicodeString(
        &PasswordToUse,
        NULL
        );

    RtlInitUnicodeString(
        &UserNameToUse,
        NULL
        );

    RtlInitUnicodeString(
        &DomainNameToUse,
        NULL
        );

    //
    // Check for valid sizes, pointers, etc.:
    //


    if (!phCredential)
    {
        return(SEC_E_INVALID_HANDLE);
    }


    //
    // Check that we can indeed call the LSA and get the client
    // handle to it.
    //

    scRet = IsOkayToExec(&Client);
    if (!NT_SUCCESS(scRet))
    {
        return(scRet);
    }

    //
    // Locate the buffers with the input data
    //

    if (!GetTokenBuffer(
            pInput,
            0,          // get the first security token
            (PVOID *) &ChallengeMessage,
            &ChallengeMessageSize,
            TRUE        // may be readonly
            ))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // If we are using supplied creds, get them now too.
    //


    if (fContextReq & ISC_REQ_USE_SUPPLIED_CREDS)
    {
        if (!GetTokenBuffer(
            pInput,
            1,          // get the second security token
            (PVOID *) &NtlmChallengeMessage,
            &NtlmChallengeMessageSize,
            TRUE        // may be readonly
            ))
        {
            scRet = SEC_E_INVALID_TOKEN;
            goto Cleanup;
        }
        else
        {
            UseSuppliedCreds = TRUE;
        }

    }

    //
    // Get the output tokens
    //

    if (!GetSecurityToken(
            pOutput,
            0,
            &AuthenticationToken) ||
        !GetSecurityToken(
            pOutput,
            1,
            &InitializeResponseToken ) )
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    //
    // Make sure the sizes are o.k.
    //

    if ((ChallengeMessageSize < sizeof(CHALLENGE_MESSAGE)) ||
        (UseSuppliedCreds &&
            !(NtlmChallengeMessageSize < sizeof(NTLM_CHALLENGE_MESSAGE))))
    {
        scRet = SEC_E_INVALID_TOKEN;
    }

    //
    // Make sure the caller wants us to allocate memory:
    //

    if (!(fContextReq & ISC_REQ_ALLOCATE_MEMORY))
    {
        scRet = SEC_E_UNSUPPORTED_FUNCTION;
        goto Cleanup;
    }

//
// BUGBUG: allow calls requesting PROMPT_FOR_CREDS to go through.
// We won't prompt, but we will setup a context properly.
//

//    if ((fContextReq & ISC_REQ_PROMPT_FOR_CREDS) != 0)
//    {
//        scRet = SEC_E_UNSUPPORTED_FUNCTION;
//        goto Cleanup;
//    }

    //
    // Verify the validity of the challenge message.
    //

    if (strncmp(
            ChallengeMessage->Signature,
            NTLMSSP_SIGNATURE,
            sizeof(NTLMSSP_SIGNATURE)))
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    if (ChallengeMessage->MessageType != NtLmChallenge)
    {
        scRet = SEC_E_INVALID_TOKEN;
        goto Cleanup;
    }

    if (ChallengeMessage->NegotiateFlags & NTLMSSP_REQUIRED_NEGOTIATE_FLAGS !=
        NTLMSSP_REQUIRED_NEGOTIATE_FLAGS)
    {
        scRet = SEC_E_UNSUPPORTED_FUNCTION;
        goto Cleanup;
    }

    if ((ChallengeMessage->NegotiateFlags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) != 0)
    {
        ParameterControl |= RETURN_NON_NT_USER_SESSION_KEY;
    }

    if ((fContextReq & ISC_REQ_USE_SUPPLIED_CREDS) != 0)
    {
        if ( NtlmChallengeMessage->Password.Buffer != NULL)
        {
            ParameterControl &= ~USE_PRIMARY_PASSWORD;
            PasswordToUse = NtlmChallengeMessage->Password;
            PasswordToUse.Buffer = (LPWSTR) ((PCHAR) PasswordToUse.Buffer +
                                              (ULONG) NtlmChallengeMessage);
        }

        if (NtlmChallengeMessage->UserName.Length != 0)
        {
            UserNameToUse = NtlmChallengeMessage->UserName;
            UserNameToUse.Buffer = (LPWSTR) ((PCHAR) UserNameToUse.Buffer +
                                              (ULONG) NtlmChallengeMessage);
            ParameterControl &= ~RETURN_PRIMARY_USERNAME;
        }
        if (NtlmChallengeMessage->DomainName.Length != 0)
        {
            DomainNameToUse = NtlmChallengeMessage->DomainName;
            DomainNameToUse.Buffer = (LPWSTR) ((PCHAR) DomainNameToUse.Buffer +
                                              (ULONG) NtlmChallengeMessage);
            ParameterControl &= ~RETURN_PRIMARY_LOGON_DOMAINNAME;
        }

    }

    //
    // Package up the parameter for a call to the LSA.
    //

    ChallengeRequestSize = sizeof(MSV1_0_GETCHALLENRESP_REQUEST) +
                                PasswordToUse.Length;

    scRet = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &ChallengeRequest,
                0L,
                &ChallengeRequestSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );
    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }


    //
    // Build the challenge request message.
    //

    ChallengeRequest->MessageType = MsV1_0Lm20GetChallengeResponse;
    ChallengeRequest->ParameterControl = ParameterControl;
    ChallengeRequest->LogonId = * (PLUID) phCredential;
    RtlCopyMemory(
        ChallengeRequest->ChallengeToClient,
        ChallengeMessage->Challenge,
        MSV1_0_CHALLENGE_LENGTH
        );
    if ((ParameterControl & USE_PRIMARY_PASSWORD) == 0)
    {
        ChallengeRequest->Password.Buffer = (LPWSTR) (ChallengeRequest+1);
        RtlCopyMemory(
            ChallengeRequest->Password.Buffer,
            PasswordToUse.Buffer,
            PasswordToUse.Length
            );
        ChallengeRequest->Password.Length = PasswordToUse.Length;
        ChallengeRequest->Password.MaximumLength = PasswordToUse.Length;
    }

    //
    // Call the LSA to get the challenge response.
    //

    scRet = LsaCallAuthenticationPackage(
                Client->hPort,
                PackageId,
                ChallengeRequest,
                ChallengeRequestSize,
                &ChallengeResponse,
                &ChallengeResponseSize,
                &FinalStatus
                );
    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }
    if (!NT_SUCCESS(FinalStatus))
    {
        scRet = FinalStatus;
        goto Cleanup;
    }

    ASSERT(ChallengeResponse->MessageType == MsV1_0Lm20GetChallengeResponse);
    //
    // Now prepare the output message.
    //

    if (UserNameToUse.Buffer == NULL)
    {
        UserNameToUse = ChallengeResponse->UserName;
    }
    if (DomainNameToUse.Buffer == NULL)
    {
        DomainNameToUse = ChallengeResponse->LogonDomainName;
    }

    AuthenticateMessageSize = sizeof(AUTHENTICATE_MESSAGE) +
                                UserNameToUse.Length +
                                DomainNameToUse.Length +
                                ChallengeResponse->CaseSensitiveChallengeResponse.Length +
                                ChallengeResponse->CaseInsensitiveChallengeResponse.Length;

    //
    // BUGBUG: where do I get the workstation name from?
    //

    AuthenticateMessage = (PAUTHENTICATE_MESSAGE) SecAllocate(AuthenticateMessageSize);
    if (AuthenticateMessage == NULL)
    {
        scRet = SEC_E_INSUFFICIENT_MEMORY;
        goto Cleanup;
    }

    Where = (PUCHAR) (AuthenticateMessage + 1);
    RtlCopyMemory(
        AuthenticateMessage->Signature,
        NTLMSSP_SIGNATURE,
        sizeof(NTLMSSP_SIGNATURE)
        );
    AuthenticateMessage->MessageType = NtLmAuthenticate;

    PutString(
        &AuthenticateMessage->LmChallengeResponse,
        &ChallengeResponse->CaseInsensitiveChallengeResponse,
        AuthenticateMessage,
        &Where
        );

    PutString(
        &AuthenticateMessage->NtChallengeResponse,
        &ChallengeResponse->CaseSensitiveChallengeResponse,
        AuthenticateMessage,
        &Where
        );

    PutString(
        &AuthenticateMessage->DomainName,
        (PSTRING) &DomainNameToUse,
        AuthenticateMessage,
        &Where
        );

    PutString(
        &AuthenticateMessage->UserName,
        (PSTRING) &UserNameToUse,
        AuthenticateMessage,
        &Where
        );

    //
    // BUGBUG: no workstation name to fill in.
    //

    AuthenticateMessage->Workstation.Length = 0;
    AuthenticateMessage->Workstation.MaximumLength = 0;
    AuthenticateMessage->Workstation.Buffer = NULL;


    //
    // Build the initialize response.
    //

    NtlmInitializeResponse = (PNTLM_INITIALIZE_RESPONSE) SecAllocate(sizeof(NTLM_INITIALIZE_RESPONSE));
    if (NtlmInitializeResponse == NULL)
    {
        scRet = SEC_E_INSUFFICIENT_MEMORY;
        goto Cleanup;
    }


    RtlCopyMemory(
        NtlmInitializeResponse->UserSessionKey,
        ChallengeResponse->UserSessionKey,
        MSV1_0_USER_SESSION_KEY_LENGTH
        );

    RtlCopyMemory(
        NtlmInitializeResponse->LanmanSessionKey,
        ChallengeResponse->LanmanSessionKey,
        MSV1_0_LANMAN_SESSION_KEY_LENGTH
        );

    //
    // Fill in the output buffers now.
    //

    AuthenticationToken->pvBuffer = AuthenticateMessage;
    AuthenticationToken->cbBuffer = AuthenticateMessageSize;
    InitializeResponseToken->pvBuffer = NtlmInitializeResponse;
    InitializeResponseToken->cbBuffer = sizeof(NTLM_INITIALIZE_RESPONSE);


    //
    // Make a local context for this
    //

    scRet = NtlmInitKernelContext(
                NtlmInitializeResponse->UserSessionKey,
                NtlmInitializeResponse->LanmanSessionKey,
                NULL,           // no token,
                phNewContext
                );

    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }
    scRet = SEC_E_OK;




Cleanup:

    if (ChallengeRequest != NULL)
    {
        ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &ChallengeRequest,
            &ChallengeRequestSize,
            MEM_RELEASE
            );
    }

    if (ChallengeResponse != NULL)
    {
        LsaFreeReturnBuffer( ChallengeResponse );
    }

    if (!NT_SUCCESS(scRet))
    {
        if (AuthenticateMessage != NULL)
        {
            SecFree(AuthenticateMessage);
        }
        if (NtlmInitializeResponse != NULL)
        {
            SecFree(NtlmInitializeResponse);
        }
    }
    return(scRet);
}
示例#14
0
BOOLEAN InjectDll(PINJECT_INFO InjectInfo)
{
	PEPROCESS Process;
	PETHREAD Thread;

	PKINJECT mem;
	ULONG size;

	PKAPC_STATE ApcState;
	PKAPC apc;

	PVOID buffer;
	PSYSTEM_PROCESS_INFO pSpi;

	LARGE_INTEGER delay;

	buffer=ExAllocatePool(NonPagedPool,1024*1024); // Allocate memory for the system information

	if(!buffer)
	{
		DbgPrint("Error: Unable to allocate memory for the process thread list.");
		return FALSE;
	}

	// Get the process thread list

	if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1024*1024,NULL)))
	{
		DbgPrint("Error: Unable to query process thread list.");
		
		ExFreePool(buffer);
		return FALSE;
	}

	pSpi=(PSYSTEM_PROCESS_INFO)buffer;

	// Find a target thread

	while(pSpi->NextEntryOffset)
	{
		if(pSpi->UniqueProcessId==InjectInfo->ProcessId)
		{
			DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread);
			break;
		}

		pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset);
	}

	// Reference the target process

	if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId,&Process)))
	{
		DbgPrint("Error: Unable to reference the target process.");
		
		ExFreePool(buffer);
		return FALSE;
	}

	DbgPrint("Process name: %s",PsGetProcessImageFileName(Process));
	DbgPrint("EPROCESS address: %#x",Process);

	// Reference the target thread

	if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread)))
	{
		DbgPrint("Error: Unable to reference the target thread.");
		ObDereferenceObject(Process); // Dereference the target process

		ExFreePool(buffer); // Free the allocated memory
		return FALSE;
	}

	DbgPrint("ETHREAD address: %#x",Thread);

	ExFreePool(buffer); // Free the allocated memory
	KeAttachProcess(Process); // Attach to target process's address space

	mem=NULL;
	size=4096;

	// Allocate memory in the target process

	if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE)))
	{
	    DbgPrint("Error: Unable to allocate memory in the target process.");
		KeDetachProcess(); // Detach from target process's address space

		ObDereferenceObject(Process); // Dereference the target process
		ObDereferenceObject(Thread); // Dereference the target thread

		return FALSE;
	}

	DbgPrint("Memory allocated at %#x",mem);

	mem->LdrLoadDll=LdrLoadDll; // Write the address of LdrLoadDll to target process
	wcscpy(mem->Buffer,InjectInfo->DllName); // Write the DLL name to target process

	RtlInitUnicodeString(&mem->DllName,mem->Buffer); // Initialize the UNICODE_STRING structure
	ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffset); // Calculate the address of the ApcState structure

	ApcState->UserApcPending=TRUE; // Force the target thread to execute APC

	memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)KernelRoutine-(ULONG)InjectDllApc); // Copy the APC code to target process
	DbgPrint("APC code address: %#x",(PKINJECT)(mem+1));

	apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); // Allocate the APC object

	if(!apc)
	{
		DbgPrint("Error: Unable to allocate the APC object.");
		size=0;

		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);  // Free the allocated memory
		KeDetachProcess(); // Detach from target process's address space

		ObDereferenceObject(Process); // Dereference the target process
		ObDereferenceObject(Thread); // Dereference the target thread

		return FALSE;
	}

	KeInitializeApc(apc,Thread,OriginalApcEnvironment,KernelRoutine,NULL,(PKNORMAL_ROUTINE)((PKINJECT)mem+1),UserMode,mem); // Initialize the APC
	DbgPrint("Inserting APC to target thread");

	// Insert the APC to the target thread

	if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT))
	{
		DbgPrint("Error: Unable to insert APC to target thread.");
		size=0;
		
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory
		KeDetachProcess(); // Detach from target process's address space

		ObDereferenceObject(Process); // Dereference the target process
		ObDereferenceObject(Thread); // Dereference the target thread

		ExFreePool(apc); // Free the APC object
		return FALSE;
	}

	delay.QuadPart=-100*10000;

	while(!mem->Executed)
	{
		KeDelayExecutionThread(KernelMode,FALSE,&delay); // Wait for the injection to complete
	}

	if(!mem->DllBase)
	{
		DbgPrint("Error: Unable to inject DLL into target process.");
		size=0;

		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);
		KeDetachProcess();

		ObDereferenceObject(Process);
		ObDereferenceObject(Thread);
		
		return FALSE;
	}

	DbgPrint("DLL injected at %#x",mem->DllBase);
	size=0;

	ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); // Free the allocated memory
	KeDetachProcess(); // Detach from target process's address space

	ObDereferenceObject(Process); // Dereference the target process
	ObDereferenceObject(Thread);  // Dereference the target thread

	return TRUE;
}
示例#15
0
NTSTATUS
VdmpInitialize(
    PVDMICAUSERDATA pIcaUserData
    )

/*++

Routine Description:

    Initialize the address space of a VDM.

Arguments:

    None,

Return Value:

    NTSTATUS.

--*/

{
    NTSTATUS Status, StatusCopy;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING SectionName;
    UNICODE_STRING WorkString;
    ULONG ViewSize;
    LARGE_INTEGER ViewBase;
    PVOID BaseAddress;
    PVOID destination;
    HANDLE SectionHandle, RegistryHandle;
    PEPROCESS Process;
    ULONG ResultLength;
    ULONG Index;
    PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
    PKEY_VALUE_FULL_INFORMATION KeyValueBuffer;
    PCM_ROM_BLOCK BiosBlock;
    ULONG LastMappedAddress;
    PVDM_PROCESS_OBJECTS pVdmObjects = NULL;
    USHORT PagedQuotaCharged = 0;
    USHORT NonPagedQuotaCharged = 0;
    HANDLE hThread;
    PVDM_TIB VdmTib;


    PAGED_CODE();

    Status = VdmpGetVdmTib(&VdmTib, VDMTIB_PROBE); // take from user mode and probe

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

    if ((KeI386MachineType & MACHINE_TYPE_PC_9800_COMPATIBLE) == 0) {

        //
        // This is PC/AT (and FMR in Japan) VDM.
        //

        RtlInitUnicodeString(
            &SectionName,
            L"\\Device\\PhysicalMemory"
            );

        InitializeObjectAttributes(
            &ObjectAttributes,
            &SectionName,
            OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
            (HANDLE) NULL,
            (PSECURITY_DESCRIPTOR) NULL
            );

        Status = ZwOpenSection(
            &SectionHandle,
            SECTION_ALL_ACCESS,
            &ObjectAttributes
            );

        if (!NT_SUCCESS(Status)) {

            return Status;

        }

        //
        // Copy the first page of memory into the VDM's address space
        //

        BaseAddress = 0;
        destination = 0;
        ViewSize = 0x1000;
        ViewBase.LowPart = 0;
        ViewBase.HighPart = 0;

        Status = ZwMapViewOfSection(
            SectionHandle,
            NtCurrentProcess(),
            &BaseAddress,
            0,
            ViewSize,
            &ViewBase,
            &ViewSize,
            ViewUnmap,
            0,
            PAGE_READWRITE
            );

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

        // problem with this statement below --
        // it could be a non-vdm process and copying memory to address 0
        // should be guarded against

        StatusCopy = STATUS_SUCCESS;
        try {
            RtlMoveMemory(
               destination,
               BaseAddress,
               ViewSize
               );
        }
        except(ExSystemExceptionFilter()) {
           StatusCopy = GetExceptionCode();
        }


        Status = ZwUnmapViewOfSection(
            NtCurrentProcess(),
            BaseAddress
            );

        if (!NT_SUCCESS(Status) || !NT_SUCCESS(StatusCopy)) {
           ZwClose(SectionHandle);
           return (NT_SUCCESS(Status) ? StatusCopy : Status);
        }

        //
        // Map Rom into address space
        //

        BaseAddress = (PVOID) 0x000C0000;
        ViewSize = 0x40000;
        ViewBase.LowPart = 0x000C0000;
        ViewBase.HighPart = 0;


        //
        // First unmap the reserved memory.  This must be done here to prevent
        // the virtual memory in question from being consumed by some other
        // alloc vm call.
        //

        Status = ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &BaseAddress,
            &ViewSize,
            MEM_RELEASE
            );

        // N.B.  This should probably take into account the fact that there are
        // a handfull of error conditions that are ok.  (such as no memory to
        // release.)

        if (!NT_SUCCESS(Status)) {
            ZwClose(SectionHandle);
            return Status;

        }

        //
        // Set up and open KeyPath
        //

        InitializeObjectAttributes(
            &ObjectAttributes,
            &CmRegistryMachineHardwareDescriptionSystemName,
            OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
            (HANDLE)NULL,
            NULL
            );

        Status = ZwOpenKey(
            &RegistryHandle,
            KEY_READ,
            &ObjectAttributes
            );

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

        //
        // Allocate space for the data
        //

        KeyValueBuffer = ExAllocatePoolWithTag(
            PagedPool,
            KEY_VALUE_BUFFER_SIZE,
            ' MDV'
            );

        if (KeyValueBuffer == NULL) {
            ZwClose(RegistryHandle);
            ZwClose(SectionHandle);
            return STATUS_NO_MEMORY;
        }

        //
        // Get the data for the rom information
        //

        RtlInitUnicodeString(
            &WorkString,
            L"Configuration Data"
            );

        Status = ZwQueryValueKey(
            RegistryHandle,
            &WorkString,
            KeyValueFullInformation,
            KeyValueBuffer,
            KEY_VALUE_BUFFER_SIZE,
            &ResultLength
            );

        if (!NT_SUCCESS(Status)) {
            ZwClose(RegistryHandle);
            ExFreePool(KeyValueBuffer);
            ZwClose(SectionHandle);
            return Status;
        }

        ResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)
            ((PUCHAR) KeyValueBuffer + KeyValueBuffer->DataOffset);

        if ((KeyValueBuffer->DataLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) ||
            (ResourceDescriptor->PartialResourceList.Count < 2)
        ) {
            ZwClose(RegistryHandle);
            ExFreePool(KeyValueBuffer);
            ZwClose(SectionHandle);
            // No rom blocks.
            return STATUS_SUCCESS;
        }

        PartialResourceDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
            ((PUCHAR)ResourceDescriptor +
            sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
            ResourceDescriptor->PartialResourceList.PartialDescriptors[0]
                .u.DeviceSpecificData.DataSize);


        if (KeyValueBuffer->DataLength < ((PUCHAR)PartialResourceDescriptor -
            (PUCHAR)ResourceDescriptor + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)
            + sizeof(CM_ROM_BLOCK))
        ) {
            ZwClose(RegistryHandle);
            ExFreePool(KeyValueBuffer);
            ZwClose(SectionHandle);
            return STATUS_ILL_FORMED_SERVICE_ENTRY;
        }


        BiosBlock = (PCM_ROM_BLOCK)((PUCHAR)PartialResourceDescriptor +
            sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));

        Index = PartialResourceDescriptor->u.DeviceSpecificData.DataSize /
            sizeof(CM_ROM_BLOCK);

        //
        // N.B.  Rom blocks begin on 2K (not necessarily page) boundaries
        //       They end on 512 byte boundaries.  This means that we have
        //       to keep track of the last page mapped, and round the next
        //       Rom block up to the next page boundary if necessary.
        //

        LastMappedAddress = 0xC0000;

        while (Index) {
    #if 0
            DbgPrint(
                "Bios Block, PhysAddr = %lx, size = %lx\n",
                BiosBlock->Address,
                BiosBlock->Size
                );
    #endif
            if ((Index > 1) &&
                ((BiosBlock->Address + BiosBlock->Size) == BiosBlock[1].Address)
            ) {
                //
                // Coalesce adjacent blocks
                //
                BiosBlock[1].Address = BiosBlock[0].Address;
                BiosBlock[1].Size += BiosBlock[0].Size;
                Index--;
                BiosBlock++;
                continue;
            }

            BaseAddress = (PVOID)(BiosBlock->Address);
            ViewSize = BiosBlock->Size;

            if ((ULONG)BaseAddress < LastMappedAddress) {
                if (ViewSize > (LastMappedAddress - (ULONG)BaseAddress)) {
                    ViewSize = ViewSize - (LastMappedAddress - (ULONG)BaseAddress);
                    BaseAddress = (PVOID)LastMappedAddress;
                } else {
                    ViewSize = 0;
                }
            }

            ViewBase.LowPart = (ULONG)BaseAddress;

            if (ViewSize > 0) {

                Status = ZwMapViewOfSection(
                    SectionHandle,
                    NtCurrentProcess(),
                    &BaseAddress,
                    0,
                    ViewSize,
                    &ViewBase,
                    &ViewSize,
                    ViewUnmap,
                    MEM_DOS_LIM,
                    PAGE_READWRITE
                    );

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

                LastMappedAddress = (ULONG)BaseAddress + ViewSize;
            }

            Index--;
            BiosBlock++;
        }

        //
        // Free up the handles
        //

        ZwClose(SectionHandle);
        ZwClose(RegistryHandle);
        ExFreePool(KeyValueBuffer);

    } else {
示例#16
0
BOOLEAN InjectDll(PINJECT_INFO InjectInfo)
{
	PEPROCESS Process;
	PETHREAD Thread;
	PKINJECT mem;
    ULONG size;
	PKAPC_STATE ApcState;
	PKAPC apc;
	PVOID buffer;
	PSYSTEM_PROCESS_INFO pSpi;
	LARGE_INTEGER delay;
	buffer=ExAllocatePool(NonPagedPool,1024*1024); 
	if(!buffer)
	{
		DbgPrint("Error: Unable to allocate memory for the process thread list.");
		return FALSE;
	}

	//5	SystemProcessInformation,
	if(!NT_SUCCESS(ZwQuerySystemInformation(5,buffer,1024*1024,NULL)))
	{
		DbgPrint("Error: Unable to query process thread list.");

		ExFreePool(buffer);
		return FALSE;
	}

	pSpi=(PSYSTEM_PROCESS_INFO)buffer;

	//找到目标进程
	while(pSpi->NextEntryOffset)
	{
		if(pSpi->UniqueProcessId==InjectInfo->ProcessId)
		{
			DbgPrint("Target thread found. TID: %d",pSpi->Threads[0].ClientId.UniqueThread);
			break;
		}

		pSpi=(PSYSTEM_PROCESS_INFO)((PUCHAR)pSpi+pSpi->NextEntryOffset);
	}

	// 引用目标进程EProcess,
	if(!NT_SUCCESS(PsLookupProcessByProcessId(InjectInfo->ProcessId,&Process)))
	{
		DbgPrint("Error: Unable to reference the target process.");
		ExFreePool(buffer);
		return FALSE;
	}

	DbgPrint("Process name: %s",PsGetProcessImageFileName(Process));
	DbgPrint("EPROCESS address: %#x",Process);

	//目标进程主线程
	if(!NT_SUCCESS(PsLookupThreadByThreadId(pSpi->Threads[0].ClientId.UniqueThread,&Thread)))
	{
		DbgPrint("Error: Unable to reference the target thread.");
		ObDereferenceObject(Process); 
		ExFreePool(buffer); 
		return FALSE;
	}

	DbgPrint("ETHREAD address: %#x",Thread);

	ExFreePool(buffer); 
	//切入到目标进程
	KeAttachProcess(Process); 

	mem=NULL;
	size=4096;

	//在目标进程申请内存
	if(!NT_SUCCESS(ZwAllocateVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,0,&size,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE)))
	{
		DbgPrint("Error: Unable to allocate memory in the target process.");
		KeDetachProcess(); 

		ObDereferenceObject(Process);
		ObDereferenceObject(Thread); 
		return FALSE;
	}

	DbgPrint("Memory allocated at %#x",mem);
	mem->LdrLoadDll=LdrLoadDll; 
	wcscpy(mem->Buffer,InjectInfo->DllName); 
	RtlInitUnicodeString(&mem->DllName,mem->Buffer); 
	ApcState=(PKAPC_STATE)((PUCHAR)Thread+ApcStateOffset); 
	ApcState->UserApcPending=TRUE;   
	memcpy((PKINJECT)(mem+1),InjectDllApc,(ULONG)KernelRoutine-(ULONG)InjectDllApc); 
	DbgPrint("APC code address: %#x",(PKINJECT)(mem+1));

	//申请apc对象
	apc=(PKAPC)ExAllocatePool(NonPagedPool,sizeof(KAPC)); 

	if(!apc)
	{
		DbgPrint("Error: Unable to allocate the APC object.");
		size=0;
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);  
		KeDetachProcess();
		ObDereferenceObject(Process); 
		ObDereferenceObject(Thread); 
		return FALSE;
	}

	KeInitializeApc(apc,
		Thread,    //目标进程主线程
		OriginalApcEnvironment,   //目标apcz状态
		KernelRoutine,  //内核apc总入口
		NULL,       //Rundown Rounine=NULL
		(PKNORMAL_ROUTINE)((PKINJECT)mem+1),   //用户空间的总apc
		UserMode,   //插入到用户apc队列
		mem); // 自己的apc队列

	DbgPrint("Inserting APC to target thread");

	// 插入apc队列
	if(!KeInsertQueueApc(apc,NULL,NULL,IO_NO_INCREMENT))
	{
		DbgPrint("Error: Unable to insert APC to target thread.");
		size=0;
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); 
		KeDetachProcess(); 
		ObDereferenceObject(Process); 
		ObDereferenceObject(Thread); 
		ExFreePool(apc); 
		return FALSE;
	}

	delay.QuadPart=-100*10000;
	while(!mem->Executed)
	{
		KeDelayExecutionThread(KernelMode,FALSE,&delay);  //等待apc执行 
	}
	if(!mem->DllBase)
	{
		DbgPrint("Error: Unable to inject DLL into target process.");
		size=0;
		ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE);
		KeDetachProcess();
		ObDereferenceObject(Process);
		ObDereferenceObject(Thread);
		return FALSE;
	}

	DbgPrint("DLL injected at %#x",mem->DllBase);
	size=0;
	ZwFreeVirtualMemory(NtCurrentProcess(),(PVOID*)&mem,&size,MEM_RELEASE); 
	ObDereferenceObject(Process); 
	ObDereferenceObject(Thread); 
	return TRUE;
}
示例#17
0
// injects the function UserApcNormalRoutine() as a user mode APC
// into the process selected by Process Pid
NTSTATUS
InjectApc(
    HANDLE ProcessId,
    PVOID User32MessageBoxA )
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    HANDLE ProcessHandle = NULL;
    PEPROCESS ProcessObject = NULL;
    BOOLEAN Attached = FALSE;
    BOOLEAN Suspended = FALSE;
    PCONTEXT_DATA ContextData = NULL;
    PUCHAR AllocationBase = NULL;
    SIZE_T AllocationSize;
    ULONG ShellcodeSize;
    PUCHAR ShellcodeBase;
    KAPC_STATE ApcState;

    // get the size of the shell code that will be copied into user VAS
    ShellcodeSize = (ULONG)Getx64FunctionSize ( (PVOID)UserApcNormalRoutine );

    if ( ! ShellcodeSize ) {
        DPF(("%s!%s Getx64FunctionSize(UserApcNormalRoutine) FAIL\n", __MODULE__, __FUNCTION__ ));
        goto Exit;
    }

    // Step #1 : Obtain the EPROCESS pointer from ProcessId (PsLookupProcessByProcessId())
    // and store it in ProcessObject
    if (!NT_SUCCESS(Status = PsLookupProcessByProcessId(ProcessId, &ProcessObject)))
    {
        DbgPrint("ERROR PsLookupProcessByProcessId (%x)\n", Status);
        goto Exit;
    }

    // Step #2 : Suspend the target process (PsSuspendProcess())
    if (!NT_SUCCESS(Status = PsSuspendProcess(ProcessObject)))
    {
        DbgPrint("ERROR PsSuspendProcess (%x)\n", Status);
        goto Exit;
    }

    Suspended = TRUE;

    // Step #3 : Attach to the target process (KeStackAttachProcess())
    KeStackAttachProcess(ProcessObject, &ApcState);
    Attached = TRUE;

    AllocationSize = ShellcodeSize + sizeof ( CONTEXT_DATA ) ;

    // Step #4 : Allocate memory in the target process large enough
    // to hold the shellcode and CONTEXT_DATA (ZwAllocateVirtualMemory())
    // and store the result in AllocationBase
    if (!NT_SUCCESS(Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &AllocationBase, 0, &AllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)))
    {
        DbgPrint("ERROR ZwAllocateVirtualMemory (%x)\n", Status);
        goto Exit;
    }
    ProcessHandle = NULL;

    ShellcodeBase = AllocationBase;
    ContextData = (PCONTEXT_DATA)(AllocationBase + ShellcodeSize);

    // Step #5 : Copy the user mode APC code into the newly allocated 
    // memory (RtlCopyMemory()) i.e. @ ShellCodeBase
    RtlCopyMemory(ShellcodeBase, (PVOID)UserApcNormalRoutine, ShellcodeSize);

    //setup the context structure with data that will be required by the APC routine
    ContextData->ShellCodeBase = ShellcodeBase;
    ContextData->ShellCodeSize = ShellcodeSize;
    strncpy (  ContextData->Text, "Hello from Kernel", STRING_SIZE );
    strncpy (  ContextData->Caption, "P0wned", STRING_SIZE );
    //user32.dll base + offset of MessageBoxA;
    ContextData->MessageBox = (MESSAGEBOXA)User32MessageBoxA; 

    // queue the APC
    Status = RequestApc(
       ProcessId,
       ShellcodeBase,
       ContextData );

    if ( ! NT_SUCCESS( Status ) ) {
        DPF(("%s!%s RequestApc() FAIL=%08x\n", __MODULE__, __FUNCTION__,
             Status ));
        goto Exit;
    }


Exit :
    // in case of an error free the memory that was allocated
    if ( ! NT_SUCCESS ( Status ) ) {

        if ( AllocationBase ) {
            AllocationSize = 0;

            // Step #6 : Free the virtual memory that was allocated in the 
            // target process (ZwFreeVirtualMemory())
            ZwFreeVirtualMemory(ProcessHandle, &AllocationBase, &AllocationSize, MEM_RELEASE | MEM_DECOMMIT);
        }
    }


    if ( Attached ) {
        // Step #7 : Detach from the target process (KeUnstackDetachProcess())
        KeUnstackDetachProcess(&ApcState);
    }

    if ( Suspended ) {
        // Step #8 : Resume the target process (PsResumeProcess())
        PsResumeProcess(ProcessObject);
    }

    if ( ProcessObject ) {
        // Step #9 : Dereference the process object (ObDereferenceObject())
        ObDereferenceObject(ProcessObject);
    }

    return Status;
}
示例#18
0
NTSTATUS VirtualFree(HANDLE hProcess, PVOID VirtualAddress) {
	SIZE_T RegionSize = 0;
	return ZwFreeVirtualMemory(hProcess, &VirtualAddress, &RegionSize, MEM_RELEASE);
}
示例#19
0
文件: int10.c 项目: GYGit/reactos
NTSTATUS
NTAPI
IntInitializeVideoAddressSpace(VOID)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
    NTSTATUS Status;
    HANDLE PhysMemHandle;
    PVOID BaseAddress;
    LARGE_INTEGER Offset;
    SIZE_T ViewSize;
    CHAR IVTAndBda[1024+256];

    /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
    BaseAddress = 0;
    ViewSize = 1024 * 1024;
    Status = ZwFreeVirtualMemory(NtCurrentProcess(),
                                 &BaseAddress,
                                 &ViewSize,
                                 MEM_RELEASE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
        return 0;
    }

    /* Open the physical memory section */
    InitializeObjectAttributes(&ObjectAttributes,
                               &PhysMemName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = ZwOpenSection(&PhysMemHandle,
                           SECTION_ALL_ACCESS,
                           &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
        return Status;
    }

    /* Map the BIOS and device registers into the address space */
    Offset.QuadPart = 0xa0000;
    ViewSize = 0x100000 - 0xa0000;
    BaseAddress = (PVOID)0xa0000;
    Status = ZwMapViewOfSection(PhysMemHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                ViewSize,
                                &Offset,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_EXECUTE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't map physical memory (%x)\n", Status);
        ZwClose(PhysMemHandle);
        return Status;
    }

    /* Close physical memory section handle */
    ZwClose(PhysMemHandle);

    if (BaseAddress != (PVOID)0xa0000)
    {
        DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
                BaseAddress);
        return STATUS_UNSUCCESSFUL;
    }

    /* Allocate some low memory to use for the non-BIOS
     * parts of the v86 mode address space
     */
    BaseAddress = (PVOID)0x1;
    ViewSize = 0xa0000 - 0x1000;
    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_RESERVE | MEM_COMMIT,
                                     PAGE_EXECUTE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
        return Status;
    }
    if (BaseAddress != (PVOID)0x0)
    {
        DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
                BaseAddress);
        return 0;
    }

    /* Get the real mode IVT and BDA from the kernel */
    Status = NtVdmControl(VdmInitialize, IVTAndBda);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtVdmControl failed (status %x)\n", Status);
        return Status;
    }

    /* Return success */
    return STATUS_SUCCESS;
}
示例#20
0
文件: stubs.c 项目: mingpen/OpenNT
SECURITY_STATUS SEC_ENTRY
GetSecurityUserInfo(
    IN PLUID pLogonId,
    IN ULONG fFlags,
    OUT PSecurityUserData * ppUserInfo)
{
    NTSTATUS Status, FinalStatus;
    PVOID GetInfoBuffer = NULL;
    PVOID GetInfoResponseBuffer = NULL;
    PMSV1_0_GETUSERINFO_REQUEST GetInfoRequest;
    PMSV1_0_GETUSERINFO_RESPONSE GetInfoResponse;
    ULONG ResponseSize;
    ULONG RegionSize = sizeof(MSV1_0_GETUSERINFO_REQUEST);
    PSecurityUserData UserInfo = NULL;
    ULONG UserInfoSize;
    PUCHAR Where;
    SECURITY_STATUS scRet;
    PClient Client = NULL;


    scRet = IsOkayToExec(&Client);
    if (!NT_SUCCESS(scRet))
    {
        return(scRet);
    }

    //
    //  Allocate virtual memory for the response buffer.
    //

    Status = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &GetInfoBuffer, 0L,
                &RegionSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );

    GetInfoRequest = GetInfoBuffer;

    if (!NT_SUCCESS(Status)) {
        scRet = Status;
        goto Cleanup;
    }

    GetInfoRequest->MessageType = MsV1_0GetUserInfo;

    RtlCopyLuid(&GetInfoRequest->LogonId, pLogonId);

    Status = LsaCallAuthenticationPackage(
                Client->hPort,
                PackageId,
                GetInfoRequest,
                RegionSize,
                &GetInfoResponseBuffer,
                &ResponseSize,
                &FinalStatus);

    GetInfoResponse = GetInfoResponseBuffer;

    if (!NT_SUCCESS(Status)) {
        GetInfoResponseBuffer = NULL;
        scRet = Status;
        goto Cleanup;
    }


    if (!NT_SUCCESS(FinalStatus)) {
        scRet = FinalStatus;
        goto Cleanup;
    }

    ASSERT(GetInfoResponse->MessageType == MsV1_0GetUserInfo);

    //
    // Build a SecurityUserData
    //

    UserInfoSize = sizeof(SecurityUserData) +
                   GetInfoResponse->UserName.MaximumLength +
                   GetInfoResponse->LogonDomainName.MaximumLength +
                   GetInfoResponse->LogonServer.MaximumLength +
                   RtlLengthSid(GetInfoResponse->UserSid);



    scRet = ZwAllocateVirtualMemory(
                NtCurrentProcess(),
                &UserInfo,
                0L,
                &UserInfoSize,
                MEM_COMMIT,
                PAGE_READWRITE
                );
    if (!NT_SUCCESS(scRet))
    {
        goto Cleanup;
    }

    //
    // Pack in the SID first, to respectalignment boundaries.
    //

    Where = (PUCHAR) (UserInfo + 1);
    UserInfo->pSid = (PSID) (Where);
    RtlCopySid(
        UserInfoSize,
        Where,
        GetInfoResponse->UserSid
        );
    Where += RtlLengthSid(Where);

    //
    // Pack in the strings
    //

    PutString(
        (PSTRING) &UserInfo->UserName,
        (PSTRING) &GetInfoResponse->UserName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &UserInfo->LogonDomainName,
        (PSTRING) &GetInfoResponse->LogonDomainName,
        0,
        &Where
        );

    PutString(
        (PSTRING) &UserInfo->LogonServer,
        (PSTRING) &GetInfoResponse->LogonServer,
        0,
        &Where
        );

    *ppUserInfo = UserInfo;
    UserInfo = NULL;
    scRet = STATUS_SUCCESS;

Cleanup:
    if (GetInfoRequest != NULL)
    {
        ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &GetInfoRequest,
            &RegionSize,
            MEM_RELEASE
            );

    }

    if (UserInfo != NULL)
    {
        FreeContextBuffer(UserInfo);
    }

    if (GetInfoResponseBuffer != NULL)
    {
        LsaFreeReturnBuffer(GetInfoResponseBuffer);
    }

    return(scRet);
}