Example #1
0
// Determine (if possible) whether a debugger is attached to the target process
HRESULT WindowsNativePipeline::IsRemoteDebuggerPresent(DWORD processId, BOOL* pfDebuggerPresent)
{
#if !defined(FEATURE_CORESYSTEM)

    // Get a process handle for the process ID.
    HandleHolder hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, processId);
    if (hProc == NULL)
        return HRESULT_FROM_GetLastError();

    // Delay-bind to CheckRemoteDebuggerPresent - WinXP SP1 and above only
    HModuleHolder hKernel32;
    hKernel32 = WszLoadLibrary(W("kernel32"));
    if (hKernel32 == NULL)
        return HRESULT_FROM_GetLastError();

    typedef BOOL (*CheckRemoteDebuggerPresentSig) (HANDLE, PBOOL);
    CheckRemoteDebuggerPresentSig pCheckRemoteDebuggerPresent = 
        reinterpret_cast<CheckRemoteDebuggerPresentSig>(GetProcAddress(hKernel32, "CheckRemoteDebuggerPresent"));
    if (pCheckRemoteDebuggerPresent == NULL)
        return HRESULT_FROM_GetLastError();

    // API exists - call it
    if (!pCheckRemoteDebuggerPresent(hProc, pfDebuggerPresent))
        return HRESULT_FROM_GetLastError();

    return S_OK;
#else

	//CoreSystem doesn't have this API
	return E_FAIL;
#endif
}
Example #2
0
// Detach
HRESULT WindowsNativePipeline::DebugActiveProcessStop(DWORD processId)
{
#if !defined(FEATURE_CORESYSTEM)
    // Late-bind to DebugActiveProcessStop since it's WinXP and above only
    HModuleHolder hKernel32;
    hKernel32 = WszLoadLibrary(W("kernel32"));
    if (hKernel32 == NULL)
        return HRESULT_FROM_GetLastError();

    typedef BOOL (*DebugActiveProcessStopSig) (DWORD);
    DebugActiveProcessStopSig pDebugActiveProcessStop = 
        reinterpret_cast<DebugActiveProcessStopSig>(GetProcAddress(hKernel32, "DebugActiveProcessStop"));

    // Win2K will fail here - can't find DebugActiveProcessStop
    if (pDebugActiveProcessStop == NULL)
        return HRESULT_FROM_GetLastError();

    // Ok, the API exists, call it
    if (!pDebugActiveProcessStop(processId))
    {
        // Detach itself failed
        return HRESULT_FROM_GetLastError();
    }
#else
	// The API exists, call it
    if (!::DebugActiveProcessStop(processId))
    {
        // Detach itself failed
        return HRESULT_FROM_GetLastError();
    }
#endif
    return S_OK;
}
Example #3
0
// Resume any suspended threads (but just once)
HRESULT WindowsNativePipeline::EnsureThreadsRunning()
{
#ifdef FEATURE_CORESYSTEM
	_ASSERTE("NYI");
	return E_FAIL;
#else
    _ASSERTE(m_dwProcessId != 0);

    // Take a snapshot of all running threads (similar to ShimProcess::QueueFakeThreadAttachEventsNativeOrder)
    // Alternately we could return thread creation/exit in WaitForDebugEvent.  But we expect this to be used 
    // very rarely, so no need to complicate more common codepaths.
    HANDLE hThreadSnap = INVALID_HANDLE_VALUE; 
    THREADENTRY32 te32; 

    hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 
    if (hThreadSnap == INVALID_HANDLE_VALUE) 
        return HRESULT_FROM_GetLastError();

    // HandleHolder doesn't deal with INVALID_HANDLE_VALUE, so we only assign if we have a legal value.
    HandleHolder hSnapshotHolder(hThreadSnap);

    // Fill in the size of the structure before using it. 
    te32.dwSize = sizeof(THREADENTRY32); 

    // Retrieve information about the first thread, and exit if unsuccessful
    if (!Thread32First(hThreadSnap, &te32)) 
        return HRESULT_FROM_GetLastError();

    // Now walk the thread list of the system and attempt to resume any that are part of this process
    // Ignore errors - this is a best effort (but ASSERT in CHK builds since we don't expect errors
    // in practice - we expect the process to be frozen at a debug event, so no races etc.)

    HRESULT hr = S_FALSE;   // no thread was resumed
    do 
    { 
        if (te32.th32OwnerProcessID == m_dwProcessId)
        {
            HandleHolder hThread = ::OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID);
            _ASSERTE(hThread != NULL);
            if (hThread != NULL)
            {
                // Resume each thread exactly once (if they were suspended multiple times, 
                // then EnsureThreadsRunning would need to be called multiple times until it
                // returned S_FALSE.
                DWORD prevCount = ::ResumeThread(hThread);
                _ASSERTE(prevCount >= 0);
                if (prevCount >= 1)
                    hr = S_OK;      // some thread was resumed
            }
        }
    } while(Thread32Next(hThreadSnap, &te32)); 

    return hr;
#endif
}
Example #4
0
HRESULT DbgTransportTarget::CreateProcess(LPCWSTR lpApplicationName,
                          LPCWSTR lpCommandLine,
                          LPSECURITY_ATTRIBUTES lpProcessAttributes,
                          LPSECURITY_ATTRIBUTES lpThreadAttributes,
                          BOOL bInheritHandles,
                          DWORD dwCreationFlags,
                          LPVOID lpEnvironment,
                          LPCWSTR lpCurrentDirectory,
                          LPSTARTUPINFOW lpStartupInfo,
                          LPPROCESS_INFORMATION lpProcessInformation)
{

    BOOL result = WszCreateProcess(lpApplicationName, 
                                   lpCommandLine,
                                   lpProcessAttributes,
                                   lpThreadAttributes,
                                   bInheritHandles,
                                   dwCreationFlags,
                                   lpEnvironment,
                                   lpCurrentDirectory,
                                   lpStartupInfo,
                                   lpProcessInformation);

    if (!result) 
    {
        return HRESULT_FROM_GetLastError();
    }

    return S_OK;
}
Example #5
0
INT32 QCALLTYPE COMPrincipal::ImpersonateLoggedOnUser(HANDLE hToken)
{
    QCALL_CONTRACT;

    HRESULT hr = S_OK;

    BEGIN_QCALL;

#ifdef FEATURE_INCLUDE_ALL_INTERFACES
        IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
        if (pSM) {
            BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
            hr = pSM->ImpersonateLoggedOnUser(hToken);
            END_SO_TOLERANT_CODE_CALLING_HOST;
        }
        else 
#endif // FEATURE_INCLUDE_ALL_INTERFACES
        {
            if (!::ImpersonateLoggedOnUser(hToken))
                hr = HRESULT_FROM_GetLastError();
        }

    STRESS_LOG2(LF_SECURITY, LL_INFO100, "COMPrincipal::ImpersonateLoggedOnUser called with hTokenSAFE = %d. Returning 0x%x\n",hToken,hr);

    END_QCALL;

    return hr;
}
Example #6
0
STDAPI GetRealProcAddress(LPCSTR pwszProcName, VOID** ppv)
{
    if(!ppv) 
    { 
        return E_POINTER; 
    } 

    HMODULE hLib = GetLibrary(LIB_mscorwks);
    if(hLib == NULL)
    {
        return HRESULT_FROM_GetLastError();
    }

    *ppv = (void*) GetProcAddress(hLib,pwszProcName);
    if(*ppv == NULL)
    {
        return HRESULT_FROM_GetLastError();
    }
    return S_OK;
}
Example #7
0
//--------------------------------------------------------------------------------------
// Free's the handle to a boundary descriptor, a SID and a handle to a privatenamespace
//--------------------------------------------------------------------------------------
HRESULT IPCShared::FreeHandles(HANDLE & hBoundaryDescriptor, PSID & pSID, HANDLE & hPrivateNamespace)
{
    WRAPPER_NO_CONTRACT;
    HRESULT hr = S_OK;

    hr = IPCShared::FreeHandles(hBoundaryDescriptor,pSID);
    if(!SUCCEEDED(hr))
        return hr;
    if(hPrivateNamespace != NULL) 
    {
        static HMODULE hKernel32 = NULL;
        if(hKernel32 == NULL)
            hKernel32 = WszGetModuleHandle(L"kernel32.dll");
        if(hKernel32 == NULL)
        {
            hr = HRESULT_FROM_GetLastError();
            return hr;
        }
        typedef WINBASEAPI BOOL (WINAPI CLOSE_PRIVATE_NAMESPACE)(HANDLE, ULONG);
        static CLOSE_PRIVATE_NAMESPACE * pClosePrivateNamespace;
        if(pClosePrivateNamespace == NULL)
            pClosePrivateNamespace = (CLOSE_PRIVATE_NAMESPACE *)GetProcAddress(hKernel32, "ClosePrivateNamespace");
        _ASSERTE(pClosePrivateNamespace != NULL);
        if (pClosePrivateNamespace == NULL)
        {
            hr = ERROR_PROC_NOT_FOUND;
        }
        else
        {
            BOOL isClosed = (*pClosePrivateNamespace)(hPrivateNamespace,0);
            hPrivateNamespace = NULL;
            if(!isClosed)
            {
                hr = HRESULT_FROM_GetLastError();
            }
            
        }
    }

    return hr;
}
Example #8
0
int LoadNativeStringResource(const NativeStringResourceTable &nativeStringResourceTable, unsigned int iResourceID, WCHAR* szBuffer, int iMax, int *pcwchUsed)
{
    int len = 0;
    if (szBuffer && iMax)
    {
        // Search the sorted set of resources for the ID we're interested in.
        NativeStringResource searchEntry = {iResourceID, NULL};
        NativeStringResource *resourceEntry = (NativeStringResource*)bsearch(
            &searchEntry,
            nativeStringResourceTable.table,
            nativeStringResourceTable.size,
            sizeof(NativeStringResource),
            CompareNativeStringResources);

        if (resourceEntry != NULL)
        {
            len = PAL_GetResourceString(NULL, resourceEntry->resourceString, szBuffer, iMax);
            if (len == 0)
            {
                int hr = HRESULT_FROM_GetLastError();

                // Tell the caller if the buffer isn't big enough
                if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) && pcwchUsed)
                    *pcwchUsed = iMax;
                    
                return hr;
            }
        }
        else
        {
            // The resource ID wasn't found in our array. Fall back on returning the ID as a string.
            len = _snwprintf_s(szBuffer, iMax, _TRUNCATE, W("[Undefined resource string ID:0x%X]"), iResourceID);
            if (len < 0)
            {   
                // The only possible failure is that that string didn't fit the buffer. So the buffer contains 
                // partial string terminated by '\0'
                // We could return ERROR_INSUFFICIENT_BUFFER, but we'll error on the side of caution here and
                // actually show something (given that this is likely a scenario involving a bug/deployment issue)
                len = iMax - 1;
            }
        }
    }

    if (pcwchUsed)
    {
        *pcwchUsed = len;
    }

    return S_OK;
}
Example #9
0
// Attach the debugger to this process.
HRESULT WindowsNativePipeline::DebugActiveProcess(MachineInfo machineInfo, DWORD processId)
{
    HRESULT hr = E_FAIL;
    BOOL ret = ::DebugActiveProcess(processId);

    if (ret)
    {
        hr = S_OK;
        m_dwProcessId = processId;
        UpdateDebugSetProcessKillOnExit();
    }
    else
    {
        hr = HRESULT_FROM_GetLastError();

        // There are at least two scenarios in which DebugActiveProcess() returns E_INVALIDARG: 
        //     1) if the specified process doesn't exist, or
        //     2) if the specified process already has a debugger atttached
        // We need to distinguish these two cases in order to return the correct HR.
        if (hr == E_INVALIDARG)
        {
            // Check whether a debugger is known to be already attached.
            // Note that this API won't work on some OSes, in which case we err on the side of returning E_INVALIDARG
            // even though a debugger may be attached.  Another approach could be to assume that if
            // OpenProcess succeeded, then DebugActiveProcess must only have failed because a debugger is
            // attached.  But I think it's better to only return the specific error code if we know for sure
            // the case is true.
            BOOL fIsDebuggerPresent = FALSE;
            if (SUCCEEDED(IsRemoteDebuggerPresent(processId, &fIsDebuggerPresent)))
            {
                if (fIsDebuggerPresent)
                {
                    hr = CORDBG_E_DEBUGGER_ALREADY_ATTACHED;
                }
            }
        }
    }

    return hr;
}
Example #10
0
    HRESULT FileOrDirectoryExists(PathString &path)
    {
        HRESULT hr = S_FALSE;

        DWORD dwFileAttributes = WszGetFileAttributes(path.GetUnicode());
        if (dwFileAttributes == INVALID_FILE_ATTRIBUTES)
        {
            hr = HRESULT_FROM_GetLastError();

            if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
                (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)))
            {
                hr = S_FALSE;
            }
        }
        else
        {
            hr = S_TRUE;
        }

        return hr;
    }
Example #11
0
//-----------------------------------------------------------------------------
// Free's the handle to a boundary descriptor and a SID
//-----------------------------------------------------------------------------
HRESULT IPCShared::FreeHandles(HANDLE & hBoundaryDescriptor, PSID & pSID)
{
    WRAPPER_NO_CONTRACT;
    HRESULT hr = S_OK;
    if(hBoundaryDescriptor != NULL) 
    {
        static HMODULE hKernel32 = NULL;
        if(hKernel32 == NULL)
            hKernel32 = WszGetModuleHandle(L"kernel32.dll");
        if(hKernel32 == NULL)
        {
            hr = HRESULT_FROM_GetLastError();
            return hr;
        }
        typedef WINBASEAPI VOID (WINAPI DELETE_BOUNDARY_DESCRIPTOR)(HANDLE);
        static DELETE_BOUNDARY_DESCRIPTOR * pDeleteBoundaryDescriptor = NULL;
        if(pDeleteBoundaryDescriptor == NULL) 
            pDeleteBoundaryDescriptor = (DELETE_BOUNDARY_DESCRIPTOR *)GetProcAddress(hKernel32, "DeleteBoundaryDescriptor");
        _ASSERTE(pDeleteBoundaryDescriptor != NULL);
        if (pDeleteBoundaryDescriptor == NULL)
        {
            hr = ERROR_PROC_NOT_FOUND;
        }
        else 
        {
            (*pDeleteBoundaryDescriptor)(hBoundaryDescriptor);
            hBoundaryDescriptor = NULL;
    
        }
    }
    if(pSID != NULL)
    {
        FreeSid(pSID);
        pSID = NULL;
    }

    return hr;
}
Example #12
0
// Create an process under the debugger.
HRESULT WindowsNativePipeline::CreateProcessUnderDebugger(
    MachineInfo machineInfo,
    LPCWSTR lpApplicationName,
    LPCWSTR lpCommandLine,
    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    BOOL bInheritHandles,
    DWORD dwCreationFlags,
    LPVOID lpEnvironment,
    LPCWSTR lpCurrentDirectory,
    LPSTARTUPINFOW lpStartupInfo,
    LPPROCESS_INFORMATION lpProcessInformation)
{
    // This is always doing Native-debugging at the OS-level.
    dwCreationFlags |= (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS);

    BOOL ret = ::WszCreateProcess(
          lpApplicationName,
          lpCommandLine,
          lpProcessAttributes,
          lpThreadAttributes,
          bInheritHandles,
          dwCreationFlags,
          lpEnvironment,
          lpCurrentDirectory,
          lpStartupInfo,
          lpProcessInformation);
    if (!ret)
    {
        return HRESULT_FROM_GetLastError();
    }

    m_dwProcessId = lpProcessInformation->dwProcessId;
    UpdateDebugSetProcessKillOnExit();
    return S_OK;    
}
Example #13
0
// Create an process under the debugger.
HRESULT DbgTransportPipeline::CreateProcessUnderDebugger(
    MachineInfo machineInfo,
    LPCWSTR lpApplicationName,
    LPCWSTR lpCommandLine,
    LPSECURITY_ATTRIBUTES lpProcessAttributes,
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    BOOL bInheritHandles,
    DWORD dwCreationFlags,
    LPVOID lpEnvironment,
    LPCWSTR lpCurrentDirectory,
    LPSTARTUPINFOW lpStartupInfo,
    LPPROCESS_INFORMATION lpProcessInformation)
{
    // INativeEventPipeline has a 1:1 relationship with CordbProcess.
    _ASSERTE(!IsTransportRunning());

    // We don't support interop-debugging on the Mac.
    _ASSERTE(!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)));

    // When we're using a transport we can't deal with creating a suspended process (we need the process to
    // startup in order that it can start up a transport thread and reply to our messages).
    _ASSERTE(!(dwCreationFlags & CREATE_SUSPENDED));

    // Connect to the debugger proxy on the remote machine and ask it to create a process for us.
    HRESULT hr  = E_FAIL;

    m_pProxy = g_pDbgTransportTarget;
    hr = m_pProxy->CreateProcess(lpApplicationName,
                                 lpCommandLine,
                                 lpProcessAttributes,
                                 lpThreadAttributes,
                                 bInheritHandles,
                                 dwCreationFlags,
                                 lpEnvironment,
                                 lpCurrentDirectory,
                                 lpStartupInfo,
                                 lpProcessInformation);

    if (SUCCEEDED(hr))
    {
        // Establish a connection to the actual runtime to be debugged.
        hr = m_pProxy->GetTransportForProcess(lpProcessInformation->dwProcessId, 
                                              &m_pTransport, 
                                              &m_hProcess);
        if (SUCCEEDED(hr))
        {
            // Wait for the connection to become useable (or time out).
            if (!m_pTransport->WaitForSessionToOpen(10000))
            {
                hr = CORDBG_E_TIMEOUT;
            }
            else
            {
                if (!m_pTransport->UseAsDebugger(&m_ticket))
                {
                    hr = CORDBG_E_DEBUGGER_ALREADY_ATTACHED;
                }
            }
        }
    }

    if (SUCCEEDED(hr))
    {
        _ASSERTE((m_hProcess != NULL) && (m_hProcess != INVALID_HANDLE_VALUE));

        m_dwProcessId = lpProcessInformation->dwProcessId;

        // For Mac remote debugging, we don't actually have a process handle to hand back to the debugger.
        // Instead, we return a handle to an event as the "process handle".  The Win32 event thread also waits
        // on this event handle, and the event will be signaled when the proxy notifies us that the process
        // on the remote machine is terminated.  However, normally the debugger calls CloseHandle() immediately 
        // on the "process handle" after CreateProcess() returns.  Doing so causes the Win32 event thread to
        // continue waiting on a closed event handle, and so it will never wake up.  
        // (In fact, in Whidbey, we also duplicate the process handle in code:CordbProcess::Init.)
        if (!DuplicateHandle(GetCurrentProcess(), 
                             m_hProcess,
                             GetCurrentProcess(), 
                             &(lpProcessInformation->hProcess), 
                             0,      // ignored since we are going to pass DUPLICATE_SAME_ACCESS
                             FALSE, 
                             DUPLICATE_SAME_ACCESS))
        {
            hr = HRESULT_FROM_GetLastError();
        }
    }

    if (SUCCEEDED(hr))
    {
        m_fRunning = TRUE;
    }
    else
    {
        Dispose();
    }

    return hr;
}
Example #14
0
//-----------------------------------------------------------------------------
// Based on the pid, write a unique name for the IPCBlockTable on Vista and Higher
//-----------------------------------------------------------------------------
HRESULT IPCShared::GenerateBlockTableName(DWORD pid, SString & sName, HANDLE & pBoundaryDesc, HANDLE & pPrivateNamespace, PSID* pSID, BOOL bCreate)
{
    WRAPPER_NO_CONTRACT;
    HRESULT hr = E_FAIL;

#define SIZE 100
    const WCHAR * szFormat = CorSxSPublicIPCBlock;
    static HMODULE hKernel32 = NULL;
    if(hKernel32 == NULL)
        hKernel32 = WszGetModuleHandle(L"kernel32.dll");
    if(hKernel32 == NULL)
    {
        hr = HRESULT_FROM_GetLastError();
        return hr;
    }
    //We are using static function pointers so that we dont call GetProcAddress every time
    //We know that the Writer will call this function only once and the reader (perfmon) is a single
    //threaded App. Therefore its safe to assign static local variables in this case. 
    typedef WINBASEAPI BOOL (WINAPI ADD_SID_TO_BOUNDARY_DESCRIPTOR)(HANDLE*, PSID);
    static ADD_SID_TO_BOUNDARY_DESCRIPTOR * pAddSIDToBoundaryDescriptor = NULL;

    typedef WINBASEAPI HANDLE (WINAPI CREATE_BOUNDARY_DESCRIPTOR)(LPCWSTR,ULONG);
    static CREATE_BOUNDARY_DESCRIPTOR * pCreateBoundaryDescriptor = NULL;
    
    typedef WINBASEAPI HANDLE (WINAPI CREATE_PRIVATE_NAMESPACE )(LPSECURITY_ATTRIBUTES, LPVOID, LPCWSTR);
    static CREATE_PRIVATE_NAMESPACE * pCreatePrivateNamespace = NULL;

    typedef WINBASEAPI HANDLE (WINAPI OPEN_PRIVATE_NAMESPACE)(LPVOID,LPCWSTR);
    static OPEN_PRIVATE_NAMESPACE * pOpenPrivateNamespace = NULL;

    if(pAddSIDToBoundaryDescriptor == NULL)
        pAddSIDToBoundaryDescriptor = (ADD_SID_TO_BOUNDARY_DESCRIPTOR *)GetProcAddress(hKernel32, "AddSIDToBoundaryDescriptor"); 
    if(pCreateBoundaryDescriptor == NULL)
        pCreateBoundaryDescriptor = (CREATE_BOUNDARY_DESCRIPTOR *)GetProcAddress(hKernel32, "CreateBoundaryDescriptorW"); 
    if(pCreatePrivateNamespace == NULL)
        pCreatePrivateNamespace = (CREATE_PRIVATE_NAMESPACE *)GetProcAddress(hKernel32, "CreatePrivateNamespaceW"); 
    if(pOpenPrivateNamespace==NULL)
        pOpenPrivateNamespace = (OPEN_PRIVATE_NAMESPACE *)GetProcAddress(hKernel32, "OpenPrivateNamespaceW");
    _ASSERTE((pAddSIDToBoundaryDescriptor != NULL) && 
            (pCreateBoundaryDescriptor != NULL) && 
            (pCreatePrivateNamespace != NULL) && 
            (pOpenPrivateNamespace != NULL));

    if ((pAddSIDToBoundaryDescriptor == NULL) || 
            (pCreateBoundaryDescriptor == NULL) || 
            (pCreatePrivateNamespace == NULL) || 
            (pOpenPrivateNamespace == NULL))
    {
        return ERROR_PROC_NOT_FOUND;
    }

    WCHAR wsz[SIZE];
    swprintf_s(wsz,SIZE, CorSxSBoundaryDescriptor, pid);

    ULONG flags = 0;
    if (RunningOnWin8())
    {
        // on win8 we specify this flag regardless if the process is inside an appcontainer, the kernel will do the right thing.
        // note that for appcontainers this flag is necessary regardless of producer or consumer, ie you can't create a boundary
        // descriptor in an appcontainer process without adding the appcontainer SID (the API call will fail).
        flags |= CREATE_BOUNDARY_DESCRIPTOR_ADD_APPCONTAINER_SID;
    }

    pBoundaryDesc = (*pCreateBoundaryDescriptor)((LPCWSTR)&wsz, flags);
    if(!pBoundaryDesc)
    {
        hr = HRESULT_FROM_GetLastError();
        return hr;
    }        
    SID_IDENTIFIER_AUTHORITY SIDWorldAuth = SECURITY_WORLD_SID_AUTHORITY;
    if(!AllocateAndInitializeSid( &SIDWorldAuth, 1,SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, pSID)) 
    {
         hr = HRESULT_FROM_GetLastError();
         return hr;
    }
    if(!(*pAddSIDToBoundaryDescriptor) (&pBoundaryDesc,*pSID))
    {
        hr = HRESULT_FROM_GetLastError();
        return hr;
    }

#ifndef FEATURE_CORECLR
    // when pid != GetCurrentProcessId() it means we're the consumer opening other process perf counter data
    if (pid != GetCurrentProcessId())
    {
        // if the target process is inside an appcontainer we need to add the appcontainer SID to the boundary descriptor.
        NewArrayHolder<BYTE> pbTokenMem;
        hr = AppX::GetAppContainerTokenInfoForProcess(pid, pbTokenMem);

        if (FAILED(hr))
        {
            // failed to open the target's process, continue on
            // assuming that the process isn't in an AppContainer.
            _ASSERTE(pbTokenMem == NULL);
        }
        else
        {
            if (hr == S_FALSE)
            {
                // not an appcontainer
                _ASSERTE(pbTokenMem == NULL);
            }
            else
            {
                // process is an appcontainer so add the SID
                PTOKEN_APPCONTAINER_INFORMATION pAppContainerTokenInfo =
                    reinterpret_cast<PTOKEN_APPCONTAINER_INFORMATION>(pbTokenMem.GetValue());
                _ASSERTE(pAppContainerTokenInfo);
                _ASSERTE(pAppContainerTokenInfo->TokenAppContainer);

                if (!(*pAddSIDToBoundaryDescriptor)(&pBoundaryDesc, pAppContainerTokenInfo->TokenAppContainer))
                    return HRESULT_FROM_WIN32(GetLastError());
            }
        }
    }
#endif // FEATURE_CORECLR
    
    if(bCreate)
    {
        SECURITY_ATTRIBUTES *pSA = NULL;
        IPCShared::CreateWinNTDescriptor(pid, FALSE, &pSA, PrivateNamespace, eDescriptor_Public);
        pPrivateNamespace = (*pCreatePrivateNamespace)(pSA, (VOID *)(pBoundaryDesc), 
                                                        (LPCWSTR)CorSxSWriterPrivateNamespacePrefix);
        if(!pPrivateNamespace)
        { 
            hr = HRESULT_FROM_GetLastError();
        }
        IPCShared::DestroySecurityAttributes(pSA);

        if(!pPrivateNamespace)
        { 
            //if already created by a different version of the runtime we return OK.
            if(hr ==HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS))
            {
                hr = S_OK;
            }
            else
            {
                return hr;
            }
        }
     }
     else
     {
        pPrivateNamespace = (*pOpenPrivateNamespace)((VOID *)(pBoundaryDesc), (LPCWSTR)CorSxSReaderPrivateNamespacePrefix);
        if(!pPrivateNamespace)
        { 
            hr = HRESULT_FROM_GetLastError();
            return hr;
        }
     }
    szFormat = (bCreate ? CorSxSWriterPrivateNamespacePrefix L"\\"  CorSxSVistaPublicIPCBlock : CorSxSReaderPrivateNamespacePrefix L"\\"  CorSxSVistaPublicIPCBlock);
    sName.Printf(szFormat);
    hr=S_OK;

    return hr;
}
Example #15
0
HRESULT IPCShared::CreateWinNTDescriptor(DWORD pid, BOOL bRestrictiveACL, SECURITY_ATTRIBUTES **ppSA, KernelObject whatObject, EDescriptorType descType)
{
    WRAPPER_NO_CONTRACT;

    HRESULT hr = NO_ERROR;

    // Gotta have a place to stick the new SA...
    if (ppSA == NULL)
    {
        _ASSERTE(!"Caller must supply ppSA");
        return E_INVALIDARG;
    }

    *ppSA = NULL;

    ACL *pACL = NULL;
    SECURITY_DESCRIPTOR *pSD = NULL;
    SECURITY_ATTRIBUTES *pSA = NULL;

    // Allocate a SD.
    _ASSERTE (SECURITY_DESCRIPTOR_MIN_LENGTH == sizeof(SECURITY_DESCRIPTOR));
    pSD = new (nothrow) SECURITY_DESCRIPTOR;

    if (pSD == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto errExit;
    }

    // Do basic SD initialization
    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
    {
        hr = HRESULT_FROM_GetLastError();
        goto errExit;
    }

    // Grab the ACL for the IPC block for the given process
    if (!InitializeGenericIPCAcl(pid, bRestrictiveACL, &pACL, whatObject, descType))
    {
        hr = E_FAIL;
        goto errExit;
    }

    // Add the ACL as the DACL for the SD.
    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
    {
        hr = HRESULT_FROM_GetLastError();
        goto errExit;
    }

    // Allocate a SA.
    pSA = new (nothrow) SECURITY_ATTRIBUTES;

    if (pSA == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto errExit;
    }

    // Pass out the new SA.
    *ppSA = pSA;

    pSA->nLength = sizeof(SECURITY_ATTRIBUTES);
    pSA->lpSecurityDescriptor = pSD;
    pSA->bInheritHandle = FALSE;

    // uncomment this line if you want to see the DACL being generated.
    //DumpSD(pSD);

errExit:
    if (FAILED(hr))
    {
        if (pACL != NULL)
        {
            for(int i = 0; i < pACL->AceCount; i++)
                DeleteAce(pACL, i);

            delete [] pACL;
        }

        if (pSD != NULL)
            delete pSD;
    }

    return hr;
}
Example #16
0
// Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a runtime in
// that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that can be waited
// on for process termination.
HRESULT DbgTransportTarget::GetTransportForProcess(DWORD                   dwPID,
                                                   DbgTransportSession   **ppTransport,
                                                   HANDLE                 *phProcessHandle)
{
    RSLockHolder lock(&m_sLock);
    HRESULT hr = S_OK;

    ProcessEntry *entry = LocateProcessByPID(dwPID);

    if (entry == NULL)
    {

       NewHolder<ProcessEntry> newEntry = new(nothrow) ProcessEntry();
       if (newEntry == NULL)
           return E_OUTOFMEMORY;

       NewHolder<DbgTransportSession> transport = new(nothrow) DbgTransportSession();
       if (transport == NULL)
       {
           return E_OUTOFMEMORY;
       }


       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
       if (hProcess == NULL)
       {
           transport->Shutdown();
           return HRESULT_FROM_GetLastError();
       }

       // Initialize it (this immediately starts the remote connection process).
       hr = transport->Init(dwPID, hProcess);
       if (FAILED(hr))
       {
           transport->Shutdown();
           CloseHandle(hProcess);
           return hr;
       }

       entry = newEntry;
       newEntry.SuppressRelease();   
       entry->m_dwPID = dwPID;
       entry->m_hProcess = hProcess;
       entry->m_transport = transport;
       transport.SuppressRelease();
       entry->m_cProcessRef = 0;

       // Adding new entry to the list.
       entry->m_pNext = m_pProcessList;
       m_pProcessList = entry;
    }

    entry->m_cProcessRef++;
    _ASSERTE(entry->m_cProcessRef > 0);
    _ASSERTE(entry->m_transport != NULL);
    _ASSERTE(entry->m_hProcess > 0);
    
    *ppTransport = entry->m_transport;
    if (!DuplicateHandle(GetCurrentProcess(), 
                         entry->m_hProcess,
                         GetCurrentProcess(), 
                         phProcessHandle,
                         0,      // ignored since we are going to pass DUPLICATE_SAME_ACCESS
                         FALSE, 
                         DUPLICATE_SAME_ACCESS))
    {
        return HRESULT_FROM_GetLastError();
    }

    return hr;
}
Example #17
0
HRESULT
LoadDataAccessDll(HINSTANCE mscorModule,
                  REFIID ifaceId,
                  ICLRDataTarget* target,
                  HMODULE* dllHandle,
                  void** iface)
{
    HRESULT status;
    WCHAR accessDllPath[MAX_PATH];
    HMODULE accessDll;

    //
    // Load the access DLL from the same directory
    // as the runtime DLL.
    //

    if (!WszGetModuleFileName(mscorModule,
                              accessDllPath, NumItems(accessDllPath)))
    {
        return HRESULT_FROM_GetLastError();
    }

    PWSTR pathTail = wcsrchr(accessDllPath, '\\');
    if (!pathTail)
    {
        return E_INVALIDARG;
    }
    pathTail++;

    PWSTR eeFlavor = L"wks";    
    if (_snwprintf_s(pathTail, _countof(accessDllPath) + (accessDllPath - pathTail),
                   NumItems(accessDllPath) - (pathTail - accessDllPath),
                   MAKEDLLNAME_W(L"mscordac%s"), eeFlavor) <= 0)
    {
        return E_INVALIDARG;
    }

    accessDll = WszLoadLibrary(accessDllPath);
    if (!accessDll)
    {
        return HRESULT_FROM_GetLastError();
    }

    //
    // Get the access interface and have it
    // enumerate the interesting memory in the target process.
    //

    void* ifacePtr;
    PFN_CLRDataCreateInstance entry = (PFN_CLRDataCreateInstance)
        GetProcAddress(accessDll, "CLRDataCreateInstance");
    if (!entry)
    {
        status = HRESULT_FROM_GetLastError();
        FreeLibrary(accessDll);
    }
    else if ((status = entry(ifaceId, target, &ifacePtr)) != S_OK)
    {
        FreeLibrary(accessDll);
    }
    else
    {
        *dllHandle = accessDll;
        *iface = ifacePtr;
    }

    return status;
}