进程遍历前先获取进程快照
代码例子如下:具体API使用查csdn
//创建进程快照(获取系统正在运行的进程信息,线程信息等)
//第二个参数一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取当前进程快照时可以设为0
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("创建进程快照失败"));
return;
}
PROCESSENTRY32 sProSnap;
sProSnap.dwSize = sizeof(sProSnap);
//从进程快照中获取第一个进程信息
BOOL bRet = Process32First(hProcessSnap, &sProSnap);
if (bRet)
{
do
{
CString csFmt;
csFmt.Format(_T("ID:%d parent ID:%d path:%s"),
sProSnap.th32ProcessID,
sProSnap.th32ParentProcessID,
sProSnap.szExeFile);
OutputDebugString(csFmt);
bRet = Process32Next(hProcessSnap, &sProSnap);
} while (bRet);
}
线程和模块遍历和进程遍历类似
线程遍历
CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);//创建线程快照
Thread32First(hSnapshot, &ppe);//获取第一个线程
Thread32Next(hSnapshot, &ppe);//获取下一个线程
模块遍历
CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0);//创建模块快照
Module32First(hSnapshot, &ppe);//获取第一个模块
Module32Next(hSnapshot, &ppe);//获取下一个模块
窗口遍历
HWND hWnd = ::GetDesktopWindow();//获取桌面窗口句柄,因为桌面是最后一个窗口
HWND hNext = ::GetWindow(hWnd, GW_CHILD);//获取桌面上一个窗口句柄
do
{
TCHAR szBuff[MAXBYTE] = { 0 };
::GetWindowText(hNext, szBuff, MAXBYTE);
DWORD dwProcId = 0;
DWORD dwThreadId = GetWindowThreadProcessId(hNext, &dwProcId);
CString csFmt;
csFmt.Format(_T("procid:%d name:%s"),
dwProcId,
szBuff);
OutputDebugString(csFmt);
hNext = ::GetNextWindow(hNext, GW_HWNDNEXT);
} while (hNext != NULL);
进程间读写和修改内存属性
int nAddr = GetDlgItemInt(EDT_ADDR);//从控件获取地址
//1. 查找窗口
HWND hWnd = ::FindWindow(NULL, _T("TestMemory"));
//2. 拿到进程id
DWORD dwProcessId;
::GetWindowThreadProcessId(hWnd, &dwProcessId);
//3. 打开进程
HANDLE hProcess = ::OpenProcess(
PROCESS_ALL_ACCESS,
TRUE,
dwProcessId);
//修改内存属性
DWORD dwOldProtect = 0;
BOOL bRet = VirtualProtectEx(
hProcess, //进程句柄
(LPVOID)nAddr, //修改内存属性的地址
1,//修改整个分页(修改是按分页单位修改的,写1个字节也会修改一个分页)
PAGE_EXECUTE_READWRITE,//修改为读写权限
&dwOldProtect);
if (!bRet)
{
AfxMessageBox(_T("修改失败!"));
}
//4. 写入数据
char chByte = 0xeb;
bRet = WriteProcessMemory(
hProcess, //进程句柄
(LPVOID)nAddr, //写入内存的地址
&chByte, //写入的数据
sizeof(chByte), //写入数据的大小
NULL);
if (!bRet)
{
AfxMessageBox(_T("写入失败!"));
}
//还原原来的内存属性
bRet = VirtualProtectEx(
hProcess, //进程句柄
(LPVOID)nAddr, //修改内存属性的地址
1,//修改整个分页
dwOldProtect,
&dwOldProtect);