偷藏星光赠你 2024-08-17 10:32 采纳率: 40%
浏览 4

C++降权执行外部程序崩溃

向各位咨询个问题:有个外部程序无需管理员权限即可正常双击运行(无界面)。但是当system权限的服务程序,降权获取当前用户的令牌去执行该外部程序,当该用户无管理员权限时,被启动的外部程序总是崩溃,崩溃模块ntdll.dll,但是当该用户赋予了管理员权限后,则被启动的程序正常运行,这个问题该如何分析解决?

执行CMD,notepad不会出现异常,该外部程序有联网,读写文件需求。


BOOL GetTokenByName(HANDLE &hToken, LPSTR lpName)
{
    if (!lpName)
    {
        return FALSE;
    }

    HANDLE hProcessSnap = NULL;
    BOOL bRet = FALSE;
    PROCESSENTRY32 pe32 = { 0 };

    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
        return FALSE;

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(hProcessSnap, &pe32))
    {
        char szExeFile[260];
        char szName[260];

        do
        {
            // 将文件名和目标名称转换为大写
            strcpy_s(szExeFile, pe32.szExeFile);
            strcpy_s(szName, lpName);
            _strupr_s(szExeFile, sizeof(szExeFile) - 1);
            _strupr_s(szName, sizeof(szName) - 1);

            if (strcmp(szExeFile, szName) == 0)
            {
                HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
                if (hProcess)
                {
                    bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
                    CloseHandle(hProcess);
                }
                CloseHandle(hProcessSnap);
                return bRet;
            }
        } while (Process32Next(hProcessSnap, &pe32));
    }

    CloseHandle(hProcessSnap);
    return FALSE;
}
void StartProcessAsCurrentUser(LPCSTR lpImage)
{
    HANDLE hToken;
    if (!GetTokenByName(hToken, (LPSTR)"EXPLORER.EXE"))
    {
        return;
    }
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    //si.lpDesktop = (LPSTR)TEXT("winsta0\\default");
    si.lpDesktop = NULL;

    BOOL bResult = CreateProcessAsUser(hToken, NULL, (LPSTR)lpImage, NULL, NULL,
        FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
    
    if (bResult)
    {
        OutputDebugString("CreateProcessAsUser ok!\r");
    }
    else
    {
        OutputDebugString("CreateProcessAsUser false!\r");
    }
    CloseHandle(hToken);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}
  • 写回答

1条回答 默认 最新

  • 一直免费一直爽 2024-08-17 10:33
    关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    这个问题可能是由于降权执行外部程序时,权限不足导致的。当用户没有管理员权限时,程序可能无法访问某些资源或执行某些操作。为了解决这个问题,你可以尝试以下方法:

    1. 确保外部程序的清单文件(例如:app.exe.manifest)中包含了所需的权限。你可以在Visual Studio中编辑清单文件,或者手动创建一个包含所需权限的清单文件。例如,如果你的程序需要读写文件和联网,你可以在清单文件中添加以下内容:
    <requestedExecutionLevel level="asInvoker" uiAccess="false" />
    
    1. 在调用CreateProcessAsUser之前,确保你的服务具有足够的权限来创建进程。你可以使用AdjustTokenPrivileges函数来提升服务的权限。例如:
    BOOL EnablePrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL bEnable)
    {
        TOKEN_PRIVILEGES tp;
        LUID luid;
    
        if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid))
            return FALSE;
    
        tp.PrivilegeCount = 1;
        tp.Privileges[0].Luid = luid;
        tp.Privileges[0].Attributes = (bEnable ? SE_PRIVILEGE_ENABLED : 0);
    
        return AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
    }
    
    void StartProcessAsCurrentUser(LPCSTR lpImage)
    {
        HANDLE hToken;
        if (!GetTokenByName(hToken, (LPSTR)"EXPLORER.EXE"))
        {
            return;
        }
    
        // 提升权限
        EnablePrivilege(hToken, SE_DEBUG_NAME, TRUE);
        EnablePrivilege(hToken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE);
        EnablePrivilege(hToken, SE_INCREASE_QUOTA_NAME, TRUE);
        EnablePrivilege(hToken, SE_TCB_NAME, TRUE);
    
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
    
        ZeroMemory(&si, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
        si.lpDesktop = NULL;
    
        BOOL bResult = CreateProcessAsUser(hToken, NULL, (LPSTR)lpImage, NULL, NULL,
            FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
        
        if (bResult)
        {
            OutputDebugString("CreateProcessAsUser ok!\r");
        }
        else
        {
            OutputDebugString("CreateProcessAsUser false!\r");
        }
        CloseHandle(hToken);
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    
    1. 如果问题仍然存在,你可以尝试以管理员身份运行服务。这样,服务将具有足够的权限来执行外部程序。但是,请注意,以管理员身份运行服务可能会带来安全风险,因此请确保你了解这些风险并采取适当的安全措施。
    评论

报告相同问题?

问题事件

  • 创建了问题 8月17日

悬赏问题

  • ¥100 HALCON DELPHI
  • ¥15 (需要远程,AI不回)VB6二进制文件转换成功,但是C#转换总是失败
  • ¥15 关于#matlab#的问题:有没有什么其他办法能够保证不退出进程(相关搜索:matlab调用)
  • ¥15 依据报错在原代吗格式的基础上解决问题
  • ¥15 在虚拟机中安装flash code
  • ¥15 单片机stm32f10x编写光敏电阻调节3.3伏大功率灯亮度(光强越大灯越暗,白天正常光强灯不亮,使用ADC,PWM等模块)望各位找一下错误或者提供一个可实现功能的代码
  • ¥20 verilog状态机方法流水灯
  • ¥15 pandas代码实现不了意图
  • ¥15 GD32H7 从存储器到外设SPI传输数据无法重复启用DMA
  • ¥25 LT码在高斯信道下的误码率仿真