Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何获取给定进程的窗口站?_C++_C_Windows_Winapi - Fatal编程技术网

C++ 如何获取给定进程的窗口站?

C++ 如何获取给定进程的窗口站?,c++,c,windows,winapi,C++,C,Windows,Winapi,比如说,如果我有一个进程ID或其句柄,我可以获取进程运行的路径吗?下面的链接可能会有所帮助: 进程不会在窗口站下运行,而是窗口站与进程“关联”。不是直接的,但请尝试以下操作: 调用枚举与调用进程处于同一会话中的可用窗口站(如果需要在另一会话中查询进程,则此操作将不起作用) 对于每个窗口站,调用枚举其桌面 对于每个桌面,调用枚举其顶级窗口 对于每个窗口,调用以获取其进程ID,并将其与正在查找的ID进行比较 另一种选择可能是执行以下操作: 调用以从目标进程ID获取句柄 调用以检索进程结构的地址 调

比如说,如果我有一个进程ID或其句柄,我可以获取进程运行的路径吗?

下面的链接可能会有所帮助:


进程不会在窗口站下运行,而是窗口站与进程“关联”。

不是直接的,但请尝试以下操作:

  • 调用枚举与调用进程处于同一会话中的可用窗口站(如果需要在另一会话中查询进程,则此操作将不起作用)

  • 对于每个窗口站,调用枚举其桌面

  • 对于每个桌面,调用枚举其顶级窗口

  • 对于每个窗口,调用以获取其进程ID,并将其与正在查找的ID进行比较

  • 另一种选择可能是执行以下操作:

  • 调用以从目标进程ID获取
    句柄

  • 调用以检索进程结构的地址

  • 调用以读取
    PEB
    。它是
    ProcessParams。DesktopName
    字段包含当前与该进程关联的工作站/桌面的名称(在MSDN中还有更多可用字段)

  • 解析
    DesktopName
    以提取窗口站和桌面名称

  • 根据需要枚举工作站,从中查找匹配的名称


  • 似乎没有任何直接的方法可以找到与给定进程关联的窗口站

    我看到两种选择:

    • 使用代码注入在目标进程中运行
      GetProcessWindowsStation
      ,然后运行
      GetUserObjectInformation

    • 使用
      enumWindowsStations
      EnumDesktops
      EnumDesktopWindows
      在会话中迭代所有窗口;然后使用
      GetWindowThreadProcessId
      并将进程ID与目标进程的ID进行比较。当然,如果进程当前没有窗口,这将不起作用


    您还可以尝试使用
    GetThreadDesktop
    GetUserObjectInformation
    获取桌面名称;我不确定这是否包括窗口站的名称。如果这确实有效,请参阅MSDN中的以枚举属于该进程的线程。

    好的,这不是为胆小鬼准备的。这是我在@RemyLebeau的建议下得出的代码。事实证明,对于32/64位进程,我需要以不同的方式执行此操作。我找不到64位进程的确切PEB结构,所以我做了一些基本的反向工程来匹配它

    这也是一个非常有趣的结果:

  • 如果我为自己的进程调用它,我会得到如下结果:
    Winsta0\Default
  • 如果我在其他GUI进程上调用它,我会得到以下结果:
    Default
  • 总体而言,您可以获得以下类型的台式机/winstations:

    • 常规输入桌面的默认值(您现在使用的)
    • Winlogon
      Winsta0\Winlogon
      用于安全桌面(例如,Windows登录屏幕)
    • 或Metro(或现代用户界面)Windows 8应用程序的空字符串
    接下来是代码。如果有人能回顾一下,那就太好了:

    //'dwProcID' = process ID to look up window station for
    HANDLE hProc = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcID);
    if(hProc)
    {
        BOOL (WINAPI *pfnIsWow64Process)(HANDLE, PBOOL);
    
        (FARPROC&)pfnIsWow64Process = ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "IsWow64Process");
    
        SYSTEM_INFO si = {0};
        ::GetNativeSystemInfo(&si);
    
        //See if 32-bit process on 64-bit OS
        BOOL bWow64Proc = TRUE;
        if(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
        {
            if(pfnIsWow64Process)
                if(!pfnIsWow64Process(hProc, &bWow64Proc))
                {
                    //Error
                    _tprintf(L"ERROR in IsWow64Process: %d\n", ::GetLastError());
                }
        }
    
        NTSTATUS ntStatus;
    
    
        if(bWow64Proc)
        {
            //32-bit process
            NTSTATUS (WINAPI *pfnNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
            (FARPROC&)pfnNtQueryInformationProcess = ::GetProcAddress(::GetModuleHandle(L"Ntdll.dll"), "NtQueryInformationProcess");
            if(pfnNtQueryInformationProcess)
            {
                PROCESS_BASIC_INFORMATION pbi = {0};
                DWORD dwsz = 0;
                if((ntStatus = pfnNtQueryInformationProcess(hProc, ProcessBasicInformation, &pbi, sizeof(pbi), &dwsz)) == 0 &&
                    dwsz <= sizeof(pbi) &&
                    pbi.PebBaseAddress)
                {
                    //Define PEB structs
                    typedef struct _RTL_DRIVE_LETTER_CURDIR
                    {
                        WORD Flags;
                        WORD Length;
                        ULONG TimeStamp;
                        STRING DosPath;
                    } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
    
                    struct RTL_USER_PROCESS_PARAMETERS_32
                    {
                        ULONG                   MaximumLength;
                        ULONG                   Length;
                        ULONG                   Flags;
                        ULONG                   DebugFlags;
                        PVOID                   ConsoleHandle;
                        ULONG                   ConsoleFlags;
                        HANDLE                  StdInputHandle;
                        HANDLE                  StdOutputHandle;
                        HANDLE                  StdErrorHandle;
                        UNICODE_STRING          CurrentDirectoryPath;
                        HANDLE                  CurrentDirectoryHandle;
                        UNICODE_STRING          DllPath;
                        UNICODE_STRING          ImagePathName;
                        UNICODE_STRING          CommandLine;
                        PVOID                   Environment;
                        ULONG                   StartingPositionLeft;
                        ULONG                   StartingPositionTop;
                        ULONG                   Width;
                        ULONG                   Height;
                        ULONG                   CharWidth;
                        ULONG                   CharHeight;
                        ULONG                   ConsoleTextAttributes;
                        ULONG                   WindowFlags;
                        ULONG                   ShowWindowFlags;
                        UNICODE_STRING          WindowTitle;
                        UNICODE_STRING          DesktopName;
                        UNICODE_STRING          ShellInfo;
                        UNICODE_STRING          RuntimeData;
                        RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
                    };
    
                    struct PEB_32
                    {
                      BYTE                          Reserved1[2];
                      BYTE                          BeingDebugged;
                      BYTE                          Reserved2[1];
                      PVOID                         Reserved3[2];
                      void*                         Ldr;
                      RTL_USER_PROCESS_PARAMETERS_32* ProcessParameters;
                      BYTE                          Reserved4[104];
                      PVOID                         Reserved5[52];
                      void*                         PostProcessInitRoutine;
                      BYTE                          Reserved6[128];
                      PVOID                         Reserved7[1];
                      ULONG                         SessionId;
                    };
    
                    //Read PEB-32
                    PEB_32 peb32 = {0};
    
                    DWORD dwcbSzRead = 0;
                    if(ReadProcessMemory(hProc, pbi.PebBaseAddress, &peb32, sizeof(peb32), &dwcbSzRead) &&
                        dwcbSzRead == sizeof(peb32) &&
                        peb32.ProcessParameters)
                    {
                        //Read RTL_USER_PROCESS_PARAMETERS_32
                        RTL_USER_PROCESS_PARAMETERS_32 rupp32 = {0};
    
                        dwcbSzRead = 0;
                        if(ReadProcessMemory(hProc, peb32.ProcessParameters, &rupp32, sizeof(rupp32), &dwcbSzRead) &&
                            dwcbSzRead == sizeof(rupp32) &&
                            rupp32.DesktopName.Buffer)
                        {
                            //Get desktop name
                            int ncbSzLn = rupp32.DesktopName.Length + sizeof(TCHAR);
                            BYTE* pDesktopName = new (std::nothrow) BYTE[ncbSzLn];
                            if(pDesktopName)
                            {
                                dwcbSzRead = 0;
                                if(ReadProcessMemory(hProc, rupp32.DesktopName.Buffer, pDesktopName, ncbSzLn, &dwcbSzRead) &&
                                    dwcbSzRead == ncbSzLn)
                                {
                                    //Set last NULL
                                    *(TCHAR*)(pDesktopName + ncbSzLn - sizeof(TCHAR)) = 0;
    
                                    //We're done
                                    _tprintf(L"Desktop32: %s\n", (LPCTSTR)pDesktopName);
                                }
                                else
                                    _tprintf(L"ERROR in ReadProcessMemory DesktopName: %d\n", ::GetLastError());
    
                                delete[] pDesktopName;
                            }
                            else
                                _tprintf(L"ERROR DesktopName ptr\n");
                        }
                        else
                            _tprintf(L"ERROR in ReadProcessMemory RTL_USER_PROCESS_PARAMETERS_32: %d\n", ::GetLastError());
                    }
                    else
                        _tprintf(L"ERROR in ReadProcessMemory PEB-32: %d\n", ::GetLastError());
                }
                else
                    _tprintf(L"ERROR in NtQueryInformationProcess: %d\n", ntStatus);
            }
            else
                _tprintf(L"ERROR NtQueryInformationProcess API\n");
        }
        else
        {
            //64-bit process
            NTSTATUS (WINAPI *pfnNtQueryInformationProcess64)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
            NTSTATUS (WINAPI *pfnNtWow64ReadVirtualMemory64)(HANDLE, PVOID64, PVOID, ULONG64, PULONG64);
    
            (FARPROC&)pfnNtQueryInformationProcess64 = ::GetProcAddress(::GetModuleHandle(L"Ntdll.dll"), "NtWow64QueryInformationProcess64");
            (FARPROC&)pfnNtWow64ReadVirtualMemory64 = ::GetProcAddress(::GetModuleHandle(L"Ntdll.dll"), "NtWow64ReadVirtualMemory64");
    
            if(pfnNtQueryInformationProcess64 &&
                pfnNtWow64ReadVirtualMemory64)
            {
                //Define PEB structs
                struct UNICODE_STRING_64 {
                    USHORT Length;
                    USHORT MaximumLength;
                    PVOID64 Buffer;
                };
    
                struct PROCESS_BASIC_INFORMATION64
                {
                    PVOID Reserved1[2];
                    PVOID64 PebBaseAddress;
                    PVOID Reserved2[4];
                    ULONG_PTR UniqueProcessId[2];
                    PVOID Reserved3[2];
                };
    
                PROCESS_BASIC_INFORMATION64 pbi64 = {0};
                DWORD dwsz = 0;
                if((ntStatus = pfnNtQueryInformationProcess64(hProc, ProcessBasicInformation, &pbi64, sizeof(pbi64), &dwsz)) == 0 &&
                    dwsz <= sizeof(pbi64))
                {
                    struct PEB_64
                    {
                        UCHAR               InheritedAddressSpace;
                        UCHAR               ReadImageFileExecOptions;
                        UCHAR               BeingDebugged;
                        BYTE                b003;
                        ULONG               Reserved0;
                        ULONG64             Mutant;
                        ULONG64             ImageBaseAddress;
                        ULONG64             Ldr;
                        PVOID64             ProcessParameters;
                    };
    
                    //Read PEB-64
                    PEB_64 peb64 = {0};
    
                    ULONG64 uicbSzRead = 0;
                    if(pfnNtWow64ReadVirtualMemory64(hProc, pbi64.PebBaseAddress, &peb64, sizeof(peb64), &uicbSzRead) == 0 &&
                        uicbSzRead == sizeof(peb64) &&
                        peb64.ProcessParameters)
                    {
                        //Don't know the structure of RTL_USER_PROCESS_PARAMETERS_64 thus read raw bytes
                        const int ncbSz_rawRUPP64 = sizeof(DWORD) * (6 * 8) + sizeof(UNICODE_STRING_64);
                        BYTE rawRUPP64[ncbSz_rawRUPP64] = {0};
    
                        uicbSzRead = 0;
                        if(pfnNtWow64ReadVirtualMemory64(hProc, peb64.ProcessParameters, &rawRUPP64, ncbSz_rawRUPP64, &uicbSzRead) == 0 &&
                            uicbSzRead == ncbSz_rawRUPP64)
                        {
                            //Point to the location in raw byte array
                            UNICODE_STRING_64* pDesktopName = (UNICODE_STRING_64*)(rawRUPP64 + sizeof(DWORD) * (6 * 8));
    
                            //Get desktop name
                            int ncbSzLn = pDesktopName->Length + sizeof(TCHAR);
                            BYTE* pBytesDesktopName = new (std::nothrow) BYTE[ncbSzLn];
                            if(pBytesDesktopName)
                            {
                                uicbSzRead = 0;
                                if(pfnNtWow64ReadVirtualMemory64(hProc, pDesktopName->Buffer, pBytesDesktopName, ncbSzLn, &uicbSzRead) == 0 &&
                                    uicbSzRead == ncbSzLn)
                                {
                                    //Set last NULL
                                    *(TCHAR*)(pBytesDesktopName + ncbSzLn - sizeof(TCHAR)) = 0;
                                    LPCTSTR pStrDesktopName = (LPCTSTR)pBytesDesktopName;
    
                                    //We're done
                                    _tprintf(L"Desktop64: %s\n", pStrDesktopName);
                                }
                                else
                                    _tprintf(L"ERROR in NtWow64ReadVirtualMemory64 DesktopName: %d\n", ::GetLastError());
    
                                delete[] pBytesDesktopName;
                            }
                            else
                                _tprintf(L"ERROR DesktopName64 ptr\n");
                        }
                        else
                            _tprintf(L"ERROR in NtWow64ReadVirtualMemory64 RTL_USER_PROCESS_PARAMETERS_32: %d\n", ::GetLastError());
                    }
                    else
                        _tprintf(L"ERROR in NtWow64ReadVirtualMemory64 PEB-64: %d\n", ::GetLastError());
                }
                else
                    _tprintf(L"ERROR in NtQueryInformationProcess64: %d\n", ntStatus);
            }
            else
                _tprintf(L"ERROR NtWow64QueryInformationProcess64 API\n");
        }
    
        ::CloseHandle(hProc);
    }
    else
        _tprintf(L"ERROR in OpenProcess: %d\n", ::GetLastError());
    
    /'dwProcID'=要查找窗口站的进程ID
    HANDLE hProc=::OpenProcess(进程查询信息|进程虚拟机读取,FALSE,dwProcID);
    如果(hProc)
    {
    BOOL(WINAPI*pfnIsWow64Process)(句柄,PBOOL);
    (FARPROC&)pfnIsWow64Process=::GetProcAddress(::GetModuleHandle(L“kernel32.dll”),“IsWow64Process”);
    系统信息si={0};
    ::GetNativeSystemInfo(&si);
    //查看64位操作系统上的32位进程
    BOOL bWow64Proc=TRUE;
    if(si.wProcessorArchitecture==处理器体系结构AMD64)
    {
    if(PFNISWOW64过程)
    if(!pfnIsWow64Process(hProc和bWow64Proc))
    {
    //错误
    _tprintf(L“ISWOW64进程中的错误:%d\n”,::GetLastError());
    }
    }
    NTSTATUS NTSTATUS;
    如果(bWow64Proc)
    {
    //32位进程
    NTSTATUS(WINAPI*pfnNtQueryInformationProcess)(句柄、PROCESSINFOCLASS、PVOID、ULONG、PULONG);
    (FARPROC&)pfnNtQueryInformationProcess=::GetProcAddress(::GetModuleHandle(L“Ntdll.dll”),“NtQueryInformationProcess”);
    if(pfnNtQueryInformationProcess)
    {
    进程基本信息pbi={0};
    DWORD dwsz=0;
    如果((ntStatus=pfnNtQueryInformationProcess(hProc、ProcessBasicInformation和pbi、sizeof(pbi和dwsz))==0&&
    dwsz长度+尺寸(TCHAR);
    BYTE*pBytesDesktopName=新(std::nothrow)字节[ncbSzLn];
    if(pBytesDesktopName)
    {
    uicbSzRead=0;
    如果(pfnNtWow64ReadVirtualMemory64(hProc、pDesktopName->Buffer、pBytesDesktopName、ncbSzLn和uicbSzRead)==0&&
    uicbSzRead==ncbSzLn)
    {
    //设置最后一个空值
    *(TCHAR*)(pBytesDesktopName+ncbSzLn-sizeof(TCHAR))=0;
    LPCTSTR pStrDesktopName=(LPCTSTR)pBytesDesktopName;
    //我们结束了
    _tprintf(L“Desktop64:%s\n”,pStrDesktopName);
    }
    其他的
    _tprintf(L“NtWow64ReadVirtualMemory64桌面名中的错误:%d\n”,::GetLastError());
    删除[]pBytesDesktopName;
    }
    其他的
    _tprintf(L“错误桌面名称64 ptr\n”);
    }
    其他的
    _tprintf(L“NtWow64ReadVirtualMemory64 RTL_用户_进程_参数_32:%d\n中的错误,::GetLastError());
    }