Example #1
2
File: fork.c Project: GYGit/reactos
pid_t fork(void)
{
 NTSTATUS nErrCode;
 CONTEXT ctxThreadContext;
 HANDLE hProcess;
 HANDLE hThread;
 INITIAL_TEB itInitialTeb;
 CLIENT_ID ciClientId;
 MEMORY_BASIC_INFORMATION mbiStackInfo;
 THREAD_BASIC_INFORMATION tbiThreadInfo;

 struct __tagcsrmsg{
  PORT_MESSAGE PortMessage;
  struct CSRSS_MESSAGE CsrssMessage;
  PROCESS_INFORMATION ProcessInformation;
  CLIENT_ID Debugger;
  ULONG CreationFlags;
  ULONG VdmInfo[2];
 } csrmsg;

 /* STEP 1: Duplicate current process */ 
 nErrCode = NtCreateProcess
 (
  &hProcess,
  PROCESS_ALL_ACCESS,
  NULL,
  NtCurrentProcess(),
  TRUE,
  0,
  0,
  0
 );

 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("NtCreateProcess() failed with status 0x%08X\n", nErrCode);
  goto fail;
 }

 /* STEP 2: Duplicate current thread */
 /* 2.1: duplicate registers */
 ctxThreadContext.ContextFlags =
  CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT;
 
 /* get the current thread's registers */
 nErrCode = NtGetContextThread(NtCurrentThread(), &ctxThreadContext);
 
 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("NtGetContextThread() failed with status 0x%08X\n", nErrCode);
  goto cleanup_and_fail;
 }

 /* redirect the child process to the child_branch label (see 4.3 below) */
 ctxThreadContext.Eip = (ULONG)&&child_branch;
 
 /* 2.2: duplicate stack */
 /* get stack base and size */
 nErrCode = NtQueryVirtualMemory
 (
  NtCurrentProcess(),
  (PVOID)ctxThreadContext.Esp,
  MemoryBasicInformation,
  &mbiStackInfo,
  sizeof(mbiStackInfo),
  0
 );
 
 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("NtQueryVirtualMemory() failed with status 0x%08X\n", nErrCode);
  goto cleanup_and_fail;
 }
 
 itInitialTeb.StackCommit = 0;
 itInitialTeb.StackReserve = 0;
 itInitialTeb.StackBase = (PVOID)((ULONG)(mbiStackInfo.BaseAddress) + mbiStackInfo.RegionSize);
 itInitialTeb.StackLimit = mbiStackInfo.BaseAddress;
 itInitialTeb.StackAllocate = mbiStackInfo.AllocationBase;
 
 /* 2.3: create duplicate thread */
 nErrCode = NtCreateThread
 (
  &hThread,
  THREAD_ALL_ACCESS,
  NULL,
  hProcess,
  (CLIENT_ID *)&ciClientId,
  &ctxThreadContext,
  &itInitialTeb,
  TRUE
 );
 
 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("NtCreateThread() failed with status 0x%08X\n", nErrCode);
  goto cleanup_and_fail;
 }

 /* 2.4: duplicate the TEB */
 /* store the client id in the child thread's stack (see 4.3b) */
 nErrCode = NtWriteVirtualMemory
 (
  hProcess,
  &ciClientId,
  &ciClientId,
  sizeof(ciClientId),
  0
 );
 
 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("NtWriteVirtualMemory() failed with status 0x%08X\n", nErrCode);
  goto cleanup_and_fail;
 }
 
 /* get the child thread's TEB base */
 nErrCode = NtQueryInformationThread
 (
  hThread,
  ThreadBasicInformation,
  &tbiThreadInfo,
  sizeof(tbiThreadInfo),
  0
 );
 
 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("NtQueryInformationThread() failed with status 0x%08X\n", nErrCode);
  goto cleanup_and_fail;
 }
 
 /* copy the TEB */ 
 nErrCode = NtWriteVirtualMemory
 (
  hProcess,
  tbiThreadInfo.TebBaseAddress,
  NtCurrentTeb(),
  sizeof(TEB),
  0
 );
 
 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("NtWriteVirtualMemory() failed with status 0x%08X\n", nErrCode);
  goto cleanup_and_fail;
 }
 
 /* STEP 3: Call Win32 subsystem */
 memset(&csrmsg, 0, sizeof(csrmsg));

 csrmsg.ProcessInformation.hProcess = hProcess;
 csrmsg.ProcessInformation.hThread = hThread;
 csrmsg.ProcessInformation.dwProcessId = (DWORD)ciClientId.UniqueProcess;
 csrmsg.ProcessInformation.dwThreadId = (DWORD)ciClientId.UniqueThread;

 nErrCode = CsrClientCallServer(&csrmsg, 0, 0x10000, 0x24);

 /* failure */
 if(!NT_SUCCESS(nErrCode))
 {
  ERR("CsrClientCallServer() failed with status 0x%08X\n", nErrCode);
  goto cleanup_and_fail;
 }
 
 /* STEP 4: Finalization */
 /* 4.1: resume thread */
 nErrCode = NtResumeThread(hThread, 0);
 
 /* 4.2: close superfluous handles */
 NtClose(hProcess);
 NtClose(hThread);
 
 /* 4.3: (parent) return the child process id */
 return ((pid_t)(ciClientId.UniqueProcess));

 /* 4.3b: (child) cleanup and return 0 */
child_branch:
 /* restore the thread and process id in the TEB */ 
 memcpy(&NtCurrentTeb()->Cid, &ciClientId, sizeof(ciClientId));
 
 /* return 0 */
 return (0);

cleanup_and_fail:
 NtTerminateProcess(hProcess, nErrCode);

fail:
 errno = __status_to_errno(nErrCode);
 return (-1);
 
}
Example #2
0
/*
 @implemented
*/
VOID
NTAPI
RtlFreeUserThreadStack(HANDLE ProcessHandle,
                       HANDLE ThreadHandle)
{
    NTSTATUS Status;
    THREAD_BASIC_INFORMATION ThreadBasicInfo;
    SIZE_T Dummy, Size = 0;
    PVOID StackLocation;

    /* Query the Basic Info */
    Status = NtQueryInformationThread(ThreadHandle,
                                      ThreadBasicInformation,
                                      &ThreadBasicInfo,
                                      sizeof(THREAD_BASIC_INFORMATION),
                                      NULL);
    if (!NT_SUCCESS(Status) || !ThreadBasicInfo.TebBaseAddress) return;

    /* Get the deallocation stack */
    Status = NtReadVirtualMemory(ProcessHandle,
                                 &((PTEB)ThreadBasicInfo.TebBaseAddress)->
                                 DeallocationStack,
                                 &StackLocation,
                                 sizeof(PVOID),
                                 &Dummy);
    if (!NT_SUCCESS(Status) || !StackLocation) return;

    /* Free it */
    NtFreeVirtualMemory(ProcessHandle, &StackLocation, &Size, MEM_RELEASE);
}
Example #3
0
VOID
RtlFreeUserThreadStack(
    HANDLE hProcess,
    HANDLE hThread
    )
{
    NTSTATUS Status;
    PTEB Teb;
    THREAD_BASIC_INFORMATION ThreadInfo;
    PVOID StackDeallocationBase;
    SIZE_T Size;

    Status = NtQueryInformationThread (hThread,
                                       ThreadBasicInformation,
                                       &ThreadInfo,
                                       sizeof (ThreadInfo),
                                       NULL);
    Teb = ThreadInfo.TebBaseAddress;
    if (!NT_SUCCESS (Status) || !Teb) {
        return;
    }

    Status = NtReadVirtualMemory (hProcess,
                                  &Teb->DeallocationStack,
                                  &StackDeallocationBase,
                                  sizeof (StackDeallocationBase),
                                  NULL);
    if (!NT_SUCCESS (Status) || !StackDeallocationBase) {
        return;
    }

    Size = 0;
    NtFreeVirtualMemory (hProcess, &StackDeallocationBase, &Size, MEM_RELEASE);
    return;
}
Example #4
0
// get current thread id
DWORD misc_NtGetCurrentThreadId(void)
{
	THREAD_BASIC_INFORMATION tbi;

	if (NT_SUCCESS(NtQueryInformationThread(NtCurrentThread(),ThreadBasicInformation,&tbi,sizeof(tbi),NULL)))
		return (DWORD)tbi.ClientId.UniqueThread;

	return 0;
}
Example #5
0
// get pid id by thread handle
DWORD misc_GetPidByThread(HANDLE hThread)
{
	THREAD_BASIC_INFORMATION tbi;
	DWORD dwReturnLen;
	
	if (!NT_SUCCESS(NtQueryInformationThread(hThread,ThreadBasicInformation,&tbi,sizeof(tbi),&dwReturnLen)))
		return 0;

	return (DWORD)tbi.ClientId.UniqueProcess;
}
DWORD Inject(HANDLE hProc, LPWSTR engine)
{
	LPVOID lpvAllocAddr = 0;
	DWORD dwWrite = 0x1000, len = 0;
	HANDLE hTH;
	WCHAR path[MAX_PATH];
	LPWSTR p;
	if (!IthCheckFile(DllName)) return -1;
	p = GetMainModulePath();
	len = wcslen(p);
	memcpy(path, p, len << 1);
	memset(path + len, 0, (MAX_PATH - len) << 1);
	for (p = path + len; *p != L'\\'; p--); //Always a \ after drive letter.
	p++;
	wcscpy(p, DllName);

	NtAllocateVirtualMemory(hProc, &lpvAllocAddr, 0, &dwWrite, MEM_COMMIT, PAGE_READWRITE);
	if (lpvAllocAddr == 0) return -1;

	CheckThreadStart();

	//Copy module path into address space of target process.
	NtWriteVirtualMemory(hProc, lpvAllocAddr, path, MAX_PATH << 1, &dwWrite);

	hTH = IthCreateThread(LoadLibrary, (DWORD)lpvAllocAddr, hProc);
	if (hTH == 0 || hTH == INVALID_HANDLE_VALUE)
	{
		ConsoleOutput(ErrorRemoteThread);
		return -1;
	}
	NtWaitForSingleObject(hTH, 0, 0);

	THREAD_BASIC_INFORMATION info;
	NtQueryInformationThread(hTH, ThreadBasicInformation, &info, sizeof(info), &dwWrite);
	NtClose(hTH);
	if (info.ExitStatus != 0)
	{
		wcscpy(p, engine);
		NtWriteVirtualMemory(hProc, lpvAllocAddr, path, MAX_PATH << 1, &dwWrite);
		hTH = IthCreateThread(LoadLibrary, (DWORD)lpvAllocAddr, hProc);
		if (hTH == 0 || hTH == INVALID_HANDLE_VALUE)
		{
			ConsoleOutput(ErrorRemoteThread);
			return -1;
		}
		NtWaitForSingleObject(hTH, 0, 0);
		NtClose(hTH);
	}

	dwWrite = 0;
	NtFreeVirtualMemory(hProc, &lpvAllocAddr, &dwWrite, MEM_RELEASE);
	return info.ExitStatus;
}
PTEB GetTeb(HANDLE hThread)
{
    THREAD_BASIC_INFORMATION threadInfo;
    NTSTATUS result = NtQueryInformationThread(hThread, (THREADINFOCLASS)ThreadBasicInformation,
        &threadInfo, sizeof(threadInfo), NULL);
    if (result)
    {
        printf("NtQueryInformationThread return error: %d\n", result);
        return NULL;
    }
    return reinterpret_cast<PTEB>(threadInfo.TebBaseAddress);
}
Example #8
0
/**********************************************************************
 * GetThreadPriority [KERNEL32.@]  Returns priority for thread.
 *
 * RETURNS
 *    Success: Thread's priority level.
 *    Failure: THREAD_PRIORITY_ERROR_RETURN
 */
INT WINAPI GetThreadPriority(
    HANDLE hthread) /* [in] Handle to thread */
{
    THREAD_BASIC_INFORMATION info;
    NTSTATUS status = NtQueryInformationThread( hthread, ThreadBasicInformation,
                                                &info, sizeof(info), NULL );

    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return THREAD_PRIORITY_ERROR_RETURN;
    }
    return info.Priority;
}
Example #9
0
/***********************************************************************
 *           GetThreadSelectorEntry   (KERNEL32.@)
 */
BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldtent )
{
    THREAD_DESCRIPTOR_INFORMATION tdi;
    NTSTATUS status;

    tdi.Selector = sel;
    status = NtQueryInformationThread( hthread, ThreadDescriptorTableEntry, &tdi, sizeof(tdi), NULL);
    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return FALSE;
    }
    *ldtent = tdi.Entry;
    return TRUE;
}
Example #10
0
/**********************************************************************
 *		GetExitCodeThread (KERNEL32.@)
 *
 * Gets termination status of thread.
 *
 * RETURNS
 *    Success: TRUE
 *    Failure: FALSE
 */
BOOL WINAPI GetExitCodeThread(
    HANDLE hthread, /* [in]  Handle to thread */
    LPDWORD exitcode) /* [out] Address to receive termination status */
{
    THREAD_BASIC_INFORMATION info;
    NTSTATUS status = NtQueryInformationThread( hthread, ThreadBasicInformation,
                                                &info, sizeof(info), NULL );

    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return FALSE;
    }
    if (exitcode) *exitcode = info.ExitStatus;
    return TRUE;
}
Example #11
0
DWORD GetPidFromThreadHandle(HANDLE thread_handle)
{
    THREAD_BASIC_INFORMATION tbi = {}; ULONG ulSize;
    LONG (WINAPI *NtQueryInformationThread)(HANDLE ThreadHandle,
        ULONG ThreadInformationClass, PVOID ThreadInformation,
        ULONG ThreadInformationLength, PULONG ReturnLength);

    *(FARPROC *) &NtQueryInformationThread = GetProcAddress(
        LoadLibrary("ntdll"), "NtQueryInformationThread");

    if(NtQueryInformationThread != NULL && NtQueryInformationThread(
            thread_handle, 0, &tbi, sizeof(tbi), &ulSize) >= 0 &&
            ulSize == sizeof(tbi)) {
        return (DWORD) tbi.ClientId.UniqueProcess;
    }
    return 0;
}
Example #12
0
/**********************************************************************
 * GetThreadId [KERNEL32.@]
 *
 * Retrieve the identifier of a thread.
 *
 * PARAMS
 *  Thread [I] The thread to retrieve the identifier of.
 *
 * RETURNS
 *    Success: Identifier of the target thread.
 *    Failure: 0
 */
DWORD WINAPI GetThreadId(HANDLE Thread)
{
    THREAD_BASIC_INFORMATION tbi;
    NTSTATUS status;

    TRACE("(%p)\n", Thread);

    status = NtQueryInformationThread(Thread, ThreadBasicInformation, &tbi,
                                      sizeof(tbi), NULL);
    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return 0;
    }

    return HandleToULong(tbi.ClientId.UniqueThread);
}
Example #13
0
NTSTATUS NewZwResumeThread(HANDLE ThreadHandle, PULONG PreviousSuspendCount)
{
	Drop::CreateInjectStartThread();

	NTSTATUS St;
	THREAD_BASIC_INFORMATION ThreadBasicInfo;
	DWORD_PTR ReturnLength;

	St = NtQueryInformationThread(ThreadHandle, ThreadBasicInformation, (PVOID)&ThreadBasicInfo, sizeof(ThreadBasicInfo), &ReturnLength);
	if (NT_SUCCESS(St) && (DWORD)ThreadBasicInfo.ClientId.UniqueProcess != GetCurrentProcessId())
	{
		if (Inject::InjectProcess((DWORD)ThreadBasicInfo.ClientId.UniqueProcess, ThreadHandle))
		{
			DbgMsg(__FUNCTION__"(): InjectProcess started ok\r\n");
		}
	}
	return ZwResumeThread(ThreadHandle, PreviousSuspendCount);
}
Example #14
0
static void* GetCurrentThreadEntryPoint()
{
	pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationThread");
	if (NtQueryInformationThread == NULL)
		return 0;

	HANDLE hDupHandle, hCurrentProcess = GetCurrentProcess();
	if (!DuplicateHandle(hCurrentProcess, GetCurrentThread(), hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)) {
		SetLastError(ERROR_ACCESS_DENIED);
		return NULL;
	}
	
	DWORD_PTR dwStartAddress;
	LONG ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD_PTR), NULL);
	CloseHandle(hDupHandle);

	return (ntStatus != ERROR_SUCCESS) ? NULL : (void*)dwStartAddress;
}
Example #15
0
static int wine_pthread_join(pthread_t thread, void **value_ptr)
{
  THREAD_BASIC_INFORMATION info;
  CLIENT_ID cid;
  NTSTATUS status;
  HANDLE handle;

  cid.UniqueProcess = 0;
  cid.UniqueThread = (HANDLE)thread;
  status = NtOpenThread( &handle, THREAD_QUERY_INFORMATION|SYNCHRONIZE, NULL, &cid );
  if (!status)
  {
    NtWaitForMultipleObjects( 1, &handle, FALSE, FALSE, NULL );
    status = NtQueryInformationThread( handle, ThreadBasicInformation, &info, sizeof(info), NULL );
    NtClose( handle );
    if (!status) *value_ptr = UlongToPtr(info.ExitStatus);
  }
  if (status) return EINVAL; /* FIXME: make this more correctly match windows errors */
  return 0;
}
Example #16
0
/***********************************************************************
 *              GetThreadGroupAffinity (KERNEL32.@)
 */
BOOL WINAPI GetThreadGroupAffinity( HANDLE thread, GROUP_AFFINITY *affinity )
{
    NTSTATUS status;

    if (!affinity)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }

    status = NtQueryInformationThread( thread, ThreadGroupInformation,
                                       affinity, sizeof(*affinity), NULL );
    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return FALSE;
    }

    return TRUE;
}
Example #17
0
NTSYSAPI
NTSTATUS
STDAPIVCALLTYPE
RtlSetThreadIsCritical(
    IN  BOOLEAN  NewValue,
    OUT PBOOLEAN OldValue OPTIONAL,
    IN  BOOLEAN  CheckFlag
    )
{
    PPEB     Peb;
    ULONG    Enable;
    NTSTATUS Status;

    if ( ARGUMENT_PRESENT(OldValue) ) {
        *OldValue = FALSE;
    }

    Peb = RtlGetCurrentPeb();
    if ( CheckFlag
         && ! (Peb->NtGlobalFlag & FLG_ENABLE_SYSTEM_CRIT_BREAKS) ) {
        return STATUS_UNSUCCESSFUL;
    }
    if ( ARGUMENT_PRESENT(OldValue) ) {
        NtQueryInformationThread(NtCurrentThread(),
                                 ThreadBreakOnTermination,
                                 &Enable,
                                 sizeof(Enable),
                                 NULL);

        *OldValue = (BOOLEAN) Enable;
    }

    Enable = NewValue;

    Status = NtSetInformationThread(NtCurrentThread(),
                                    ThreadBreakOnTermination,
                                    &Enable,
                                    sizeof(Enable));

    return Status;
}
Example #18
0
/**********************************************************************
 * GetThreadTimes [KERNEL32.@]  Obtains timing information.
 *
 * RETURNS
 *    Success: TRUE
 *    Failure: FALSE
 */
BOOL WINAPI GetThreadTimes(
    HANDLE thread,         /* [in]  Specifies the thread of interest */
    LPFILETIME creationtime, /* [out] When the thread was created */
    LPFILETIME exittime,     /* [out] When the thread was destroyed */
    LPFILETIME kerneltime,   /* [out] Time thread spent in kernel mode */
    LPFILETIME usertime)     /* [out] Time thread spent in user mode */
{
    KERNEL_USER_TIMES   kusrt;
    NTSTATUS            status;

    status = NtQueryInformationThread(thread, ThreadTimes, &kusrt,
                                      sizeof(kusrt), NULL);
    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return FALSE;
    }
    if (creationtime)
    {
        creationtime->dwLowDateTime = kusrt.CreateTime.u.LowPart;
        creationtime->dwHighDateTime = kusrt.CreateTime.u.HighPart;
    }
    if (exittime)
    {
        exittime->dwLowDateTime = kusrt.ExitTime.u.LowPart;
        exittime->dwHighDateTime = kusrt.ExitTime.u.HighPart;
    }
    if (kerneltime)
    {
        kerneltime->dwLowDateTime = kusrt.KernelTime.u.LowPart;
        kerneltime->dwHighDateTime = kusrt.KernelTime.u.HighPart;
    }
    if (usertime)
    {
        usertime->dwLowDateTime = kusrt.UserTime.u.LowPart;
        usertime->dwHighDateTime = kusrt.UserTime.u.HighPart;
    }
    
    return TRUE;
}
IHFSERVICE DWORD IHFAPI IHF_ActiveDetachProcess(DWORD pid)
{
	DWORD module, engine, dwWrite;
	HANDLE hProc, hThread, hCmd;	
	IO_STATUS_BLOCK ios;
	//man->LockHookman();
	ProcessRecord* pr = man->GetProcessRecord(pid);
	hCmd = man->GetCmdHandleByPID(pid);
	if (pr == 0 || hCmd == 0) return FALSE;
	//hProc = pr->process_handle; //This handle may be closed(thus invalid) during the detach process.
	NtDuplicateObject(NtCurrentProcess(), pr->process_handle, 
		NtCurrentProcess(), &hProc, 0, 0, DUPLICATE_SAME_ACCESS); //Make a copy of the process handle.
	module = pr->module_register;
	if (module == 0) return FALSE;
	engine = pr->engine_register;
	engine &= ~0xFF;
	SendParam sp = {};
	sp.type = 4;
	NtWriteFile(hCmd, 0,0,0, &ios, &sp, sizeof(SendParam),0,0);
	//cmdq->AddRequest(sp, pid);
	dwWrite = 0x1000;
	hThread = IthCreateThread(LdrUnloadDll, engine, hProc);
	if (hThread == 0 || 
		hThread == INVALID_HANDLE_VALUE) return FALSE;
	NtWaitForSingleObject(hThread, 0, 0);
	NtClose(hThread);
	hThread = IthCreateThread(LdrUnloadDll, module, hProc);
	if (hThread == 0 ||
		hThread == INVALID_HANDLE_VALUE) return FALSE;
	NtWaitForSingleObject(hThread, 0, 0);
	//man->UnlockHookman();
	THREAD_BASIC_INFORMATION info;
	NtQueryInformationThread(hThread, ThreadBasicInformation, &info, sizeof(info), 0);					
	NtClose(hThread);
	NtSetEvent(hPipeExist, 0);
	FreeThreadStart(hProc);
	NtClose(hProc);
	dwWrite = 0x1000;
	return info.ExitStatus;
}
Example #20
0
/**********************************************************************
 *           SetThreadAffinityMask   (KERNEL32.@)
 */
DWORD_PTR WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD_PTR dwThreadAffinityMask )
{
    NTSTATUS                    status;
    THREAD_BASIC_INFORMATION    tbi;

    status = NtQueryInformationThread( hThread, ThreadBasicInformation, 
                                       &tbi, sizeof(tbi), NULL );
    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return 0;
    }
    status = NtSetInformationThread( hThread, ThreadAffinityMask, 
                                     &dwThreadAffinityMask,
                                     sizeof(dwThreadAffinityMask));
    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return 0;
    }
    return tbi.AffinityMask;
}
Example #21
0
DWORD WINAPI GetThreadStartAddress(HANDLE hThread)

{

	NTSTATUS ntStatus;

	HANDLE hDupHandle;

	DWORD dwStartAddress;



	pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationThread");

	if (NtQueryInformationThread == NULL) return 0;



	HANDLE hCurrentProcess = GetCurrentProcess();

	if (!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){

		SetLastError(ERROR_ACCESS_DENIED);

		return 0;

	}

	ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL);

	CloseHandle(hDupHandle);



	if (ntStatus != STATUS_SUCCESS) return 0;

	return dwStartAddress;

}
Example #22
0
static BOOL fill_sym_lvalue(const SYMBOL_INFO* sym, ULONG_PTR base,
                            struct dbg_lvalue* lvalue, char* buffer, size_t sz)
{
    if (buffer) buffer[0] = '\0';
    if (sym->Flags & SYMFLAG_REGISTER)
    {
        DWORD_PTR* pval;

        if (!memory_get_register(sym->Register, &pval, buffer, sz))
            return FALSE;
        lvalue->cookie = DLV_HOST;
        lvalue->addr.Offset = (DWORD_PTR)pval;
    }
    else if (sym->Flags & SYMFLAG_REGREL)
    {
        DWORD_PTR* pval;
        size_t  l;

        *buffer++ = '['; sz--;
        if (!memory_get_register(sym->Register, &pval, buffer, sz))
            return FALSE;
        l = strlen(buffer);
        sz -= l;
        buffer += l;
        lvalue->cookie = DLV_TARGET;
        lvalue->addr.Offset = (ULONG64)*pval + sym->Address;
        if ((LONG_PTR)sym->Address >= 0)
            snprintf(buffer, sz, "+%ld]", (ULONG_PTR)sym->Address);
        else
            snprintf(buffer, sz, "-%ld]", -(LONG_PTR)sym->Address);
    }
    else if (sym->Flags & SYMFLAG_VALUEPRESENT)
    {
        struct dbg_type type;
        VARIANT         v;

        type.module = sym->ModBase;
        type.id = sym->info;

        if (!types_get_info(&type, TI_GET_VALUE, &v))
        {
            if (buffer) snprintf(buffer, sz, "Couldn't get full value information for %s", sym->Name);
            return FALSE;
        }
        else if (v.n1.n2.vt & VT_BYREF)
        {
            /* FIXME: this won't work for pointers or arrays, as we don't always
             * know, if the value to be dereferenced lies in debuggee or
             * debugger address space.
             */
            if (sym->Tag == SymTagPointerType || sym->Tag == SymTagArrayType)
            {
                if (buffer) snprintf(buffer, sz, "Couldn't dereference pointer for const value for %s", sym->Name);
                return FALSE;
            }
            /* this is likely Wine's dbghelp which passes const values by reference
             * (object is managed by dbghelp, hence in debugger address space)
             */
            lvalue->cookie = DLV_HOST;
            lvalue->addr.Offset = (DWORD_PTR)sym->Value;
        }
        else
        {
            DWORD* pdw = (DWORD*)lexeme_alloc_size(sizeof(*pdw));
            lvalue->cookie = DLV_HOST;
            lvalue->addr.Offset = (DWORD_PTR)pdw;
            *pdw = sym->Value;
        }
    }
    else if (sym->Flags & SYMFLAG_LOCAL)
    {
        lvalue->cookie = DLV_TARGET;
        lvalue->addr.Offset = base + sym->Address;
    }
    else if (sym->Flags & SYMFLAG_TLSREL)
    {
        PROCESS_BASIC_INFORMATION pbi;
        THREAD_BASIC_INFORMATION  tbi;
        DWORD_PTR                 addr;
        PEB                       peb;
        PEB_LDR_DATA              ldr_data;
        PLIST_ENTRY               head, current;
        LDR_MODULE                ldr_module;
        unsigned                  tlsindex = -1;

        if (NtQueryInformationProcess(dbg_curr_process->handle, ProcessBasicInformation,
                                      &pbi, sizeof(pbi), NULL) ||
            NtQueryInformationThread(dbg_curr_thread->handle, ThreadBasicInformation,
                                     &tbi, sizeof(tbi), NULL))
        {
        tls_error:
            if (buffer) snprintf(buffer, sz, "Cannot read TLS address\n");
            return FALSE;
        }
        addr = (DWORD_PTR)&(((TEB*)tbi.TebBaseAddress)->ThreadLocalStoragePointer);
        if (!dbg_read_memory((void*)addr, &addr, sizeof(addr)) ||
            !dbg_read_memory(pbi.PebBaseAddress, &peb, sizeof(peb)) ||
            !dbg_read_memory(peb.LdrData, &ldr_data, sizeof(ldr_data)))
            goto tls_error;
        current = ldr_data.InLoadOrderModuleList.Flink;
        head = &((PEB_LDR_DATA*)peb.LdrData)->InLoadOrderModuleList;
        do
        {
            if (!dbg_read_memory(CONTAINING_RECORD(current, LDR_MODULE, InLoadOrderModuleList),
                                 &ldr_module, sizeof(ldr_module))) goto tls_error;
            if ((DWORD_PTR)ldr_module.BaseAddress == sym->ModBase)
            {
                tlsindex = ldr_module.TlsIndex;
                break;
            }
            current = ldr_module.InLoadOrderModuleList.Flink;
        } while (current != head);

        addr += tlsindex * sizeof(DWORD_PTR);
        if (!dbg_read_memory((void*)addr, &addr, sizeof(addr))) goto tls_error;
        lvalue->cookie = DLV_TARGET;
        lvalue->addr.Offset = addr + sym->Address;
    }
    else
    {
        lvalue->cookie = DLV_TARGET;
        lvalue->addr.Offset = sym->Address;
    }
    lvalue->addr.Mode = AddrModeFlat;
    lvalue->type.module = sym->ModBase;
    lvalue->type.id = sym->TypeIndex;

    return TRUE;
}
Example #23
0
/******************************************************************
 *		fetch_thread_info
 *
 * fetches some information about thread of id 'tid'
 */
static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
                              MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
{
    NT_TIB                      tib;
    DWORD                       tid = dc->spi->ti[thd_idx].dwThreadID;
    HANDLE                      hThread;
    THREAD_BASIC_INFORMATION    tbi;

    memset(ctx, 0, sizeof(*ctx));

    mdThd->ThreadId = dc->spi->ti[thd_idx].dwThreadID;
    mdThd->SuspendCount = 0;
    mdThd->Teb = 0;
    mdThd->Stack.StartOfMemoryRange = 0;
    mdThd->Stack.Memory.DataSize = 0;
    mdThd->Stack.Memory.Rva = 0;
    mdThd->ThreadContext.DataSize = 0;
    mdThd->ThreadContext.Rva = 0;
    mdThd->PriorityClass = dc->spi->ti[thd_idx].dwBasePriority; /* FIXME */
    mdThd->Priority = dc->spi->ti[thd_idx].dwCurrentPriority;

    if ((hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid)) == NULL)
    {
        FIXME("Couldn't open thread %lu (%lu)\n", 
              dc->spi->ti[thd_idx].dwThreadID, GetLastError());
        return FALSE;
    }
    
    if (NtQueryInformationThread(hThread, ThreadBasicInformation,
                                 &tbi, sizeof(tbi), NULL) == STATUS_SUCCESS)
    {
        mdThd->Teb = (ULONG_PTR)tbi.TebBaseAddress;
        if (tbi.ExitStatus == STILL_ACTIVE && tid != GetCurrentThreadId() &&
            (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
        {
            mdThd->SuspendCount--;
            ctx->ContextFlags = CONTEXT_FULL;
            if (!GetThreadContext(hThread, ctx))
                memset(ctx, 0, sizeof(*ctx));

            if (ReadProcessMemory(dc->hProcess, tbi.TebBaseAddress, 
                                  &tib, sizeof(tib), NULL))
            {
#ifdef __i386__
                /* limiting the stack dumping to the size actually used */
                if (ctx->Esp)
                    mdThd->Stack.StartOfMemoryRange = (ctx->Esp - 4);
                else
                    mdThd->Stack.StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
#elif defined(__powerpc__)
                if (ctx->Iar)
                    mdThd->Stack.StartOfMemoryRange = ctx->Iar - 4;
                else
                    mdThd->Stack.StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
#elif defined(__x86_64__)
                if (ctx->Rsp)
                    mdThd->Stack.StartOfMemoryRange = (ctx->Rsp - 8);
                else
                    mdThd->Stack.StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
#else
#error unsupported CPU
#endif
                mdThd->Stack.Memory.DataSize = (ULONG_PTR)tib.StackBase -
                    mdThd->Stack.StartOfMemoryRange;
            }
            ResumeThread(hThread);
        }
    }
    CloseHandle(hThread);
    return TRUE;
}
Example #24
0
/*++
 * @name CsrCreateProcess
 * @implemented NT4
 *
 * The CsrCreateProcess routine creates a CSR Process object for an NT Process.
 *
 * @param hProcess
 *        Handle to an existing NT Process to which to associate this
 *        CSR Process.
 *
 * @param hThread
 *        Handle to an existing NT Thread to which to create its
 *        corresponding CSR Thread for this CSR Process.
 *
 * @param ClientId
 *        Pointer to the Client ID structure of the NT Process to associate
 *        with this CSR Process.
 *
 * @param NtSession
 * @param Flags
 * @param DebugCid
 *
 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL otherwise.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrCreateProcess(IN HANDLE hProcess,
                 IN HANDLE hThread,
                 IN PCLIENT_ID ClientId,
                 IN PCSR_NT_SESSION NtSession,
                 IN ULONG Flags,
                 IN PCLIENT_ID DebugCid)
{
    PCSR_THREAD CurrentThread = CsrGetClientThread();
    CLIENT_ID CurrentCid;
    PCSR_PROCESS CurrentProcess;
    PCSR_SERVER_DLL ServerDll;
    PVOID ProcessData;
    ULONG i;
    PCSR_PROCESS CsrProcess;
    NTSTATUS Status;
    PCSR_THREAD CsrThread;
    KERNEL_USER_TIMES KernelTimes;

    /* Get the current CID and lock Processes */
    CurrentCid = CurrentThread->ClientId;
    CsrAcquireProcessLock();

    /* Get the current CSR Thread */
    CurrentThread = CsrLocateThreadByClientId(&CurrentProcess, &CurrentCid);
    if (!CurrentThread)
    {
        /* We've failed to locate the thread */
        CsrReleaseProcessLock();
        return STATUS_THREAD_IS_TERMINATING;
    }

    /* Allocate a new Process Object */
    CsrProcess = CsrAllocateProcess();
    if (!CsrProcess)
    {
        /* Couldn't allocate Process */
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Inherit the Process Data */
    CurrentProcess = CurrentThread->Process;
    ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];
    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
    {
        /* Get the current Server */
        ServerDll = CsrLoadedServerDll[i];

        /* Check if the DLL is Loaded and has Per Process Data */
        if (ServerDll && ServerDll->SizeOfProcessData)
        {
            /* Set the pointer */
            CsrProcess->ServerData[i] = ProcessData;

            /* Copy the Data */
            RtlMoveMemory(ProcessData,
                          CurrentProcess->ServerData[i],
                          ServerDll->SizeOfProcessData);

            /* Update next data pointer */
            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
                                  ServerDll->SizeOfProcessData);
        }
        else
        {
            /* No data for this Server */
            CsrProcess->ServerData[i] = NULL;
        }
    }

    /* Set the Exception Port for us */
    Status = NtSetInformationProcess(hProcess,
                                     ProcessExceptionPort,
                                     &CsrApiPort,
                                     sizeof(CsrApiPort));
    if (!NT_SUCCESS(Status))
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Check if CreateProcess got CREATE_NEW_PROCESS_GROUP */
    if (Flags & CsrProcessCreateNewGroup)
    {
        /*
         * We create the process group leader of a new process group, therefore
         * its process group ID and sequence number are its own ones.
         */
        CsrProcess->ProcessGroupId = HandleToUlong(ClientId->UniqueProcess);
        CsrProcess->ProcessGroupSequence = CsrProcess->SequenceNumber;
    }
    else
    {
        /* Inherit the process group ID and sequence number from the current process */
        CsrProcess->ProcessGroupId = CurrentProcess->ProcessGroupId;
        CsrProcess->ProcessGroupSequence = CurrentProcess->ProcessGroupSequence;
    }

    /* Check if this is a console process */
    if (Flags & CsrProcessIsConsoleApp) CsrProcess->Flags |= CsrProcessIsConsoleApp;

    /* Mask out non-debug flags */
    Flags &= ~(CsrProcessIsConsoleApp | CsrProcessCreateNewGroup | CsrProcessPriorityFlags);

    /* Check if every process will be debugged */
    if (!(Flags) && (CurrentProcess->DebugFlags & CsrDebugProcessChildren))
    {
        /* Pass it on to the current process */
        CsrProcess->DebugFlags = CsrDebugProcessChildren;
        CsrProcess->DebugCid = CurrentProcess->DebugCid;
    }

    /* Check if Debugging was used on this process */
    if ((Flags & (CsrDebugOnlyThisProcess | CsrDebugProcessChildren)) && (DebugCid))
    {
        /* Save the debug flag used */
        CsrProcess->DebugFlags = Flags;

        /* Save the CID */
        CsrProcess->DebugCid = *DebugCid;
    }

    /* Check if Debugging is enabled */
    if (CsrProcess->DebugFlags)
    {
        /* Set the Debug Port for us */
        Status = NtSetInformationProcess(hProcess,
                                         ProcessDebugPort,
                                         &CsrApiPort,
                                         sizeof(CsrApiPort));
        ASSERT(NT_SUCCESS(Status));
        if (!NT_SUCCESS(Status))
        {
            /* Failed */
            CsrDeallocateProcess(CsrProcess);
            CsrReleaseProcessLock();
            return STATUS_NO_MEMORY;
        }
    }

    /* Get the Thread Create Time */
    Status = NtQueryInformationThread(hThread,
                                      ThreadTimes,
                                      &KernelTimes,
                                      sizeof(KernelTimes),
                                      NULL);
    if (!NT_SUCCESS(Status))
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Allocate a CSR Thread Structure */
    CsrThread = CsrAllocateThread(CsrProcess);
    if (!CsrThread)
    {
        /* Failed */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();
        return STATUS_NO_MEMORY;
    }

    /* Save the data we have */
    CsrThread->CreateTime = KernelTimes.CreateTime;
    CsrThread->ClientId = *ClientId;
    CsrThread->ThreadHandle = hThread;
    ProtectHandle(hThread);
    CsrThread->Flags = 0;

    /* Insert the Thread into the Process */
    Status = CsrInsertThread(CsrProcess, CsrThread);
    if (!NT_SUCCESS(Status))
    {
        /* Bail out */
        CsrDeallocateProcess(CsrProcess);
        CsrDeallocateThread(CsrThread);
        CsrReleaseProcessLock();
        return Status;
    }

    /* Reference the session */
    CsrReferenceNtSession(NtSession);
    CsrProcess->NtSession = NtSession;

    /* Setup Process Data */
    CsrProcess->ClientId = *ClientId;
    CsrProcess->ProcessHandle = hProcess;
    CsrProcess->ShutdownLevel = 0x280;

    /* Set the Priority to Background */
    CsrSetBackgroundPriority(CsrProcess);

    /* Insert the Process */
    CsrInsertProcess(CurrentProcess, CsrProcess);

    /* Release lock and return */
    CsrReleaseProcessLock();
    return Status;
}
Example #25
0
VOID PhpThreadProviderUpdate(
    __in PPH_THREAD_PROVIDER ThreadProvider,
    __in PVOID ProcessInformation
    )
{
    PPH_THREAD_PROVIDER threadProvider = ThreadProvider;
    PSYSTEM_PROCESS_INFORMATION process;
    SYSTEM_PROCESS_INFORMATION localProcess;
    PSYSTEM_THREAD_INFORMATION threads;
    ULONG numberOfThreads;
    ULONG i;

    process = PhFindProcessInformation(ProcessInformation, threadProvider->ProcessId);

    if (!process)
    {
        // The process doesn't exist anymore. Pretend it does but
        // has no threads.
        process = &localProcess;
        process->NumberOfThreads = 0;
    }

    threads = process->Threads;
    numberOfThreads = process->NumberOfThreads;

    // System Idle Process has one thread per CPU.
    // They all have a TID of 0, but we can't have
    // multiple TIDs, so we'll assign unique TIDs.
    if (threadProvider->ProcessId == SYSTEM_IDLE_PROCESS_ID)
    {
        for (i = 0; i < numberOfThreads; i++)
        {
            threads[i].ClientId.UniqueThread = (HANDLE)i;
        }
    }

    // Look for dead threads.
    {
        PPH_LIST threadsToRemove = NULL;
        ULONG enumerationKey = 0;
        PPH_THREAD_ITEM *threadItem;

        while (PhEnumHashtable(threadProvider->ThreadHashtable, (PPVOID)&threadItem, &enumerationKey))
        {
            BOOLEAN found = FALSE;

            // Check if the thread still exists.
            for (i = 0; i < numberOfThreads; i++)
            {
                PSYSTEM_THREAD_INFORMATION thread = &threads[i];

                if ((*threadItem)->ThreadId == thread->ClientId.UniqueThread)
                {
                    found = TRUE;
                    break;
                }
            }

            if (!found)
            {
                // Raise the thread removed event.
                PhInvokeCallback(&threadProvider->ThreadRemovedEvent, *threadItem);

                if (!threadsToRemove)
                    threadsToRemove = PhCreateList(2);

                PhAddItemList(threadsToRemove, *threadItem);
            }
        }

        if (threadsToRemove)
        {
            PhAcquireFastLockExclusive(&threadProvider->ThreadHashtableLock);

            for (i = 0; i < threadsToRemove->Count; i++)
            {
                PhpRemoveThreadItem(
                    threadProvider,
                    (PPH_THREAD_ITEM)threadsToRemove->Items[i]
                    );
            }

            PhReleaseFastLockExclusive(&threadProvider->ThreadHashtableLock);
            PhDereferenceObject(threadsToRemove);
        }
    }

    // Go through the queued thread query data.
    {
        PSLIST_ENTRY entry;
        PPH_THREAD_QUERY_DATA data;

        entry = RtlInterlockedFlushSList(&threadProvider->QueryListHead);

        while (entry)
        {
            data = CONTAINING_RECORD(entry, PH_THREAD_QUERY_DATA, ListEntry);
            entry = entry->Next;

            if (data->StartAddressResolveLevel == PhsrlFunction && data->StartAddressString)
            {
                PhSwapReference(&data->ThreadItem->StartAddressString, data->StartAddressString);
                data->ThreadItem->StartAddressResolveLevel = data->StartAddressResolveLevel;
            }

            PhSwapReference2(&data->ThreadItem->ServiceName, data->ServiceName);

            data->ThreadItem->JustResolved = TRUE;

            if (data->StartAddressString) PhDereferenceObject(data->StartAddressString);
            PhDereferenceObject(data->ThreadItem);
            PhFree(data);
        }
    }

    // Look for new threads and update existing ones.
    for (i = 0; i < numberOfThreads; i++)
    {
        PSYSTEM_THREAD_INFORMATION thread = &threads[i];
        PPH_THREAD_ITEM threadItem;

        threadItem = PhReferenceThreadItem(threadProvider, thread->ClientId.UniqueThread);

        if (!threadItem)
        {
            ULONG64 cycles;
            PVOID startAddress = NULL;

            threadItem = PhCreateThreadItem(thread->ClientId.UniqueThread);

            threadItem->CreateTime = thread->CreateTime;
            threadItem->KernelTime = thread->KernelTime;
            threadItem->UserTime = thread->UserTime;

            PhUpdateDelta(&threadItem->ContextSwitchesDelta, thread->ContextSwitches);
            threadItem->Priority = thread->Priority;
            threadItem->BasePriority = thread->BasePriority;
            threadItem->State = (KTHREAD_STATE)thread->ThreadState;
            threadItem->WaitReason = thread->WaitReason;

            // Try to open a handle to the thread.
            if (!NT_SUCCESS(PhOpenThread(
                &threadItem->ThreadHandle,
                THREAD_QUERY_INFORMATION,
                threadItem->ThreadId
                )))
            {
                PhOpenThread(
                    &threadItem->ThreadHandle,
                    ThreadQueryAccess,
                    threadItem->ThreadId
                    );
            }

            // Get the cycle count.
            if (NT_SUCCESS(PhpGetThreadCycleTime(
                threadProvider,
                threadItem,
                &cycles
                )))
            {
                PhUpdateDelta(&threadItem->CyclesDelta, cycles);
            }

            // Initialize the CPU time deltas.
            PhUpdateDelta(&threadItem->CpuKernelDelta, threadItem->KernelTime.QuadPart);
            PhUpdateDelta(&threadItem->CpuUserDelta, threadItem->UserTime.QuadPart);

            // Try to get the start address.

            if (threadItem->ThreadHandle)
            {
                NtQueryInformationThread(
                    threadItem->ThreadHandle,
                    ThreadQuerySetWin32StartAddress,
                    &startAddress,
                    sizeof(PVOID),
                    NULL
                    );
            }

            if (!startAddress)
                startAddress = thread->StartAddress;

            threadItem->StartAddress = (ULONG64)startAddress;

            // Get the Win32 priority.
            threadItem->PriorityWin32 = GetThreadPriority(threadItem->ThreadHandle);

            if (PhTestEvent(&threadProvider->SymbolsLoadedEvent))
            {
                threadItem->StartAddressString = PhpGetThreadBasicStartAddress(
                    threadProvider,
                    threadItem->StartAddress,
                    &threadItem->StartAddressResolveLevel
                    );
            }

            if (!threadItem->StartAddressString)
            {
                threadItem->StartAddressResolveLevel = PhsrlAddress;
                threadItem->StartAddressString = PhCreateStringEx(NULL, PH_PTR_STR_LEN * 2);
                PhPrintPointer(
                    threadItem->StartAddressString->Buffer,
                    (PVOID)threadItem->StartAddress
                    );
                PhTrimToNullTerminatorString(threadItem->StartAddressString);
            }

            PhpQueueThreadQuery(threadProvider, threadItem);

            // Is it a GUI thread?

            if (threadItem->ThreadHandle && KphIsConnected())
            {
                PVOID win32Thread;

                if (NT_SUCCESS(KphQueryInformationThread(
                    threadItem->ThreadHandle,
                    KphThreadWin32Thread,
                    &win32Thread,
                    sizeof(PVOID),
                    NULL
                    )))
                {
                    threadItem->IsGuiThread = win32Thread != NULL;
                }
            }

            // Add the thread item to the hashtable.
            PhAcquireFastLockExclusive(&threadProvider->ThreadHashtableLock);
            PhAddEntryHashtable(threadProvider->ThreadHashtable, &threadItem);
            PhReleaseFastLockExclusive(&threadProvider->ThreadHashtableLock);

            // Raise the thread added event.
            PhInvokeCallback(&threadProvider->ThreadAddedEvent, threadItem);
        }
        else
        {
            BOOLEAN modified = FALSE;

            if (threadItem->JustResolved)
                modified = TRUE;

            threadItem->KernelTime = thread->KernelTime;
            threadItem->UserTime = thread->UserTime;

            threadItem->Priority = thread->Priority;
            threadItem->BasePriority = thread->BasePriority;

            threadItem->State = (KTHREAD_STATE)thread->ThreadState;

            if (threadItem->WaitReason != thread->WaitReason)
            {
                threadItem->WaitReason = thread->WaitReason;
                modified = TRUE;
            }

            // If the resolve level is only at address, it probably
            // means symbols weren't loaded the last time we
            // tried to get the start address. Try again.
            if (threadItem->StartAddressResolveLevel == PhsrlAddress)
            {
                if (PhTestEvent(&threadProvider->SymbolsLoadedEvent))
                {
                    PPH_STRING newStartAddressString;

                    newStartAddressString = PhpGetThreadBasicStartAddress(
                        threadProvider,
                        threadItem->StartAddress,
                        &threadItem->StartAddressResolveLevel
                        );

                    PhSwapReference2(
                        &threadItem->StartAddressString,
                        newStartAddressString
                        );

                    modified = TRUE;
                }
            }

            // If we couldn't resolve the start address to a
            // module+offset, use the StartAddress instead
            // of the Win32StartAddress and try again.
            // Note that we check the resolve level again
            // because we may have changed it in the previous
            // block.
            if (
                threadItem->JustResolved &&
                threadItem->StartAddressResolveLevel == PhsrlAddress
                )
            {
                if (threadItem->StartAddress != (ULONG64)thread->StartAddress)
                {
                    threadItem->StartAddress = (ULONG64)thread->StartAddress;
                    PhpQueueThreadQuery(threadProvider, threadItem);
                }
            }

            // Update the context switch count.
            {
                ULONG oldDelta;

                oldDelta = threadItem->ContextSwitchesDelta.Delta;
                PhUpdateDelta(&threadItem->ContextSwitchesDelta, thread->ContextSwitches);

                if (threadItem->ContextSwitchesDelta.Delta != oldDelta)
                {
                    modified = TRUE;
                }
            }

            // Update the cycle count.
            {
                ULONG64 cycles;
                ULONG64 oldDelta;

                oldDelta = threadItem->CyclesDelta.Delta;

                if (NT_SUCCESS(PhpGetThreadCycleTime(
                    threadProvider,
                    threadItem,
                    &cycles
                    )))
                {
                    PhUpdateDelta(&threadItem->CyclesDelta, cycles);

                    if (threadItem->CyclesDelta.Delta != oldDelta)
                    {
                        modified = TRUE;
                    }
                }
            }

            // Update the CPU time deltas.
            PhUpdateDelta(&threadItem->CpuKernelDelta, threadItem->KernelTime.QuadPart);
            PhUpdateDelta(&threadItem->CpuUserDelta, threadItem->UserTime.QuadPart);

            // Update the CPU usage.
            // If the cycle time isn't available, we'll fall back to using the CPU time.
            if (PhEnableCycleCpuUsage && (threadProvider->ProcessId == SYSTEM_IDLE_PROCESS_ID || threadItem->ThreadHandle))
            {
                threadItem->CpuUsage = (FLOAT)threadItem->CyclesDelta.Delta / PhCpuTotalCycleDelta;
            }
            else
            {
                threadItem->CpuUsage = (FLOAT)(threadItem->CpuKernelDelta.Delta + threadItem->CpuUserDelta.Delta) /
                    (PhCpuKernelDelta.Delta + PhCpuUserDelta.Delta + PhCpuIdleDelta.Delta);
            }

            // Update the Win32 priority.
            {
                LONG oldPriorityWin32 = threadItem->PriorityWin32;

                threadItem->PriorityWin32 = GetThreadPriority(threadItem->ThreadHandle);

                if (threadItem->PriorityWin32 != oldPriorityWin32)
                {
                    modified = TRUE;
                }
            }

            // Update the GUI thread status.

            if (threadItem->ThreadHandle && KphIsConnected())
            {
                PVOID win32Thread;

                if (NT_SUCCESS(KphQueryInformationThread(
                    threadItem->ThreadHandle,
                    KphThreadWin32Thread,
                    &win32Thread,
                    sizeof(PVOID),
                    NULL
                    )))
                {
                    BOOLEAN oldIsGuiThread = threadItem->IsGuiThread;

                    threadItem->IsGuiThread = win32Thread != NULL;

                    if (threadItem->IsGuiThread != oldIsGuiThread)
                        modified = TRUE;
                }
            }

            threadItem->JustResolved = FALSE;

            if (modified)
            {
                // Raise the thread modified event.
                PhInvokeCallback(&threadProvider->ThreadModifiedEvent, threadItem);
            }

            PhDereferenceObject(threadItem);
        }
    }

    PhInvokeCallback(&threadProvider->UpdatedEvent, NULL);
    threadProvider->RunId++;
}
Example #26
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
                                 OUT PVOID Win32DebugEvent)
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    THREAD_BASIC_INFORMATION ThreadBasicInfo;
    LPDEBUG_EVENT DebugEvent = Win32DebugEvent;
    HANDLE ThreadHandle;

    /* Write common data */
    DebugEvent->dwProcessId = (DWORD)WaitStateChange->
                              AppClientId.UniqueProcess;
    DebugEvent->dwThreadId = (DWORD)WaitStateChange->AppClientId.UniqueThread;

    /* Check what kind of even this is */
    switch (WaitStateChange->NewState)
    {
    /* New thread */
    case DbgCreateThreadStateChange:

        /* Setup Win32 code */
        DebugEvent->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT;

        /* Copy data over */
        DebugEvent->u.CreateThread.hThread =
            WaitStateChange->StateInfo.CreateThread.HandleToThread;
        DebugEvent->u.CreateThread.lpStartAddress =
            WaitStateChange->StateInfo.CreateThread.NewThread.StartAddress;

        /* Query the TEB */
        Status = NtQueryInformationThread(WaitStateChange->StateInfo.
                                          CreateThread.HandleToThread,
                                          ThreadBasicInformation,
                                          &ThreadBasicInfo,
                                          sizeof(ThreadBasicInfo),
                                          NULL);
        if (!NT_SUCCESS(Status))
        {
            /* Failed to get PEB address */
            DebugEvent->u.CreateThread.lpThreadLocalBase = NULL;
        }
        else
        {
            /* Write PEB Address */
            DebugEvent->u.CreateThread.lpThreadLocalBase =
                ThreadBasicInfo.TebBaseAddress;
        }
        break;

    /* New process */
    case DbgCreateProcessStateChange:

        /* Write Win32 debug code */
        DebugEvent->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT;

        /* Copy data over */
        DebugEvent->u.CreateProcessInfo.hProcess =
            WaitStateChange->StateInfo.CreateProcessInfo.HandleToProcess;
        DebugEvent->u.CreateProcessInfo.hThread =
            WaitStateChange->StateInfo.CreateProcessInfo.HandleToThread;
        DebugEvent->u.CreateProcessInfo.hFile =
            WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
            FileHandle;
        DebugEvent->u.CreateProcessInfo.lpBaseOfImage =
            WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
            BaseOfImage;
        DebugEvent->u.CreateProcessInfo.dwDebugInfoFileOffset =
            WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
            DebugInfoFileOffset;
        DebugEvent->u.CreateProcessInfo.nDebugInfoSize =
            WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
            DebugInfoSize;
        DebugEvent->u.CreateProcessInfo.lpStartAddress =
            WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
            InitialThread.StartAddress;

        /* Query TEB address */
        Status = NtQueryInformationThread(WaitStateChange->StateInfo.
                                          CreateProcessInfo.HandleToThread,
                                          ThreadBasicInformation,
                                          &ThreadBasicInfo,
                                          sizeof(ThreadBasicInfo),
                                          NULL);
        if (!NT_SUCCESS(Status))
        {
            /* Failed to get PEB address */
            DebugEvent->u.CreateProcessInfo.lpThreadLocalBase = NULL;
        }
        else
        {
            /* Write PEB Address */
            DebugEvent->u.CreateProcessInfo.lpThreadLocalBase =
                ThreadBasicInfo.TebBaseAddress;
        }

        /* Clear image name */
        DebugEvent->u.CreateProcessInfo.lpImageName = NULL;
        DebugEvent->u.CreateProcessInfo.fUnicode = TRUE;
        break;

    /* Thread exited */
    case DbgExitThreadStateChange:

        /* Write the Win32 debug code and the exit status */
        DebugEvent->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT;
        DebugEvent->u.ExitThread.dwExitCode =
            WaitStateChange->StateInfo.ExitThread.ExitStatus;
        break;

    /* Process exited */
    case DbgExitProcessStateChange:

        /* Write the Win32 debug code and the exit status */
        DebugEvent->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT;
        DebugEvent->u.ExitProcess.dwExitCode =
            WaitStateChange->StateInfo.ExitProcess.ExitStatus;
        break;

    /* Any sort of exception */
    case DbgExceptionStateChange:
    case DbgBreakpointStateChange:
    case DbgSingleStepStateChange:

        /* Check if this was a debug print */
        if (WaitStateChange->StateInfo.Exception.ExceptionRecord.
                ExceptionCode == DBG_PRINTEXCEPTION_C)
        {
            /* Set the Win32 code */
            DebugEvent->dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT;

            /* Copy debug string information */
            DebugEvent->u.DebugString.lpDebugStringData =
                (PVOID)WaitStateChange->
                StateInfo.Exception.ExceptionRecord.
                ExceptionInformation[1];
            DebugEvent->u.DebugString.nDebugStringLength =
                WaitStateChange->StateInfo.Exception.ExceptionRecord.
                ExceptionInformation[0];
            DebugEvent->u.DebugString.fUnicode = FALSE;
        }
        else if (WaitStateChange->StateInfo.Exception.ExceptionRecord.
                 ExceptionCode == DBG_RIPEXCEPTION)
        {
            /* Set the Win32 code */
            DebugEvent->dwDebugEventCode = RIP_EVENT;

            /* Set exception information */
            DebugEvent->u.RipInfo.dwType =
                WaitStateChange->StateInfo.Exception.ExceptionRecord.
                ExceptionInformation[1];
            DebugEvent->u.RipInfo.dwError =
                WaitStateChange->StateInfo.Exception.ExceptionRecord.
                ExceptionInformation[0];
        }
        else
        {
            /* Otherwise, this is a debug event, copy info over */
            DebugEvent->dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
            DebugEvent->u.Exception.ExceptionRecord =
                WaitStateChange->StateInfo.Exception.ExceptionRecord;
            DebugEvent->u.Exception.dwFirstChance =
                WaitStateChange->StateInfo.Exception.FirstChance;
        }
        break;

    /* DLL Load */
    case DbgLoadDllStateChange:

        /* Set the Win32 debug code */
        DebugEvent->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT;

        /* Copy the rest of the data */
        DebugEvent->u.LoadDll.lpBaseOfDll =
            WaitStateChange->StateInfo.LoadDll.BaseOfDll;
        DebugEvent->u.LoadDll.hFile =
            WaitStateChange->StateInfo.LoadDll.FileHandle;
        DebugEvent->u.LoadDll.dwDebugInfoFileOffset =
            WaitStateChange->StateInfo.LoadDll.DebugInfoFileOffset;
        DebugEvent->u.LoadDll.nDebugInfoSize =
            WaitStateChange->StateInfo.LoadDll.DebugInfoSize;

        /* Open the thread */
        InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
        Status = NtOpenThread(&ThreadHandle,
                              THREAD_QUERY_INFORMATION,
                              &ObjectAttributes,
                              &WaitStateChange->AppClientId);
        if (NT_SUCCESS(Status))
        {
            /* Query thread information */
            Status = NtQueryInformationThread(ThreadHandle,
                                              ThreadBasicInformation,
                                              &ThreadBasicInfo,
                                              sizeof(ThreadBasicInfo),
                                              NULL);
            NtClose(ThreadHandle);
        }

        /* Check if we got thread information */
        if (NT_SUCCESS(Status))
        {
            /* Save the image name from the TIB */
            DebugEvent->u.LoadDll.lpImageName =
                ((PTEB)ThreadBasicInfo.TebBaseAddress)->
                NtTib.ArbitraryUserPointer;
        }
        else
        {
            /* Otherwise, no name */
            DebugEvent->u.LoadDll.lpImageName = NULL;
        }

        /* It's Unicode */
        DebugEvent->u.LoadDll.fUnicode = TRUE;
        break;

    /* DLL Unload */
    case DbgUnloadDllStateChange:

        /* Set Win32 code and DLL Base */
        DebugEvent->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT;
        DebugEvent->u.UnloadDll.lpBaseOfDll =
            WaitStateChange->StateInfo.UnloadDll.BaseAddress;
        break;

    /* Anything else, fail */
    default:
        return STATUS_UNSUCCESSFUL;
    }

    /* Return success */
    return STATUS_SUCCESS;
}
Example #27
0
VOID PhpUpdateThreadDetails(
    _In_ HWND hwndDlg,
    _In_ PPH_THREADS_CONTEXT Context,
    _In_ BOOLEAN Force
    )
{
    PPH_THREAD_ITEM *threads;
    ULONG numberOfThreads;
    PPH_THREAD_ITEM threadItem;
    PPH_STRING startModule = NULL;
    PPH_STRING started = NULL;
    WCHAR kernelTime[PH_TIMESPAN_STR_LEN_1] = L"N/A";
    WCHAR userTime[PH_TIMESPAN_STR_LEN_1] = L"N/A";
    PPH_STRING contextSwitches = NULL;
    PPH_STRING cycles = NULL;
    PPH_STRING state = NULL;
    WCHAR priority[PH_INT32_STR_LEN_1] = L"N/A";
    WCHAR basePriority[PH_INT32_STR_LEN_1] = L"N/A";
    PWSTR ioPriority = L"N/A";
    PWSTR pagePriority = L"N/A";
    WCHAR idealProcessor[PH_INT32_STR_LEN + 1 + PH_INT32_STR_LEN + 1] = L"N/A";
    HANDLE threadHandle;
    SYSTEMTIME time;
    IO_PRIORITY_HINT ioPriorityInteger;
    ULONG pagePriorityInteger;
    PROCESSOR_NUMBER idealProcessorNumber;
    ULONG suspendCount;

    PhGetSelectedThreadItems(&Context->ListContext, &threads, &numberOfThreads);

    if (numberOfThreads == 1)
        threadItem = threads[0];
    else
        threadItem = NULL;

    PhFree(threads);

    if (numberOfThreads != 1 && !Force)
        return;

    if (numberOfThreads == 1)
    {
        startModule = threadItem->StartAddressFileName;

        PhLargeIntegerToLocalSystemTime(&time, &threadItem->CreateTime);
        started = PhaFormatDateTime(&time);

        PhPrintTimeSpan(kernelTime, threadItem->KernelTime.QuadPart, PH_TIMESPAN_HMSM);
        PhPrintTimeSpan(userTime, threadItem->UserTime.QuadPart, PH_TIMESPAN_HMSM);

        contextSwitches = PhaFormatUInt64(threadItem->ContextSwitchesDelta.Value, TRUE);

        if (WINDOWS_HAS_CYCLE_TIME)
            cycles = PhaFormatUInt64(threadItem->CyclesDelta.Value, TRUE);

        if (threadItem->State != Waiting)
        {
            if ((ULONG)threadItem->State < MaximumThreadState)
                state = PhaCreateString(PhKThreadStateNames[(ULONG)threadItem->State]);
            else
                state = PhaCreateString(L"Unknown");
        }
        else
        {
            if ((ULONG)threadItem->WaitReason < MaximumWaitReason)
                state = PhaConcatStrings2(L"Wait:", PhKWaitReasonNames[(ULONG)threadItem->WaitReason]);
            else
                state = PhaCreateString(L"Waiting");
        }

        PhPrintInt32(priority, threadItem->Priority);
        PhPrintInt32(basePriority, threadItem->BasePriority);

        if (NT_SUCCESS(PhOpenThread(&threadHandle, ThreadQueryAccess, threadItem->ThreadId)))
        {
            if (NT_SUCCESS(PhGetThreadIoPriority(threadHandle, &ioPriorityInteger)) &&
                ioPriorityInteger < MaxIoPriorityTypes)
            {
                ioPriority = PhIoPriorityHintNames[ioPriorityInteger];
            }

            if (NT_SUCCESS(PhGetThreadPagePriority(threadHandle, &pagePriorityInteger)) &&
                pagePriorityInteger <= MEMORY_PRIORITY_NORMAL)
            {
                pagePriority = PhPagePriorityNames[pagePriorityInteger];
            }

            if (NT_SUCCESS(NtQueryInformationThread(threadHandle, ThreadIdealProcessorEx, &idealProcessorNumber, sizeof(PROCESSOR_NUMBER), NULL)))
            {
                PH_FORMAT format[3];

                PhInitFormatU(&format[0], idealProcessorNumber.Group);
                PhInitFormatC(&format[1], ':');
                PhInitFormatU(&format[2], idealProcessorNumber.Number);
                PhFormatToBuffer(format, 3, idealProcessor, sizeof(idealProcessor), NULL);
            }

            if (threadItem->WaitReason == Suspended && NT_SUCCESS(NtQueryInformationThread(threadHandle, ThreadSuspendCount, &suspendCount, sizeof(ULONG), NULL)))
            {
                PH_FORMAT format[4];

                PhInitFormatSR(&format[0], state->sr);
                PhInitFormatS(&format[1], L" (");
                PhInitFormatU(&format[2], suspendCount);
                PhInitFormatS(&format[3], L")");
                state = PH_AUTO(PhFormat(format, 4, 30));
            }

            NtClose(threadHandle);
        }
    }

    if (Force)
    {
        // These don't change...

        SetDlgItemText(hwndDlg, IDC_STARTMODULE, PhGetStringOrEmpty(startModule));
        EnableWindow(GetDlgItem(hwndDlg, IDC_OPENSTARTMODULE), !!startModule);

        SetDlgItemText(hwndDlg, IDC_STARTED, PhGetStringOrDefault(started, L"N/A"));
    }

    SetDlgItemText(hwndDlg, IDC_KERNELTIME, kernelTime);
    SetDlgItemText(hwndDlg, IDC_USERTIME, userTime);
    SetDlgItemText(hwndDlg, IDC_CONTEXTSWITCHES, PhGetStringOrDefault(contextSwitches, L"N/A"));
    SetDlgItemText(hwndDlg, IDC_CYCLES, PhGetStringOrDefault(cycles, L"N/A"));
    SetDlgItemText(hwndDlg, IDC_STATE, PhGetStringOrDefault(state, L"N/A"));
    SetDlgItemText(hwndDlg, IDC_PRIORITY, priority);
    SetDlgItemText(hwndDlg, IDC_BASEPRIORITY, basePriority);
    SetDlgItemText(hwndDlg, IDC_IOPRIORITY, ioPriority);
    SetDlgItemText(hwndDlg, IDC_PAGEPRIORITY, pagePriority);
    SetDlgItemText(hwndDlg, IDC_IDEALPROCESSOR, idealProcessor);
}
Example #28
0
/*++
 * @name CsrSbCreateSession
 *
 * The CsrSbCreateSession API is called by the Session Manager whenever a new
 * session is created.
 *
 * @param ApiMessage
 *        Pointer to the Session Manager API Message.
 *
 * @return TRUE in case of success, FALSE otherwise.
 *
 * @remarks The CsrSbCreateSession routine will initialize a new CSR NT
 *          Session and allocate a new CSR Process for the subsystem process.
 *
 *--*/
BOOLEAN
NTAPI
CsrSbCreateSession(IN PSB_API_MSG ApiMessage)
{
    PSB_CREATE_SESSION_MSG CreateSession = &ApiMessage->CreateSession;
    HANDLE hProcess, hThread;
    PCSR_PROCESS CsrProcess;
    NTSTATUS Status;
    KERNEL_USER_TIMES KernelTimes;
    PCSR_THREAD CsrThread;
    //PVOID ProcessData;
    //ULONG i;

    /* Save the Process and Thread Handles */
    hProcess = CreateSession->ProcessInfo.ProcessHandle;
    hThread = CreateSession->ProcessInfo.ThreadHandle;

    /* Lock the Processes */
    CsrAcquireProcessLock();

    /* Allocate a new process */
    CsrProcess = CsrAllocateProcess();
    if (!CsrProcess)
    {
        /* Fail */
        ApiMessage->ReturnValue = STATUS_NO_MEMORY;
        CsrReleaseProcessLock();
        return TRUE;
    }

    /* Set the exception port */
    Status = NtSetInformationProcess(hProcess,
                                     ProcessExceptionPort,
                                     &CsrApiPort,
                                     sizeof(HANDLE));

    /* Check for success */
    if (!NT_SUCCESS(Status))
    {
        /* Fail the request */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();

        /* Strange as it seems, NTSTATUSes are actually returned */
        return (BOOLEAN)STATUS_NO_MEMORY;
    }

    /* Get the Create Time */
    Status = NtQueryInformationThread(hThread,
                                      ThreadTimes,
                                      &KernelTimes,
                                      sizeof(KERNEL_USER_TIMES),
                                      NULL);

    /* Check for success */
    if (!NT_SUCCESS(Status))
    {
        /* Fail the request */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();

        /* Strange as it seems, NTSTATUSes are actually returned */
        return (BOOLEAN)Status;
    }

    /* Allocate a new Thread */
    CsrThread = CsrAllocateThread(CsrProcess);
    if (!CsrThread)
    {
        /* Fail the request */
        CsrDeallocateProcess(CsrProcess);
        CsrReleaseProcessLock();

        ApiMessage->ReturnValue = STATUS_NO_MEMORY;
        return TRUE;
    }

    /* Setup the Thread Object */
    CsrThread->CreateTime = KernelTimes.CreateTime;
    CsrThread->ClientId = CreateSession->ProcessInfo.ClientId;
    CsrThread->ThreadHandle = hThread;
    ProtectHandle(hThread);
    CsrThread->Flags = 0;

    /* Insert it into the Process List */
    CsrInsertThread(CsrProcess, CsrThread);

    /* Setup Process Data */
    CsrProcess->ClientId = CreateSession->ProcessInfo.ClientId;
    CsrProcess->ProcessHandle = hProcess;
    CsrProcess->NtSession = CsrAllocateNtSession(CreateSession->SessionId);

    /* Set the Process Priority */
    CsrSetBackgroundPriority(CsrProcess);
#if 0
    /* Get the first data location */
    ProcessData = &CsrProcess->ServerData[CSR_SERVER_DLL_MAX];

    /* Loop every DLL */
    for (i = 0; i < CSR_SERVER_DLL_MAX; i++)
    {
        /* Check if the DLL is loaded and has Process Data */
        if (CsrLoadedServerDll[i] && CsrLoadedServerDll[i]->SizeOfProcessData)
        {
            /* Write the pointer to the data */
            CsrProcess->ServerData[i] = ProcessData;

            /* Move to the next data location */
            ProcessData = (PVOID)((ULONG_PTR)ProcessData +
                                  CsrLoadedServerDll[i]->SizeOfProcessData);
        }
        else
        {
            /* Nothing for this Process */
            CsrProcess->ServerData[i] = NULL;
        }
    }
#else
    /* HACKZ: should go in BaseSrv part of CreateCallback done in Insert below */
    RtlInitializeCriticalSection(&CsrProcess->HandleTableLock);
#endif
    /* Insert the Process */
    CsrInsertProcess(NULL, NULL, CsrProcess);

    /* Activate the Thread */
    ApiMessage->ReturnValue = NtResumeThread(hThread, NULL);

    /* Release lock and return */
    CsrReleaseProcessLock();
    return TRUE;
}
Example #29
0
/******************************************************************
 *		fetch_thread_info
 *
 * fetches some information about thread of id 'tid'
 */
static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
                              const MINIDUMP_EXCEPTION_INFORMATION* except,
                              MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
{
    DWORD                       tid = dc->threads[thd_idx].tid;
    HANDLE                      hThread;
    THREAD_BASIC_INFORMATION    tbi;

    memset(ctx, 0, sizeof(*ctx));

    mdThd->ThreadId = tid;
    mdThd->SuspendCount = 0;
    mdThd->Teb = 0;
    mdThd->Stack.StartOfMemoryRange = 0;
    mdThd->Stack.Memory.DataSize = 0;
    mdThd->Stack.Memory.Rva = 0;
    mdThd->ThreadContext.DataSize = 0;
    mdThd->ThreadContext.Rva = 0;
    mdThd->PriorityClass = dc->threads[thd_idx].prio_class;
    mdThd->Priority = dc->threads[thd_idx].curr_prio;

    if ((hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid)) == NULL)
    {
        FIXME("Couldn't open thread %u (%u)\n", tid, GetLastError());
        return FALSE;
    }
    
    if (NtQueryInformationThread(hThread, ThreadBasicInformation,
                                 &tbi, sizeof(tbi), NULL) == STATUS_SUCCESS)
    {
        mdThd->Teb = (ULONG_PTR)tbi.TebBaseAddress;
        if (tbi.ExitStatus == STILL_ACTIVE)
        {
            if (tid != GetCurrentThreadId() &&
                (mdThd->SuspendCount = SuspendThread(hThread)) != (DWORD)-1)
            {
                ctx->ContextFlags = CONTEXT_FULL;
                if (!GetThreadContext(hThread, ctx))
                    memset(ctx, 0, sizeof(*ctx));

                fetch_thread_stack(dc, tbi.TebBaseAddress, ctx, &mdThd->Stack);
                ResumeThread(hThread);
            }
            else if (tid == GetCurrentThreadId() && except)
            {
                CONTEXT lctx, *pctx;
                mdThd->SuspendCount = 1;
                if (except->ClientPointers)
                {
                    EXCEPTION_POINTERS      ep;

                    ReadProcessMemory(dc->hProcess, except->ExceptionPointers,
                                      &ep, sizeof(ep), NULL);
                    ReadProcessMemory(dc->hProcess, ep.ContextRecord,
                                      &lctx, sizeof(lctx), NULL);
                    pctx = &lctx;
                }
                else pctx = except->ExceptionPointers->ContextRecord;

                *ctx = *pctx;
                fetch_thread_stack(dc, tbi.TebBaseAddress, pctx, &mdThd->Stack);
            }
            else mdThd->SuspendCount = 0;
        }
    }
    CloseHandle(hThread);
    return TRUE;
}
Example #30
0
BOOL GetThreadIDHTASKALIAS(
    DWORD  dwThreadID32,
    HTASKALIAS *ha
) {
    OBJECT_ATTRIBUTES   obja;
    THREAD_BASIC_INFORMATION ThreadInfo;
    HANDLE      hThread;
    NTSTATUS    Status;
    FILETIME    ftDummy;
    CLIENT_ID   cid;

    InitializeObjectAttributes(
            &obja,
            NULL,
            0,
            NULL,
            0 );

    cid.UniqueProcess = 0;      // Don't know it, 0 means any process
    cid.UniqueThread  = (HANDLE)dwThreadID32;

    Status = NtOpenThread(
                &hThread,
                THREAD_QUERY_INFORMATION,
                &obja,
                &cid );

    if ( !NT_SUCCESS(Status) ) {
#if DBG
        DbgPrint("WOW32: Could not get open thread handle\n");
#endif
        return( FALSE );
    }

    Status = NtQueryInformationThread(
        hThread,
        ThreadBasicInformation,
        (PVOID)&ThreadInfo,
        sizeof(THREAD_BASIC_INFORMATION),
        NULL
        );

    ha->dwProcessID32 = (DWORD)ThreadInfo.ClientId.UniqueProcess;
    ha->dwThreadID32  = dwThreadID32;

    GetThreadTimes( hThread,
        &ha->ftCreationTime,
        &ftDummy,
        &ftDummy,
        &ftDummy );

    Status = NtClose( hThread );
    if ( !NT_SUCCESS(Status) ) {
#if DBG
        DbgPrint("WOW32: Could not close thread handle\n");
        DbgBreakPoint();
#endif
        return( FALSE );
    }
    return( TRUE );
}