想做一个类似于windows的任务管理器的东东,要像任务管理器一样可以得到每个进程的用户名,OpenProcess只能打开当前用户的进程,对于用户名为SYSTEM、Local Service、Net Service等的进程都OpenProcess失败,于是我写了个EnableDebugPrivilege函数来提升为debug权限,可是好像还是没有用,OpenProcess时还是失败,另外对于像当前用户的进程OpenProcess返回都是正确,相关代码如下:望高手们能够多多帮忙下啊,谢谢了!!
inline BOOL CProcessViewDlg::EnableDebugPrivilege(BOOL fEnable) 
{
   // Enabling the debug privilege allows the application to see
   // information about service applications
   BOOL fOk = FALSE;    // Assume function fails
   HANDLE hToken;   // Try to open this process's access token
   if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, 
      &hToken)) {      // Attempt to modify the "Debug" privilege
      TOKEN_PRIVILEGES tp;
      tp.PrivilegeCount = 1;
      LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
      tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
      AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
      fOk = (GetLastError() == ERROR_SUCCESS);
      CloseHandle(hToken);
   }
   return(fOk);
}// 更新CListCtrl中的进程列表
// 返回当前进程总数
DWORD CProcessViewDlg::RefreshProcessesList()
{
if ( m_ctrlprocess.GetItemCount() > 0 ) 
{
m_ctrlprocess.DeleteAllItems();
}
//Get Processes Infomation List
ULONG  ulCount,processID;
HANDLE   hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);   
if( hSnapShot == INVALID_HANDLE_VALUE )
{
MessageBox("创建快照失败!","提示!",MB_OK);
return( FALSE );
}
EnableDebugPrivilege(TRUE);
PROCESSENTRY32*   processInfo=new   PROCESSENTRY32;   
processID = 0;   
ulCount = 0;
processInfo->dwSize=sizeof(PROCESSENTRY32);    
while( Process32Next(hSnapShot,processInfo) != FALSE )   
{    
ulCount++;
processID   =   processInfo->th32ProcessID;  
CString str = "";
str.Format("%d",processID);
int nIndex = m_ctrlprocess.InsertItem( ulCount, str);
m_ctrlprocess.SetItemText( nIndex,1,processInfo->szExeFile);
HANDLE   token;
HANDLE   hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID);
if( hProcess == NULL )   
{   
// delete   processInfo;   
// return ulCount;
}   
if(OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&token))
{
if(ImpersonateLoggedOnUser(token))
{
TCHAR  infoBuf[INFO_BUFFER_SIZE];
DWORD  bufCharCount = INFO_BUFFER_SIZE;
GetUserName(infoBuf,&bufCharCount);
RevertToSelf();
m_ctrlprocess.SetItemText( nIndex,2,infoBuf);
}
}
CloseHandle(token);
}   

CloseHandle(hSnapShot);
delete processInfo;
EnableDebugPrivilege(FALSE);
return ulCount;
}

解决方案 »

  1.   

    管理员权限?可是不是先增加为debug权限么?另外,我当前用的这个系统用户就是管理员权限的啊~~
      

  2.   

    http://www.zhongts.net/MyEssay/AdminToSystem.htm
      

  3.   

    不会吧?这样才只是获得了SYSTEM的权限?那对于那些什么Net Service和Local Service不是都要获取一遍??问题是出在这儿么?OpenProcess难道只能打开当前用户下的进程?要打开所有的进程没有一个简单的方法么?其实我只是想像任务管理器一样获取到每个进程的用户名,我想用的是OpenProcessToken然后再用GetUserName来得到用户名,只是为了OpenProcessToken的第一个传入参数我才要打开OpenProcess来获得每个进程的进程句柄的,如果高手们有些简单的常用的获得进程用户名的方法可以帮忙告诉我一下,不胜感激啊!!
      

  4.   

    EnableDebugPrivilege不知道你怎么写的,一般情况下是: TOKEN_PRIVILEGES tp;
    HANDLE hToken;
    LUID luid; // 
    // enable debug privilege
    //  if(!OpenProcessToken(GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES,
    &hToken ))
    {
    return NULL;
    } if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
    {
    return NULL;
    } tp.PrivilegeCount           = 1;
    tp.Privileges[0].Luid       = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_USED_FOR_ACCESS; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
    NULL, NULL ); if (GetLastError() != ERROR_SUCCESS)
    {
    return NULL;
    }另外, OpenProcess不要用ALL_ACCESS,不就只是查询吗?用QUERY_INFORMATION
      

  5.   

    yjgx007,你写的和我写的是差不多的啊?可是为什么我的在OpenProcess时就不成功呢?另外,我已经试过了你说的只用查询的QUERY_INFORMATION还是不行呢~~
      

  6.   

    我试了一下,确实是有问题,以前都是看到说提升到debug权限就能访问系统进程
    看来至少在xp下不是这么回事啊,楼主有答案了吗
      

  7.   

    void RaisePrivilege()
    {
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if(OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))
    {
    if(LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid))
    {
    AdjustTokenPrivileges(hToken,FALSE,&tp,NULL,NULL,0);
    }
    }
    if(hToken)
    CloseHandle(hToken);
    }
    我的为什么没有问题可以通过openprocess获得句柄取得文件名
    void PrintProcessNameAndID(DWORD processID)
    {
    TCHAR szProcessName[MAX_PATH] = _T("<unknown>");
      HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS/* | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ*/,FALSE,processID);     
    //Process name.
      if(NULL!=hProcess)
      {
    HMODULE hMod;
        DWORD cbNeeded;
        if(EnumProcessModules(hProcess,&hMod,sizeof(hMod), &cbNeeded))         
        {
    GetModuleBaseName(hProcess,hMod,szProcessName,sizeof(szProcessName)/sizeof(TCHAR));                        
        }
      }
    wprintf(_T("PID: %d (%s)\n"),processID,szProcessName);
      CloseHandle(hProcess);
    }
      

  8.   

    不知道你是什么系统,虽然没有具体的资料,但是感觉好像xp sp2以后应该是把这个权限给封掉了,2003,vista统统不行,好像是除了服务程序天生就是system账户运行的以外,其他的程序就算是加上了debug权限,也没办法完全控制system账户运行的进程。
      

  9.   

    试过,加不上,还试过在程序里面获得system权限用户的token来createprocessasuser也不行
    目前能行得通的办法只有把程序作成服务了。
      

  10.   

    你直接创建一个system token 的进程,用它来open。
      

  11.   

    怎么创建一个system token的进程阿,你说的是找到一个system进程的token,复制以后用createprocessasuser?,这样也不行啊,打开系统进程复制token的时候就出错了
      

  12.   

    不是这样,用你说的方法好像不可以。我的方法是截获传送给NtCreateProcess的token,然后改成system's token即可,
    比如用这种方法运行的regedit.exe可以直接看到sam下的内容。具体方法网上
    有,或者可以参考我blog即将发表的文章。
      

  13.   

    楼主,你的问题解决了没有,我也遇到同样问题了,提升了DEBUG权限也不行,OPENPROCESS错误码由5变成了87,SNAPSHOT由5变成299