zoukankan      html  css  js  c++  java
  • 转: CreateProcessAsUser 0xC0000005访问冲突问题

    转:http://blog.csdn.net/glc22/article/details/77227367
     
    在使用CreateProcessAsUser时出现了 0xC0000005访问冲突问题,百思不得其解。终于在子航的博客http://www.cnblogs.com/hezihang/p/3387283.html找到问题根源
     
    错误代码:
    1. #include <WtsApi32.h>  
    2. #pragma comment(lib, "WtsApi32.lib")  
    3.   
    4. bool MyImpersonateLoggedOnUser()  
    5. {  
    6.     HANDLE hToken = NULL;  
    7.     DWORD dwConsoleSessionId = WTSGetActiveConsoleSessionId();  
    8.     if (WTSQueryUserToken(dwConsoleSessionId, &hToken))  
    9.     {  
    10.         if (ImpersonateLoggedOnUser(hToken))  
    11.         {  
    12.             // 保存Token  
    13.             WCHAR *szCmdLine = L"c:\notepad.exe";  //错误在这里  
    14.   
    15.             STARTUPINFO si;  
    16.             ZeroMemory(&si, sizeof(STARTUPINFO));  
    17.             si.cb = sizeof(STARTUPINFO);  
    18.             si.lpDesktop = L"winsta0\default";  
    19.   
    20.             PROCESS_INFORMATION pi;  
    21.             ZeroMemory(&pi, sizeof(pi));  
    22.             // hToken为当前登陆用户的令牌  
    23.             LPVOID lpEnvBlock = NULL;  
    24.             BOOL bEnv = false;// CreateEnvironmentBlock(&lpEnvBlock, hToken, FALSE);  
    25.             DWORD dwFlags = CREATE_NEW_CONSOLE;  
    26.             if (bEnv)  
    27.             {  
    28.                 dwFlags |= CREATE_UNICODE_ENVIRONMENT;  
    29.             }  
    30.             // 环境变量创建失败仍然可以创建进程,但会影响到后面的进程获取环境变量内容  
    31.             bool bRet = CreateProcessAsUser(  
    32.                 hToken,  
    33.                 NULL,  
    34.                 szCmdLine,  
    35.                 NULL,  
    36.                 NULL,  
    37.                 FALSE,  
    38.                 dwFlags,  
    39.                 bEnv ? lpEnvBlock : NULL,  
    40.                 NULL,  
    41.                 &si,  
    42.                 &pi);  
    43.             int a = GetLastError();  
    44.             // 使用完毕需要释放环境变量的空间  
    45.             if (bEnv)  
    46.             {  
    47.                 DestroyEnvironmentBlock(lpEnvBlock);  
    48.             }  
    49.             WaitForSingleObject(pi.hProcess, INFINITE);  
    50.            return true;  
    51.         }  
    52.     }  
    53.     return false;  
    54. }   

    szCmdLine指针是保存在堆上,但字符串“c:\notepad.exe”是一个常量,它是保存在常量区的,被写保护了CreateProcessAsUser 访问堆上的地址出了问题
    如果把“c:\notepad.exe"定义到栈或者全局变量就不存在此问题了。
    修改后的代码:      
    1. #include <WtsApi32.h>  
    2. #pragma comment(lib, "WtsApi32.lib")  
    3. bool MyImpersonateLoggedOnUser()  
    4. {  
    5.     HANDLE hToken = NULL;  
    6.     DWORD dwConsoleSessionId = WTSGetActiveConsoleSessionId();  
    7.     if (WTSQueryUserToken(dwConsoleSessionId, &hToken))  
    8.     {  
    9.         if (ImpersonateLoggedOnUser(hToken))  
    10.         {  
    11.             // 保存Token  
    12.             WCHAR szCmdLine[] = L"c:\notepad.exe";   //改变了szCmdLine的地址空间  
    13.             STARTUPINFO si;  
    14.             ZeroMemory(&si, sizeof(STARTUPINFO));  
    15. si.cb = sizeof(STARTUPINFO);  
    16. si.lpDesktop = L"winsta0\default";  
    17.             PROCESS_INFORMATION pi;  
    18.             ZeroMemory(&pi, sizeof(pi));  
    19.             // hToken为当前登陆用户的令牌  
    20.             LPVOID lpEnvBlock = NULL;  
    21.             BOOL bEnv = false;// CreateEnvironmentBlock(&lpEnvBlock, hToken, FALSE);  
    22.             DWORD dwFlags = CREATE_NEW_CONSOLE;  
    23.             if (bEnv)  
    24.             {  
    25.                 dwFlags |= CREATE_UNICODE_ENVIRONMENT;  
    26.             }  
    27.             // 环境变量创建失败仍然可以创建进程,但会影响到后面的进程获取环境变量内容  
    28.             bool bRet = CreateProcessAsUser(  
    29.                 hToken,  
    30.                 NULL,  
    31.                 szCmdLine,  
    32.                 NULL,  
    33.                 NULL,  
    34.                 FALSE,  
    35.                 dwFlags,  
    36.                 bEnv ? lpEnvBlock : NULL,  
    37.                 NULL,  
    38.                 &si,  
    39.                 &pi);  
    40.             int a = GetLastError();  
    41.             // 使用完毕需要释放环境变量的空间  
    42.             if (bEnv)  
    43.             {  
    44.                 DestroyEnvironmentBlock(lpEnvBlock);  
    45.             }  
    46.                         WaitForSingleObject(pi.hProcess, INFINITE);  
    47.             return true;  
    48.         }  
    49.     }  
    50.     return false;  
    51. }  
  • 相关阅读:
    css相关
    文章管理列表
    高性能MySQL基础篇
    mysql
    node.js开发实战
    React Hooks
    client-*,scroll-*,offset-*的区别
    将create-react-app从javascript迁移到typescript
    为Github项目添加Travis持续集成服务
    cookie储存
  • 原文地址:https://www.cnblogs.com/studyskill/p/7650833.html
Copyright © 2011-2022 走看看