【问题标题】:Get path of Csrss.exe获取 Csrss.exe 的路径
【发布时间】:2020-12-16 00:10:02
【问题描述】:

我想获取指向 Csrss.exe 的 PID 路径。我不能使用 OpenProcess 函数,因为 MSDN 明确指出它将在 Csrss.exe 和 Idle 等进程上返回 ACCESS_DENIED。我试过使用

Process32Next

得到一个

PROCESSENTRY32

结构,它有一个 exeName 字段。但是,这只是可执行文件的名称。您可以通过调用获取完整路径

QueryFullProcessImageName

但是,该函数接受一个 HPROCESS,不幸的是它需要调用 OpenProcess。 我需要这样做,因为我正在尝试验证进程是否是 Microsoft 签名进程,因此我获取了进程的 PID,并且为了检查它是否已签名,我必须获取进程的路径。

【问题讨论】:

  • 当你有debug privillages时尝试调用OpenProcess。
  • 出于好奇,为什么?
  • @Dai 我基本上是在尝试验证在我的安全环境中创建的进程是否是真实的 Windows 应用程序,因为 Windows 有时会在一些地方创建随机进程。

标签: c# c++ .net winapi


【解决方案1】:

事实证明,Vista 及更高版本中新增了用于获取进程路径和新进程访问权限的功能 (PROCESS_QUERY_LIMITED_INFORMATION):

您可以通过此权限获取进程的句柄。示例如下:

#include <Windows.h>
#include <psapi.h>
#include <iostream>
#include <tlhelp32.h>

BOOL SetPrivilege(
    HANDLE hToken,  // token handle 
    LPCTSTR Privilege,  // Privilege to enable/disable 
    BOOL bEnablePrivilege  // TRUE to enable. FALSE to disable 
)
{
    TOKEN_PRIVILEGES tp = { 0 };
    // Initialize everything to zero 
    LUID luid;
    DWORD cb = sizeof(TOKEN_PRIVILEGES);
    if (!LookupPrivilegeValue(NULL, Privilege, &luid))
        return FALSE;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege) {
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    }
    else {
        tp.Privileges[0].Attributes = 0;
    }
    AdjustTokenPrivileges(hToken, FALSE, &tp, cb, NULL, NULL);
    if (GetLastError() != ERROR_SUCCESS)
    {
        std::cout << GetLastError() << std::endl;
        return FALSE;
    }

    return TRUE;
}
int main()
{
    HANDLE curHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
    OpenProcessToken(curHandle, TOKEN_ADJUST_PRIVILEGES, &curHandle);
    BOOL b = SetPrivilege(curHandle, SE_DEBUG_NAME, TRUE);
    wchar_t buf[MAX_PATH] = L"";
    int pid = 668;
    HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
    if (handle)
    {
        GetModuleFileNameExW(handle, 0, buf, MAX_PATH);
        std::wcout << buf << "\n";
    }
    else
    {
        std::cout << "error = " << GetLastError() << std::endl;
    }
    char s[MAX_PATH] = "";
    DWORD len = MAX_PATH;
    if (handle)
    {
        QueryFullProcessImageName(handle, 0, s, &len);
        std::cout << s;
    }
    if (handle)
        CloseHandle(handle);
    return 0;
}

输出:

【讨论】:

  • 感谢您的回答!有机会我会试试的。
  • 嗯,OpenProcess 仍然返回 0。
  • @User12341921 需要开启debug privillages,并以管理员模式运行程序。我改了代码,你可以参考一下。
  • 感谢您更新代码!我试过了,效果很好。但是,唯一的缺点是我必须以管理员身份运行该进程。没有管理员就无法获取csrss.exe路径吗?
  • @User12341921 可以,可以参考here。
猜你喜欢
  • 2011-08-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 2012-11-27
  • 2016-04-13
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多