顾乔芝士网

持续更新的前后端开发技术栈

Windows 24H2上livekd无法使用了?

近日同事做调试分析时使用livekd发现用不了,对比了下环境,与系统版本有关,24H2以上的livekd启动有问题,运行后象下图这样就退出了:

我这位同事很牛,他继续调试了livekd,发现是livekd在调用NtQuerySystemInformation去获取ntoskrnl.exe的基址为0,导致不通继续执行。

网上搜了下,是微软在24H2后不允许普通程序获取内核模块地址:

当进程以管理员权限运行并且设置了SeDebugPrivilege为TRUE的情况下,这个问题就解决了。

方法有好几种:

  1. 用Process hacker或SystemInformer中的Runas功能,以System帐号启动livekd
  2. PowerShell以管理员权限运行后,再运行livekd
  3. 写个类似的程序来启动livekd, 附上代码备忘:
#include 
#include 
#include 

bool EnableDebugPrivilege() {
    HANDLE hToken;
    LUID luid;
    TOKEN_PRIVILEGES tokenPrivileges;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        std::cerr << "OpenProcessToken failed: " << GetLastError() << std::endl;
        return false;
    }

    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
        std::cerr << "LookupPrivilegeValue failed: " << GetLastError() << std::endl;
        CloseHandle(hToken);
        return false;
    }

    tokenPrivileges.PrivilegeCount = 1;
    tokenPrivileges.Privileges[0].Luid = luid;
    tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
        std::cerr << "AdjustTokenPrivileges failed: " << GetLastError() << std::endl;
        CloseHandle(hToken);
        return false;
    }

    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
        std::cerr << "The token does not have the specified privilege." << std::endl;
        CloseHandle(hToken);
        return false;
    }

    CloseHandle(hToken);
    return true;
}

bool CreateProcessWithDebugPrivilege(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, STARTUPINFO& si, PROCESS_INFORMATION& pi) {
    HANDLE hToken;
    HANDLE hNewToken;
    LUID luid;
    TOKEN_PRIVILEGES tokenPrivileges;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        std::cerr << "OpenProcessToken failed: " << GetLastError() << std::endl;
        return false;
    }

    if (!DuplicateTokenEx(hToken, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_IMPERSONATE, NULL, SecurityImpersonation, TokenPrimary, &hNewToken)) {
        std::cerr << "DuplicateTokenEx failed: " << GetLastError() << std::endl;
        CloseHandle(hToken);
        return false;
    }

    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
        std::cerr << "LookupPrivilegeValue failed: " << GetLastError() << std::endl;
        CloseHandle(hToken);
        CloseHandle(hNewToken);
        return false;
    }

    tokenPrivileges.PrivilegeCount = 1;
    tokenPrivileges.Privileges[0].Luid = luid;
    tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!AdjustTokenPrivileges(hNewToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
        std::cerr << "AdjustTokenPrivileges failed: " << GetLastError() << std::endl;
        CloseHandle(hToken);
        CloseHandle(hNewToken);
        return false;
    }

    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
        std::cerr << "The token does not have the specified privilege." << std::endl;
        CloseHandle(hToken);
        CloseHandle(hNewToken);
        return false;
    }

    CloseHandle(hToken);

    if (!CreateProcessAsUserW(hNewToken, lpApplicationName, lpCommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
        std::cerr << "CreateProcessAsUserW failed: " << GetLastError() << std::endl;
        CloseHandle(hNewToken);
        return false;
    }

    CloseHandle(hNewToken);
    return true;
}

int main(int argc, char* argv[]) 
{
    if (!EnableDebugPrivilege()) {
        std::cerr << "Failed to enable debug privilege." << std::endl;
        return 1;
    }

    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi;
  
    wchar_t szArgv[MAX_PATH] = { 0 };
    if (argc < 2)
    {
        mbstowcs(szArgv, "c:\\symbols", strlen("c:\\symbols"));
    }
    else
    {
        mbstowcs(szArgv, argv[1], strlen(argv[1]));
    }

    wchar_t szCmdline[MAX_PATH] = { 0 };
    swprintf_s(szCmdline, _countof(szCmdline), L"livekd64.exe -y srv*%s*https://msdl.microsoft.com/download/symbols", szArgv);

    if (CreateProcessWithDebugPrivilege(NULL, szCmdline, si, pi)) {
        std::cout << "Process created with debug privilege." << std::endl;
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    else {
        std::cerr << "Failed to create process." << std::endl;
        return 1;
    }

    return 0;
}
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言