Пример #1
0
VOID InjectDllIntoProcess(PWCHAR ProcessName)
{
	HANDLE ThreadId;
	HANDLE ProcessId = GetPidAndTidByName(ProcessName, &ThreadId);
	if (ProcessId)
	{
		PETHREAD Thread;
		NTSTATUS St = PsLookupThreadByThreadId(ThreadId, &Thread);
		if (NT_SUCCESS(St))
		{
			PKAPC pkaApc = (PKAPC)ExAllocatePool(NonPagedPool, sizeof(KAPC));
			if(pkaApc)
			{
				KeInitializeApc(pkaApc, (PKTHREAD)Thread, 0, APCInjectRoutine, 0, 0, KernelMode, 0);
				KeInsertQueueApc(pkaApc, 0, 0, IO_NO_INCREMENT);
			}

			ObDereferenceObject(Thread);
		}
	}
	else
	{
		DbgPrint("GetPidAndTidByName error\n");
	}
}
Пример #2
0
/* 获取ShadowSSDT表地址偏移 */
ULONG GetSSDTShadowTableAddr()
{
	ULONG		ktrdCid;
	NTSTATUS	status;
	ULONG		ethread;
	ULONG		shadowTableAddr=0;
	ULONG		i=0;

	/* 尝试枚举系统线程获取 KTHREAD */
	for( ktrdCid = 8; ktrdCid < 32768; ktrdCid += 4)
	{
		status = PsLookupThreadByThreadId( (HANDLE)ktrdCid, &(PETHREAD)ethread );
		if( NT_SUCCESS(status) )
		{	// 
			if( *(PULONG)( ethread + 0x0e0 )  !=  (ULONG)KeServiceDescriptorTable )
			{
				/* 获取 KTHREAD.ServiceTable 指针值 */
				shadowTableAddr =  *(PULONG)( ethread + 0x0e0 );
				break;
			}
		}
	}

	return shadowTableAddr;
}
Пример #3
0
/*
 * UserGetKeyboardLayout
 *
 * Returns hkl of given thread keyboard layout
 */
HKL FASTCALL
UserGetKeyboardLayout(
    DWORD dwThreadId)
{
    NTSTATUS Status;
    PETHREAD pThread;
    PTHREADINFO pti;
    PKL pKl;
    HKL hKl;

    if (!dwThreadId)
    {
        pti = PsGetCurrentThreadWin32Thread();
        pKl = pti->KeyboardLayout;
        return pKl ? pKl->hkl : NULL;
    }

    Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)dwThreadId, &pThread);
    if (!NT_SUCCESS(Status))
    {
        EngSetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    pti = PsGetThreadWin32Thread(pThread);
    pKl = pti->KeyboardLayout;
    hKl = pKl ? pKl->hkl : NULL;;
    ObDereferenceObject(pThread);
    return hKl;
}
Пример #4
0
ULONG GetSwapContextAddr()
{
	PETHREAD pEThread = NULL;
	NTSTATUS Status = STATUS_SUCCESS;
	Status = PsLookupThreadByThreadId( 8, &pEThread );
	if( !NT_SUCCESS(Status) )
		return 0;
	if( MmIsAddressValid( (PULONG)((ULONG)pEThread+0x28) ) )
	{
		ULONG pCurrentStack = *(PULONG)((ULONG)pEThread + 0x28);
		return *(PULONG)(pCurrentStack+0x8) - 5;
	}
	else
		return 0;
}
Пример #5
0
NTSTATUS HwlTerminateProcess64(PEPROCESS Process)
{
	//get pspterminatethreadbypointer
	ULONG32 callcode=0;
	ULONG64 AddressOfPspTTBP=0, AddressOfPsTST=0, i=0;
	PETHREAD Thread=NULL;
	PEPROCESS tProcess=NULL;
	NTSTATUS status=0;
	if(PspTerminateThreadByPointer==NULL)
	{
		AddressOfPsTST=(ULONG64)GetFunctionAddr(L"PsTerminateSystemThread");
		if(AddressOfPsTST==0)
			return STATUS_UNSUCCESSFUL;
		for(i=1;i<0xff;i++)
		{
			if(MmIsAddressValid((PVOID)(AddressOfPsTST+i))!=FALSE)
			{
				if(*(BYTE *)(AddressOfPsTST+i)==0x01 && *(BYTE *)(AddressOfPsTST+i+1)==0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
				{
					RtlMoveMemory(&callcode,(PVOID)(AddressOfPsTST+i+2),4);
					AddressOfPspTTBP=(ULONG64)callcode + 5 + AddressOfPsTST+i+1;
				}
			}
		}
		PspTerminateThreadByPointer=(PSPTERMINATETHREADBYPOINTER)AddressOfPspTTBP;
	}
	//loop call pspterminatethreadbypointer
	for(i=4;i<0x40000;i+=4)
	{
		status=PsLookupThreadByThreadId((HANDLE)i, &Thread);
		if(NT_SUCCESS(status))
		{
			tProcess=IoThreadToProcess(Thread);
			if(tProcess==Process)
				PspTerminateThreadByPointer(Thread,0,1);
			ObDereferenceObject(Thread);
		}
	}
	//return status
	return STATUS_SUCCESS;
}
Пример #6
0
    __checkReturn
    bool Initialize()
    {
        if (!m_stack.Begin())
        {
            if (!Id && NT_SUCCESS(PsLookupThreadByThreadId(m_threadId, &Id)))
            {
                m_vadScanner.Init(Id);

                CPassiveLvl irql;
                void* teb;
                if (teb = GetWow64Teb(Id))
                    ResolveThreadLimits<NT_TIB32>(reinterpret_cast<NT_TIB32*>(teb));
                else if (teb = PsGetThreadTeb(Id))
                    ResolveThreadLimits<NT_TIB>(reinterpret_cast<NT_TIB*>(teb));

                //DbgPrint("\nstack boundaries : %p %p\n", m_stack.Begin(), m_stack.End());
                return true;
            }
        }
        return false;
    }
Пример #7
0
/*
 * Test the Thread to verify and validate it. Hard to the core tests are required.
 */
PTHREADINFO
FASTCALL
IntTID2PTI(HANDLE id)
{
   NTSTATUS Status;
   PETHREAD Thread;
   PTHREADINFO pti;
   Status = PsLookupThreadByThreadId(id, &Thread);
   if (!NT_SUCCESS(Status))
   {
      return NULL;
   }
   if (PsIsThreadTerminating(Thread))
   {
      ObDereferenceObject(Thread);
      return NULL;
   }
   pti = PsGetThreadWin32Thread(Thread);
   if (!pti)
   {
      ObDereferenceObject(Thread);
      return NULL;
   }
   // Validate and verify!
   _SEH2_TRY
   {
      if (pti->TIF_flags & TIF_INCLEANUP) pti = NULL;
      if (pti && !(pti->TIF_flags & TIF_GUITHREADINITIALIZED)) pti = NULL;
      if (PsGetThreadId(Thread) != id) pti = NULL;
   }
   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
   {
      pti = NULL;
   }
   _SEH2_END
   ObDereferenceObject(Thread);
   return pti;
}
Пример #8
0
static VOID JpkfagsOnCreateThread(
    __in HANDLE ProcessId,
    __in HANDLE ThreadId,
    __in BOOLEAN Create
    )
{
	PETHREAD ThreadObject;

	UNREFERENCED_PARAMETER( ProcessId );

	if ( ! Create )
	{
		//
		// We are obly interested in thread terminations.
		//
		// Obtain ETHREAD from ThreadId.
		//
		if ( NT_SUCCESS( PsLookupThreadByThreadId( ThreadId, &ThreadObject ) ) )
		{
			JpkfagpCleanupThread( ThreadObject );
			ObDereferenceObject( ThreadObject );
		}
	}
}
Пример #9
0
BOOL
APIENTRY
NtUserGetGUIThreadInfo(
   DWORD idThread, /* If NULL use foreground thread */
   LPGUITHREADINFO lpgui)
{
   NTSTATUS Status;
   PTHRDCARETINFO CaretInfo;
   GUITHREADINFO SafeGui;
   PDESKTOP Desktop;
   PUSER_MESSAGE_QUEUE MsgQueue;
   PTHREADINFO W32Thread;
   PETHREAD Thread = NULL;

   DECLARE_RETURN(BOOLEAN);

   TRACE("Enter NtUserGetGUIThreadInfo\n");
   UserEnterShared();

   Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   if(SafeGui.cbSize != sizeof(GUITHREADINFO))
   {
      EngSetLastError(ERROR_INVALID_PARAMETER);
      RETURN( FALSE);
   }

   if (idThread)
   {
      Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread);
      if(!NT_SUCCESS(Status))
      {
         EngSetLastError(ERROR_ACCESS_DENIED);
         RETURN( FALSE);
      }
      W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread;
      Desktop = W32Thread->rpdesk;

      if (!Thread || !Desktop )
      {
        if(Thread)
           ObDereferenceObject(Thread);
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
      
      if ( W32Thread->MessageQueue )
        MsgQueue = W32Thread->MessageQueue;
      else
      {
        if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue;
      }
   }
   else
   {  /* Get the foreground thread */
      /* FIXME: Handle NULL queue properly? */
      MsgQueue = IntGetFocusMessageQueue();
      if(!MsgQueue)
      {
        EngSetLastError(ERROR_ACCESS_DENIED);
        RETURN( FALSE);
      }
   }

   CaretInfo = &MsgQueue->CaretInfo;

   SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
/*
   if (W32Thread->pMenuState->pGlobalPopupMenu)
   {
       SafeGui.flags |= GUI_INMENUMODE;

       if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify)
          SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify);

       if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar)
       {
          if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu)
          {
             SafeGui.flags |= GUI_SYSTEMMENUMODE;
          }
       }
       else
       {
          SafeGui.flags |= GUI_POPUPMENUMODE;
       }
   }
 */
   SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;

   if (MsgQueue->MenuOwner)
      SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;

   if (MsgQueue->MoveSize)
      SafeGui.flags |= GUI_INMOVESIZE;

   /* FIXME: Add flag GUI_16BITTASK */

   SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0;
   SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0;
   SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0;
   SafeGui.hwndMoveSize = MsgQueue->MoveSize;
   SafeGui.hwndCaret = CaretInfo->hWnd;

   SafeGui.rcCaret.left = CaretInfo->Pos.x;
   SafeGui.rcCaret.top = CaretInfo->Pos.y;
   SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
   SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;

   if (idThread)
      ObDereferenceObject(Thread);

   Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   RETURN( TRUE);

CLEANUP:
   TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Пример #10
0
/// <summary>
/// Find first thread of the target process
/// </summary>
/// <param name="pid">Target PID.</param>
/// <param name="ppThread">Found thread. Thread object reference count is increased by 1</param>
/// <returns>Status code</returns>
NTSTATUS BBLookupProcessThread( IN HANDLE pid, OUT PETHREAD* ppThread )
{
    NTSTATUS status = STATUS_SUCCESS;
    PVOID pBuf = ExAllocatePoolWithTag( NonPagedPool, 1024 * 1024, BB_POOL_TAG );
    PSYSTEM_PROCESS_INFO pInfo = (PSYSTEM_PROCESS_INFO)pBuf;

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

    if (!pInfo)
    {
        DPRINT( "BlackBone: %s: Failed to allocate memory for process list\n", __FUNCTION__ );
        return STATUS_NO_MEMORY;
    }

    // Get the process thread list
    status = ZwQuerySystemInformation( SystemProcessInformation, pInfo, 1024 * 1024, NULL );
    if (!NT_SUCCESS( status ))
    {
        ExFreePoolWithTag( pBuf, BB_POOL_TAG );
        return status;
    }

    // Find target thread
    if (NT_SUCCESS( status ))
    {
        status = STATUS_NOT_FOUND;
        for (;;)
        {
            if (pInfo->UniqueProcessId == pid)
            {
                status = STATUS_SUCCESS;
                break;
            }
            else if (pInfo->NextEntryOffset)
                pInfo = (PSYSTEM_PROCESS_INFO)((PUCHAR)pInfo + pInfo->NextEntryOffset);
            else
                break;
        }
    }

    // Reference target thread
    if (NT_SUCCESS( status ))
    {
        status = STATUS_NOT_FOUND;

        // Get first thread
        for (ULONG i = 0; i < pInfo->NumberOfThreads; i++)
        {
            // Skip current thread
            if (/*pInfo->Threads[i].WaitReason == Suspended ||
                 pInfo->Threads[i].ThreadState == 5 ||*/
                 pInfo->Threads[i].ClientId.UniqueThread == PsGetCurrentThread())
            {
                continue;
            }

            status = PsLookupThreadByThreadId( pInfo->Threads[i].ClientId.UniqueThread, ppThread );
            break;
        }
    }
    else
        DPRINT( "BlackBone: %s: Failed to locate process\n", __FUNCTION__ );

    if (pBuf)
        ExFreePoolWithTag( pBuf, BB_POOL_TAG );

    return status;
}
Пример #11
0
NTSTATUS DispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){
    NTSTATUS  ntStatus = STATUS_UNSUCCESSFUL;
    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
    switch(irpStack->Parameters.DeviceIoControl.IoControlCode){
        case IOCTL_GET_HOOKS:
            {
                unsigned int i,j;
                PETHREAD pethread;
                PTHREADINFO ptiCurrent;
                PDESKTOPINFO pdesktopinfo;
                PPROCESSINFO ppi;
                PARAMS_GET_HOOKS *params;
                DATA_GET_HOOKS *data;
                PHOOK* aphkStart;

                if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DATA_GET_HOOKS)) {
                    ntStatus = STATUS_BUFFER_TOO_SMALL;
                    break;
                }
                if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PARAMS_GET_HOOKS)) {
                    ntStatus = STATUS_BUFFER_TOO_SMALL;
                    break;
                }

                params = ExAllocatePoolWithTag(PagedPool, sizeof(PARAMS_GET_HOOKS), 'tdkh');
                if (!params) {
                    break;
                }

                memcpy(params, Irp->AssociatedIrp.SystemBuffer, sizeof(PARAMS_GET_HOOKS));

                pethread = PsGetCurrentThread();
                ptiCurrent = PsGetThreadWin32Thread(pethread);
                if (g_win7) {
                    pdesktopinfo = (PDESKTOPINFO)((unsigned int*)ptiCurrent)[0xCC/4];
                    ppi = (PPROCESSINFO)&((char*)ptiCurrent)[0xB8];
                    aphkStart = (PHOOK*)&((char*)pdesktopinfo)[0x10];
                } else {
                    pdesktopinfo = ptiCurrent->pDeskInfo;
                    ppi = ptiCurrent->ppi;
                    aphkStart = pdesktopinfo->aphkStart;
                }

                data = (DATA_GET_HOOKS*)Irp->AssociatedIrp.SystemBuffer;
                memset(data, 0, sizeof(DATA_GET_HOOKS));

                retrieve_hooks(aphkStart, ppi, data->global_hook);

                data->threads=0;
                j=0;
                for (i=0;i<params->threads;i++) {
                    if (PsLookupThreadByThreadId((HANDLE)params->thread_id[i], &pethread) != STATUS_SUCCESS) {
                        continue;
                    }
                    if (g_win7) {
                        if (PsGetThreadSessionId(pethread) != PsGetCurrentProcessSessionId()) {
                            ObDereferenceObject(pethread);
                            continue;
                        }
                    }
                    ptiCurrent = PsGetThreadWin32Thread(pethread);
                    if (ptiCurrent) {
                        if (g_win7) {
                            aphkStart = (PHOOK*)&((char*)ptiCurrent)[0x198];
                            ppi = (PPROCESSINFO)&((char*)ptiCurrent)[0xB8];
                        } else {
                            aphkStart = (PHOOK*)&((char*)ptiCurrent)[0xf4];
                            ppi = ptiCurrent->ppi;
                        }
                        if (has_hooks(aphkStart)) {
                            data->threads++;
                            if (j<MAX_OUT_THREADS) {
                                retrieve_hooks(aphkStart, ppi, data->thread[j].hook);
                                data->thread[j].thread_id = params->thread_id[i];
                                j++;
                            }
                        }
                    }
                    ObDereferenceObject(pethread);
                }

                ExFreePool(params);

                ntStatus = STATUS_SUCCESS;
                break;
            }
        case IOCTL_HMOD_TBL_INX_TO_MOD_NAME:
            {
                DATA_HMOD_TBL_INX_TO_MOD_NAME *data;
                PARAMS_HMOD_TBL_INX_TO_MOD_NAME *params;
                WCHAR tmp;
                int hmod_table_index;

                if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DATA_HMOD_TBL_INX_TO_MOD_NAME)) {
                    ntStatus = STATUS_BUFFER_TOO_SMALL;
                    break;
                }
                if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(PARAMS_HMOD_TBL_INX_TO_MOD_NAME)) {
                    ntStatus = STATUS_BUFFER_TOO_SMALL;
                    break;
                }

                params = Irp->AssociatedIrp.SystemBuffer;

                UserGetAtomName = (UserGetAtomName_ptr)params->UserGetAtomName_address;
                aatomSysLoaded = (ATOM*)params->aatomSysLoaded_address;
                hmod_table_index = params->hmod_table_index;

                if (UserGetAtomName && aatomSysLoaded) {
                    __try {
                        (*UserGetAtomName)(aatomSysLoaded[0], &tmp, 1);
                    } __except (EXCEPTION_EXECUTE_HANDLER) {
                        UserGetAtomName = 0;
                    }
                }

                data = Irp->AssociatedIrp.SystemBuffer;

                if (UserGetAtomName) {
                    (*UserGetAtomName)(aatomSysLoaded[hmod_table_index], data->module_name, MAX_PATH);
                } else {
                    data->module_name[0] = 0;
                }

                ntStatus = STATUS_SUCCESS;
                break;
            }
    }
Пример #12
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;
}
Пример #13
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;
}
Пример #14
0
NTSTATUS
RequestApc(
   HANDLE ProcessId,
   PVOID ShellcodeBase,
   PVOID ContextData )
{
    NTSTATUS Status;
    PKAPC UserApc = NULL;
    PKAPC KernelApc = NULL;
    HANDLE ThreadId = NULL;
    PKTHREAD ThreadObject = NULL;


    ThreadId = GetThreadForProcess ( ProcessId );

    if ( ! ThreadId ) {
        DPF(("%s!%s GetThreadForProcess() FAIL\n", __MODULE__, __FUNCTION__ ));
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    // get the ETHREAD/KTHREAD for ThreadId
    Status = PsLookupThreadByThreadId ( ThreadId, &ThreadObject );

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

    // allocate memory for the user mode APC object
    UserApc = ExAllocatePoolWithTag ( NonPagedPool, sizeof (KAPC), 'auMC' );
    if ( ! UserApc ) {
        DPF(("%s!%s ExAllocatePoolWithTag(UserApc) FAIL=%08x\n", __MODULE__, __FUNCTION__ ));
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }

    // allocate memory for the kernel mode APC
    KernelApc = ExAllocatePoolWithTag ( NonPagedPool, sizeof (KAPC), 'akMC' );
    if ( ! KernelApc ) {
        DPF(("%s!%s ExAllocatePoolWithTag(KernelApc) FAIL=%08x\n", __MODULE__, __FUNCTION__ ));
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Exit;
    }
    
    // initialize the user mode APC obect with the 
    // APC routines UserApcKernelRoutine and UserApcNormalRoutine
    KeInitializeApc ( 
        UserApc,
        ThreadObject,
        OriginalApcEnvironment,
        (PKKERNEL_ROUTINE)UserApcKernelRoutine,
        (PKRUNDOWN_ROUTINE)NULL,
        (PKNORMAL_ROUTINE)ShellcodeBase, // user routine UserApcNormalRoutine()
        UserMode,
        ContextData );

    // queue the user mode APC
    // note that this APC will not be delivered until the thread is alerted
    // when the kernel mode APC calls KeTestAlertThread()
    KeInsertQueueApc( 
        UserApc,
        NULL,
        NULL,
        IO_NO_INCREMENT );

    // initialize the kernel mode APC obect with the 
    // APC routines KernelApcKernelRoutine and KernelApcNormalRoutine
    KeInitializeApc ( 
        KernelApc,
        ThreadObject,
        OriginalApcEnvironment,
        (PKKERNEL_ROUTINE)KernelApcKernelRoutine,
        (PKRUNDOWN_ROUTINE)NULL,
        (PKNORMAL_ROUTINE)KernelApcNormalRoutine,
        KernelMode,
        NULL );

    // queue the kernel mode APC which will alert the target thread
    KeInsertQueueApc( 
        KernelApc,
        NULL,
        NULL,
        IO_NO_INCREMENT );


Exit :
    if ( ThreadObject ) {
        ObDereferenceObject ( ThreadObject );
    }

    if ( ! NT_SUCCESS ( Status ) ) {
        if ( UserApc ) {
            ExFreePool ( UserApc );
        }
        
        if ( KernelApc ) {
            ExFreePool ( KernelApc );
        }
    }

    return Status;
} // RequestApc()
Пример #15
0
PETHREAD GetThreadObjectByThreadId(HANDLE ThreadID) {
	PETHREAD Thread;
	return NT_SUCCESS(PsLookupThreadByThreadId(ThreadID, &Thread)) ? Thread : NULL;
}
Пример #16
0
HWINEVENTHOOK
APIENTRY
NtUserSetWinEventHook(
   UINT eventMin,
   UINT eventMax,
   HMODULE hmodWinEventProc,
   PUNICODE_STRING puString,
   WINEVENTPROC lpfnWinEventProc,
   DWORD idProcess,
   DWORD idThread,
   UINT dwflags)
{
   PEVENTHOOK pEH;
   HWINEVENTHOOK Ret = NULL;
   NTSTATUS Status;
   HANDLE Handle;
   PETHREAD Thread = NULL;

   TRACE("NtUserSetWinEventHook hmod 0x%x, pfn 0x%x\n",hmodWinEventProc, lpfnWinEventProc);

   UserEnterExclusive();

   if ( !GlobalEvents )
   {
      GlobalEvents = ExAllocatePoolWithTag(PagedPool, sizeof(EVENTTABLE), TAG_HOOK);
      if (GlobalEvents == NULL)
      {
         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
         goto SetEventExit;
      }
      GlobalEvents->Counts = 0;      
      InitializeListHead(&GlobalEvents->Events);
   }

   if (eventMin > eventMax)
   {
      EngSetLastError(ERROR_INVALID_HOOK_FILTER);
      goto SetEventExit;
   }

   if (!lpfnWinEventProc)
   {
      EngSetLastError(ERROR_INVALID_FILTER_PROC);
      goto SetEventExit;
   }

   if ((dwflags & WINEVENT_INCONTEXT) && !hmodWinEventProc)
   {
      EngSetLastError(ERROR_HOOK_NEEDS_HMOD);
      goto SetEventExit;
   }

   if (idThread)
   {
      Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread);
      if (!NT_SUCCESS(Status))
      {   
         EngSetLastError(ERROR_INVALID_THREAD_ID);
         goto SetEventExit;
      }
   }
   // Creator, pti is set here.
   pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK));
   if (pEH)
   {
      InsertTailList(&GlobalEvents->Events, &pEH->Chain);
      GlobalEvents->Counts++;

      UserHMGetHandle(pEH) = Handle;
      pEH->eventMin  = eventMin;
      pEH->eventMax  = eventMax;
      pEH->idProcess = idProcess; // These are cmp'ed
      pEH->idThread  = idThread;  //  "
      pEH->Flags     = dwflags;
    /*
       If WINEVENT_INCONTEXT, set offset from hmod and proc. Save ihmod from
       the atom index table where the hmod data is saved to be recalled later
       if fSync set by WINEVENT_INCONTEXT.
       If WINEVENT_OUTOFCONTEXT just use proc..
       Do this instead....
     */
      if (NULL != hmodWinEventProc)
      {
         pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc);
         pEH->ihmod = (INT)hmodWinEventProc;
         pEH->Proc = lpfnWinEventProc;
      }
      else
         pEH->Proc = lpfnWinEventProc;

      UserDereferenceObject(pEH);

      Ret = Handle;
      IntSetSrvEventMask( eventMin, eventMax);
   }

SetEventExit:
   if (Thread) ObDereferenceObject(Thread);
   UserLeave();
   return Ret;
}