您的位置:首页 > 其它

枚举当前系统进程以及进程加载模块

2011-04-03 21:11 483 查看
枚举当前系统进程的方法大致分一下几个步骤:

一、 提升应用程序的进程权限

]///////////////自定义函数实现/////////////////

BOOL PromotePrivilege(BOOL bEnable)
{
// 附给本进程特权,以便访问系统进程
HANDLE hToken;

// 打开一个进程的访问令牌
if(::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
// 取得特权名称为"SetDebugPrivilege"的LUID
LUID uID;
if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &uID))
{
return FALSE;
}

// 调整特权级别
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = uID;
tp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
if(!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL,NULL))
{
return FALSE;
}

// 关闭访问令牌句柄
::CloseHandle(hToken);
return TRUE;
}
return FALSE;
}


二、枚举系统进程,枚举进程的思路是 先获得进程快照, 然后Process32First, 然后Process32Next

]  BOOL EnumProcess()

{

HANDLE hSnapshot = NULL; //快照句柄
//注意快照hSnapshot 赋值
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, 0 );//创建快照
if (hSnapshot == INVALID_HANDLE_VALUE)
{
return FALSE;
}

//枚举进程
PROCESSENTRY32  procEntry32;
procEntry32.dwSize = sizeof(PROCESSENTRY32);

if (!Process32First(hSnapshot,  &procEntry32))
{
CloseHandle(hSnapshot);
return FALSE;
}

do

{

/*********在这里加入你的操作,比如把进程的名称,PID, ParentID,都能从procEntry32获取******/

/******* 进程的路径获取请参照下面的函数

******CString GetProcPath(DWORD dwProcID); //根据进程ID获取进程的路径

************************************************************************/

} while (Process32Next( hSnapshot, &procEntry32));

CloseHandle(hSnapshot); //记得关掉handle

}


三、获取进程的绝对路径

]CString GetProcPath(DWORD dwProcID)
{
//OpenProcess,根据ID打开进程ID

HANDLE hProc = OpenProcess(  PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,dwProcID );

if (hProc == NULL)
{
return _T("");
}
HMODULE hMod;
DWORD cbNeeded;
CString sPath;
TCHAR lPath[MAX_PATH] = _T("");
// 获取进程模块
if( EnumProcessModules(hProc, &hMod, sizeof( hMod ), &cbNeeded ) )
{
//获得可执行文件路径
GetModuleFileNameExW( hProc, hMod, sPath.GetBuffer( MAX_PATH ), MAX_PATH );
sPath.ReleaseBuffer();
int n=sPath.Find(_T("://")); //类似kmp匹配
sPath=sPath.Mid(n-1); //从比如说C://开始取路径
GetLongPathName(sPath,lPath,255); //转换为long的形式
}
CloseHandle( hProc );

return sPath;

}


四、枚举进程所有模块, 其实跟上面的获取进程绝对路径一样,用到都是EnumProcessModules,不过上面的hMod 是一个变量,下面的是一个HMODULE hMod[1024];

]void CProcDlg::GetDllInfo(DWORD dwProcID)
{

//OpenProcess,根据ID打开进程ID

HANDLE hProc = OpenProcess(  PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,dwProcID );

if (hProc == NULL)
{
return -1;
}
HMODULE hMod[1024];
DWORD cbNeeded;
TCHAR szModName[MAX_PATH];
TCHAR lPath[MAX_PATH] = _T("");
// 获取进程模块
if( EnumProcessModules(hProc, hMod, sizeof(hMod ), &cbNeeded ) )
{
//获得模块路径
for (int i = 0; i <= cbNeeded/sizeof(HMODULE); ++i )
{

if ( GetModuleFileNameExW( hProc, hMod[i], szModName,sizeof(szModName)))
{
CString ModName, FTime;
CFileStatus status;
ModName = szModName;
//特殊处理
if (ModName.Find(_T("//??//")) != -1)
{
ModName.Replace(_T("//??//"),_T(""));
}
if (ModName.Find(_T("//SystemRoot")) != -1)
{
ModName.Replace(_T("//SystemRoot"),_T("C://WINDOWS"));
}

m_procModuelListCtrl.InsertItem(i,ModName); //0.模块路径
CFileVersion fileVer; //这个获得模块的相应信息类将在下面提到。
fileVer.Open(ModName);
CString str = fileVer.GetFileDescription();
m_procModuelListCtrl.SetItemText(i, 1, str);  //1.文件描述
str = fileVer.GetCompanyName();
m_procModuelListCtrl.SetItemText(i, 2, str); //2. 公司名称
str = fileVer.GetProductVersion();
m_procModuelListCtrl.SetItemText(i, 3, str);//3.产品版本
fileVer.Close();
CFile::GetStatus(ModName,status);
FTime = status.m_mtime.Format("%m/%d/%y");
m_procModuelListCtrl.SetItemText(i, 4, FTime);
m_procModuelListCtrl.SetItemData(i,i); //准备排序

}
}
CloseHandle( hProc );
//更新listCtrl内容
m_procModuelListCtrl.SetRedraw(TRUE);
m_procModuelListCtrl.Invalidate();
m_procModuelListCtrl.UpdateWindow();
int iCnt = m_procModuelListCtrl.GetItemCount();
return iCnt - 1;

}

else
{
CloseHandle( hProc );
return -1;
}

}


有关模块的信息思路是这样的, 先GetFileVersionSize 在GetFileVersionInfo, 然后调用VerQueryValue

有关详细的操作请参照这里: http://blog.csdn.net/ACE1985/archive/2010/07/14/5732024.aspx

下载地址:http://download.csdn.net/source/3156627

有这几个函数写一个进程管理器就差不多了, 例外关于进程的监控,不如进程的开启和关闭,我的思路是这样的:问题已经解决了,谢谢大家,我最后还是用定时器做的,列表中枚举的进程ID先用vector 来保存下来,每次枚举进程的时候先查看进程的ID是否在这个vector 里面,如果不存在的话插入到进程列表里面,这样就能监控进程的开启;枚举完后检查vector 里面的进程的状态是否关闭了,如果关闭的话就从列表控件里面删除相应的Item, vector里面也移除,这样的话就能监控进程的关闭了。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: