想做一个类似于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;
}
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;
}
解决方案 »
- 使用HttpSendRequestEx的post上传文件, 微软文章编号177188的例子运行失败
- map问题
- 为什么我电脑上找不到RemoteData控件
- 请问如何用VC把 Access 表导出到 Excel 表里去?
- 当自己的对话框被激活,该事件是哪个?
- 这样使用Hook怎么会编译不过?
- 自己写了个简单的com dll,不知道怎么在vc中调用
- 系统关闭时候,发给每个进程什么消息啊?
- ListBox
- CWnd::GetScrollInfo()报错
- [HELP]把 Recordset 保存为 IStream 出错……
- 程序退出时总是中断在atlsimpstr.h的void Release() throw()函数处?
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
看来至少在xp下不是这么回事啊,楼主有答案了吗
{
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);
}
目前能行得通的办法只有把程序作成服务了。
比如用这种方法运行的regedit.exe可以直接看到sam下的内容。具体方法网上
有,或者可以参考我blog即将发表的文章。