C++ 如何获取给定进程的窗口站?
比如说,如果我有一个进程ID或其句柄,我可以获取进程运行的路径吗?下面的链接可能会有所帮助:C++ 如何获取给定进程的窗口站?,c++,c,windows,winapi,C++,C,Windows,Winapi,比如说,如果我有一个进程ID或其句柄,我可以获取进程运行的路径吗?下面的链接可能会有所帮助: 进程不会在窗口站下运行,而是窗口站与进程“关联”。不是直接的,但请尝试以下操作: 调用枚举与调用进程处于同一会话中的可用窗口站(如果需要在另一会话中查询进程,则此操作将不起作用) 对于每个窗口站,调用枚举其桌面 对于每个桌面,调用枚举其顶级窗口 对于每个窗口,调用以获取其进程ID,并将其与正在查找的ID进行比较 另一种选择可能是执行以下操作: 调用以从目标进程ID获取句柄 调用以检索进程结构的地址 调
进程不会在窗口站下运行,而是窗口站与进程“关联”。不是直接的,但请尝试以下操作:
句柄
PEB
。它是ProcessParams。DesktopName
字段包含当前与该进程关联的工作站/桌面的名称(在MSDN中还有更多可用字段)DesktopName
以提取窗口站和桌面名称似乎没有任何直接的方法可以找到与给定进程关联的窗口站 我看到两种选择:
- 使用代码注入在目标进程中运行
,然后运行GetProcessWindowsStation
GetUserObjectInformation
- 使用
、enumWindowsStations
和EnumDesktops
在会话中迭代所有窗口;然后使用EnumDesktopWindows
并将进程ID与目标进程的ID进行比较。当然,如果进程当前没有窗口,这将不起作用GetWindowThreadProcessId
您还可以尝试使用
GetThreadDesktop
和GetUserObjectInformation
获取桌面名称;我不确定这是否包括窗口站的名称。如果这确实有效,请参阅MSDN中的以枚举属于该进程的线程。好的,这不是为胆小鬼准备的。这是我在@RemyLebeau的建议下得出的代码。事实证明,对于32/64位进程,我需要以不同的方式执行此操作。我找不到64位进程的确切PEB结构,所以我做了一些基本的反向工程来匹配它
这也是一个非常有趣的结果:
Winsta0\Default
Default
常规输入桌面的默认值(您现在使用的)
或Winlogon
用于安全桌面(例如,Windows登录屏幕)Winsta0\Winlogon
或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());
}