获取系统中的进程列表(win 2 SDK)
获取系统中进程列表
在DOS操作系统下,一个程序可以读写系统中的所有内存,所以可以方便地修改任何地方的代码和数据
,不管这些代码和数据是不是自己所有的,另外,程序可以自由存取所有的寄存器,自由设置所有的中
断,所以程序可以通过设置单步中断或断点中断来跟踪代码的执行。这些功能可以
获取系统中进程列表
在DOS操作系统下,一个程序可以读写系统中的所有内存,所以可以方便地修改任何地方的代码和数据
,不管这些代码和数据是不是自己所有的,另外,程序可以自由存取所有的寄存器,自由设置所有的中
断,所以程序可以通过设置单步中断或断点中断来跟踪代码的执行。这些功能可以归结为对一个进程进
行调试。
在Windows操作系统中,不同进程之间的地址空间是隔离的,要用指令直接存取其他进程地址空间中的
代码和数据是不可能的,用户程序也没有权限去截获中断,甚至连在自己的代码段中写数据都是不合法
的,那么在Windows中还可以实现类似DOS中的调试功能吗?答案是肯定的,但必须通过专用的API
函数来完成。
要对进程进行某种操作,就必须首先知道该进程的进程句柄或者进程ID,否则一切无从谈起,对于程序
自己创建的子进程来说,CreateProcess函数返回了进程句柄和进程ID,但如果需要调试系统中已经
运行的进程,那就必须首先获取它们的句柄才行。
Win2中并没有直接获取其他进程句柄的函数,但如果知道进程ID,可以由此得到进程句柄,所以可以
首先通过某种途径获取进程ID。
1. 从窗口句柄获取进程句柄
获取进程ID的方法之一是使用GetWindowThreadProcessId函数,这个函数可以从一个窗口句柄获
得创建该窗口的进程的进程ID,而通过FindWindow函数得到窗口句柄是很简单的,所以
GetWindowThreadProcessId函数的用途相当广泛。该函数的用法是:
DWORD GetWindowThreadProcessId(
HWD hWnd, // handle to window
LPDWORD lpdwProcessId // process identifier
);
其中hWnd参数指定需要用来获取进程ID的窗口句柄,lpdwProcessId指向一个双字变量,函数在这
里返回创建窗口的进程ID,函数的返回值是目标进程中创建该窗口的线程的线程句柄(一个有用的副产
品!)。
得到了进程ID以后,就可以通过OpenProcess函数来获取该进程的句柄了:
HADLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance option
DWORD dwProcessId // process identifier
);
函数的参数定义如下:
● dwDesiredAccess——指定需要对该进程进行的操作,要对目标进程进行某种操作,必须指定操作
代码,但是在Windows T操作系统中,对其他进程操作需要有相应的权限,如需要结束目标进程就必
须有PROCESS_TERMIATE权限才行,当权限不够的时候,打开进程的操作就会失败。一般来说,
除了系统进程以外,可以对其他进程进行任何操作,操作码可以是以下取值的组合:
■ PROCESS_ALL_ACCESS——等于下面全部操作码的组合。
■ PROCESS_CREATE_THREAD——允许创建远程线程。
■ PROCESS_DUP_HADLE——允许进程句柄被复制。
■ PROCESS_QUERY_IFORMATIO——允许使用GetExitCodeProcess函数查询进程的退出
码或使用GetPriorityClass函数查询进程的优先级。
■ PROCESS_SET_IFORMATIO——允许使用SetPriorityClass函数设置进程的优先级。
■ PROCESS_TERMIATE——允许终止进程。
■ PROCESS_VM_OPERATIO—允许使用WriteProcessMemory函数或VirtualProtectEx函数
修改进程的地址空间。
■ PROCESS_VM_READ——允许对进程的地址空间进行读操作。
■ PROCESS_VM_WRITE——允许对进程的地址空间进行写操作。
● bInheritHandle——指明返回的进程句柄是否可以被当前进程的子进程继承,如果参数指定为
TRUE,则句柄可以被继承。
● dwProcessId——指定目标进程的进程ID。
如果函数执行成功,返回值是被打开的进程句柄。如果函数执行失败则返回ULL。一般打开失败的原因
是由权限不够引起的。当完成对目标进程的操作以后,必须使用CloseHandle将获得的句柄关闭。
2. 从快照函数获取进程句柄
使用GetWindowThreadProcessId获取进程ID的先决条件是进程必须创建了窗口,对于在后台运行
的没有窗口的进程该如何处理呢?这就要通过枚举系统中运行的进程来解决了,这个功能可以由
CreateToolhelp2Snapshot函数来实现。
通过CreateToolhelp2Snapshot函数可以获得一个进程的列表,可以从列表中得到进程的ID、进程
对应的可执行文件名和创建该进程的父进程ID等数据,这个函数支持Windows 9x系列和Windows
2000及以上的系统,不支持Windows T 4.0(幸好使用T 4.0的机会已经不多了)。
CreateToolhelp2Snapshot函数的名称比较奇怪,“Snapshot”是快照的意思,难道函数和拍快速
成像照片有某种联系吗?没有联系,“快照”只是函数执行方式的一种形像的比喻罢了。就像自然界中的
生命循环一样,系统中的进程也是生生不息的,随时都可能有进程被结束,也随时会有新的进程诞生。“
快照”保留了函数被调用时的进程列表,在以后读取“快照”数据的过程中如果有进程创建或结束,就不会
影响“快照”中的列表,就好比我们照了一张照片后走人,照片还是可以留下来慢慢地看。
下面的例子演示了这些函数的用法。
程序比较简单,就是获取系统中所有进程的列表,然后点击刷新按钮重新获取新的列表,点击终止,可以终止选中的进程。
新建一个VC6的Win2应用程序,代码如下:
//
#include <windows.h>
#include <tlhelp2.h>
#include resource.h
HWD hWinList = ULL;
char szTerminate[] = TEXT(无法结束指定进程);
void GetProcessList(HWD hWnd);
LRESULT CALLBACK DialogProc(HWD hWnd, UIT uMsg, WPARAM wParam, LPARAM lParam);
int WIAPI WinMain(I HISTACE hInstance, I HISTACE hPrevInstance, I LPSTR lpCmdLine, I int nShowCmd )
{
DialogBoxParam(hInstance, MAKEITRESOURCE(IDD_MAI), ULL, DialogProc, 0);
return 0;
}
void GetProcessList(HWD hWnd)
{
PROCESSETRY2 stProcess;
HADLE hSnapShot;
DWORD dwRtn;
BOOL b;
RtlZeroMemory(&stProcess, sizeof(stProcess));
SendMessage(hWinList, LB_RESETCOTET, 0, 0);
stProcess.dwSize = sizeof(stProcess);
hSnapShot = CreateToolhelp2Snapshot(TH2CS_SAPPROCESS, 0);
b = Process2First(hSnapShot, &stProcess);
while ( b )
{
dwRtn = SendMessage(hWinList, LB_ADDSTRIG, 0, (LPARAM)stProcess.szExeFile);
SendMessage(hWinList, LB_SETITEMDATA, dwRtn, );
b = Process2ext(hSnapShot, &stProcess);
}
CloseHandle(hSnapShot);
EnableWindow(GetDlgItem(hWnd, IDOK), FALSE);
}
LRESULT CALLBACK DialogProc(HWD hWnd, UIT uMsg, WPARAM wParam, LPARAM lParam)
{
int nItem = 0;
LRESULT lRes = 0;
HADLE hProcess = ULL;
switch ( uMsg )
{
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
case WM_IITDIALOG:
hWinList = GetDlgItem(hWnd, IDC_PROCESS);
GetProcessList(hWnd);
break;
case WM_COMMAD:
if ( LOWORD(wParam) == IDOK )
{
nItem = SendMessage(hWinList, LB_GETCURSEL, 0, 0);
lRes = SendMessage(hWinList, LB_GETITEMDATA, nItem, 0);
if ( ( hProcess = OpenProcess(PROCESS_TERMIATE, FALSE, lRes) ) )
{
TerminateProcess(hProcess, -1);
CloseHandle(hProcess);
Sleep(200);
GetProcessList(hWinList);
}
else
MessageBox(hWnd, szTerminate, ULL, MB_OK | MB_ICOERROR);
}
else if ( LOWORD(wParam) == IDC_REFRESH )
{
GetProcessList(hWnd);
}
else if ( LOWORD(wParam) == IDC_PROCESS )
{
if ( HIWORD(wParam) == LB_SELCHAGE )
{
EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
}
}
break;
default:
return FALSE;
}
return TRUE;
}
// resource.h
#define IDD_MAI 101
#define IDC_REFRESH 1000
#define IDC_PROCESS 1001
// ProcessList.rc
#include resource.h
#include afxres.h
//
// Dialog
//
IDD_MAI DIALOG DISCARDABLE 0, 0, 218, 145
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTIO | WS_SYSMEU
CAPTIO 进程列表
FOT 10, 宋体
BEGI
DEFPUSHBUTTO 终止(&T),IDOK,161,124,50,14
PUSHBUTTO 刷新(&R),IDC_REFRESH,97,124,50,14
LISTBOX IDC_PROCESS,7,7,204,110,LBS_SORT | LBS_OITEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
ED
需要注意的是,程序运行之后,上面的很多进程不能随便的结束的,如果你结束了一些关键的系统进程,可能会立马导致系统崩溃。我曾经就试过结束WILOGO.EXE这个进程,结果,系统立马重启了,还好没有什么东西需要保存,不然就惨了。
本文理论讲解部分来源于罗云彬2位汇编语言,源码也是由2位汇编程序改写而来。如果想知道更详细的内容或者是汇编版本,请看此书。
转载请注明出处:
author: cnhnyu
e-mail: cnhnyu<AT>gmail<DOT>com
qq: 9448026
在DOS操作系统下,一个程序可以读写系统中的所有内存,所以可以方便地修改任何地方的代码和数据
,不管这些代码和数据是不是自己所有的,另外,程序可以自由存取所有的寄存器,自由设置所有的中
断,所以程序可以通过设置单步中断或断点中断来跟踪代码的执行。这些功能可以归结为对一个进程进
行调试。
在Windows操作系统中,不同进程之间的地址空间是隔离的,要用指令直接存取其他进程地址空间中的
代码和数据是不可能的,用户程序也没有权限去截获中断,甚至连在自己的代码段中写数据都是不合法
的,那么在Windows中还可以实现类似DOS中的调试功能吗?答案是肯定的,但必须通过专用的API
函数来完成。
要对进程进行某种操作,就必须首先知道该进程的进程句柄或者进程ID,否则一切无从谈起,对于程序
自己创建的子进程来说,CreateProcess函数返回了进程句柄和进程ID,但如果需要调试系统中已经
运行的进程,那就必须首先获取它们的句柄才行。
Win2中并没有直接获取其他进程句柄的函数,但如果知道进程ID,可以由此得到进程句柄,所以可以
首先通过某种途径获取进程ID。
1. 从窗口句柄获取进程句柄
获取进程ID的方法之一是使用GetWindowThreadProcessId函数,这个函数可以从一个窗口句柄获
得创建该窗口的进程的进程ID,而通过FindWindow函数得到窗口句柄是很简单的,所以
GetWindowThreadProcessId函数的用途相当广泛。该函数的用法是:
DWORD GetWindowThreadProcessId(
HWD hWnd, // handle to window
LPDWORD lpdwProcessId // process identifier
);
其中hWnd参数指定需要用来获取进程ID的窗口句柄,lpdwProcessId指向一个双字变量,函数在这
里返回创建窗口的进程ID,函数的返回值是目标进程中创建该窗口的线程的线程句柄(一个有用的副产
品!)。
得到了进程ID以后,就可以通过OpenProcess函数来获取该进程的句柄了:
HADLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance option
DWORD dwProcessId // process identifier
);
函数的参数定义如下:
● dwDesiredAccess——指定需要对该进程进行的操作,要对目标进程进行某种操作,必须指定操作
代码,但是在Windows T操作系统中,对其他进程操作需要有相应的权限,如需要结束目标进程就必
须有PROCESS_TERMIATE权限才行,当权限不够的时候,打开进程的操作就会失败。一般来说,
除了系统进程以外,可以对其他进程进行任何操作,操作码可以是以下取值的组合:
■ PROCESS_ALL_ACCESS——等于下面全部操作码的组合。
■ PROCESS_CREATE_THREAD——允许创建远程线程。
■ PROCESS_DUP_HADLE——允许进程句柄被复制。
■ PROCESS_QUERY_IFORMATIO——允许使用GetExitCodeProcess函数查询进程的退出
码或使用GetPriorityClass函数查询进程的优先级。
■ PROCESS_SET_IFORMATIO——允许使用SetPriorityClass函数设置进程的优先级。
■ PROCESS_TERMIATE——允许终止进程。
■ PROCESS_VM_OPERATIO—允许使用WriteProcessMemory函数或VirtualProtectEx函数
修改进程的地址空间。
■ PROCESS_VM_READ——允许对进程的地址空间进行读操作。
■ PROCESS_VM_WRITE——允许对进程的地址空间进行写操作。
● bInheritHandle——指明返回的进程句柄是否可以被当前进程的子进程继承,如果参数指定为
TRUE,则句柄可以被继承。
● dwProcessId——指定目标进程的进程ID。
如果函数执行成功,返回值是被打开的进程句柄。如果函数执行失败则返回ULL。一般打开失败的原因
是由权限不够引起的。当完成对目标进程的操作以后,必须使用CloseHandle将获得的句柄关闭。
2. 从快照函数获取进程句柄
使用GetWindowThreadProcessId获取进程ID的先决条件是进程必须创建了窗口,对于在后台运行
的没有窗口的进程该如何处理呢?这就要通过枚举系统中运行的进程来解决了,这个功能可以由
CreateToolhelp2Snapshot函数来实现。
通过CreateToolhelp2Snapshot函数可以获得一个进程的列表,可以从列表中得到进程的ID、进程
对应的可执行文件名和创建该进程的父进程ID等数据,这个函数支持Windows 9x系列和Windows
2000及以上的系统,不支持Windows T 4.0(幸好使用T 4.0的机会已经不多了)。
CreateToolhelp2Snapshot函数的名称比较奇怪,“Snapshot”是快照的意思,难道函数和拍快速
成像照片有某种联系吗?没有联系,“快照”只是函数执行方式的一种形像的比喻罢了。就像自然界中的
生命循环一样,系统中的进程也是生生不息的,随时都可能有进程被结束,也随时会有新的进程诞生。“
快照”保留了函数被调用时的进程列表,在以后读取“快照”数据的过程中如果有进程创建或结束,就不会
影响“快照”中的列表,就好比我们照了一张照片后走人,照片还是可以留下来慢慢地看。
下面的例子演示了这些函数的用法。
程序比较简单,就是获取系统中所有进程的列表,然后点击刷新按钮重新获取新的列表,点击终止,可以终止选中的进程。
新建一个VC6的Win2应用程序,代码如下:
//
#include <windows.h>
#include <tlhelp2.h>
#include resource.h
HWD hWinList = ULL;
char szTerminate[] = TEXT(无法结束指定进程);
void GetProcessList(HWD hWnd);
LRESULT CALLBACK DialogProc(HWD hWnd, UIT uMsg, WPARAM wParam, LPARAM lParam);
int WIAPI WinMain(I HISTACE hInstance, I HISTACE hPrevInstance, I LPSTR lpCmdLine, I int nShowCmd )
{
DialogBoxParam(hInstance, MAKEITRESOURCE(IDD_MAI), ULL, DialogProc, 0);
return 0;
}
void GetProcessList(HWD hWnd)
{
PROCESSETRY2 stProcess;
HADLE hSnapShot;
DWORD dwRtn;
BOOL b;
RtlZeroMemory(&stProcess, sizeof(stProcess));
SendMessage(hWinList, LB_RESETCOTET, 0, 0);
stProcess.dwSize = sizeof(stProcess);
hSnapShot = CreateToolhelp2Snapshot(TH2CS_SAPPROCESS, 0);
b = Process2First(hSnapShot, &stProcess);
while ( b )
{
dwRtn = SendMessage(hWinList, LB_ADDSTRIG, 0, (LPARAM)stProcess.szExeFile);
SendMessage(hWinList, LB_SETITEMDATA, dwRtn, );
b = Process2ext(hSnapShot, &stProcess);
}
CloseHandle(hSnapShot);
EnableWindow(GetDlgItem(hWnd, IDOK), FALSE);
}
LRESULT CALLBACK DialogProc(HWD hWnd, UIT uMsg, WPARAM wParam, LPARAM lParam)
{
int nItem = 0;
LRESULT lRes = 0;
HADLE hProcess = ULL;
switch ( uMsg )
{
case WM_CLOSE:
EndDialog(hWnd, 0);
break;
case WM_IITDIALOG:
hWinList = GetDlgItem(hWnd, IDC_PROCESS);
GetProcessList(hWnd);
break;
case WM_COMMAD:
if ( LOWORD(wParam) == IDOK )
{
nItem = SendMessage(hWinList, LB_GETCURSEL, 0, 0);
lRes = SendMessage(hWinList, LB_GETITEMDATA, nItem, 0);
if ( ( hProcess = OpenProcess(PROCESS_TERMIATE, FALSE, lRes) ) )
{
TerminateProcess(hProcess, -1);
CloseHandle(hProcess);
Sleep(200);
GetProcessList(hWinList);
}
else
MessageBox(hWnd, szTerminate, ULL, MB_OK | MB_ICOERROR);
}
else if ( LOWORD(wParam) == IDC_REFRESH )
{
GetProcessList(hWnd);
}
else if ( LOWORD(wParam) == IDC_PROCESS )
{
if ( HIWORD(wParam) == LB_SELCHAGE )
{
EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
}
}
break;
default:
return FALSE;
}
return TRUE;
}
// resource.h
#define IDD_MAI 101
#define IDC_REFRESH 1000
#define IDC_PROCESS 1001
// ProcessList.rc
#include resource.h
#include afxres.h
//
// Dialog
//
IDD_MAI DIALOG DISCARDABLE 0, 0, 218, 145
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTIO | WS_SYSMEU
CAPTIO 进程列表
FOT 10, 宋体
BEGI
DEFPUSHBUTTO 终止(&T),IDOK,161,124,50,14
PUSHBUTTO 刷新(&R),IDC_REFRESH,97,124,50,14
LISTBOX IDC_PROCESS,7,7,204,110,LBS_SORT | LBS_OITEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
ED
需要注意的是,程序运行之后,上面的很多进程不能随便的结束的,如果你结束了一些关键的系统进程,可能会立马导致系统崩溃。我曾经就试过结束WILOGO.EXE这个进程,结果,系统立马重启了,还好没有什么东西需要保存,不然就惨了。
本文理论讲解部分来源于罗云彬2位汇编语言,源码也是由2位汇编程序改写而来。如果想知道更详细的内容或者是汇编版本,请看此书。
转载请注明出处:
author: cnhnyu
e-mail: cnhnyu<AT>gmail<DOT>com
qq: 9448026
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
上传时间: 2023-06-29 02:03:35
推荐阅读
留言与评论(共有 16 条评论) |
本站网友 短信联盟 | 9分钟前 发表 |
■ PROCESS_QUERY_IFORMATIO——允许使用GetExitCodeProcess函数查询进程的退出 码或使用GetPriorityClass函数查询进程的优先级 | |
本站网友 大连经济酒店 | 5分钟前 发表 |
I int nShowCmd ) { DialogBoxParam(hInstance | |
本站网友 会议纪录 | 27分钟前 发表 |
I LPSTR lpCmdLine | |
本站网友 车源 | 14分钟前 发表 |
FALSE | |
本站网友 流转 | 29分钟前 发表 |
如果函数执行成功,返回值是被打开的进程句柄 | |
本站网友 北方工业 | 23分钟前 发表 |
要对进程进行某种操作,就必须首先知道该进程的进程句柄或者进程ID,否则一切无从谈起,对于程序 自己创建的子进程来说,CreateProcess函数返回了进程句柄和进程ID,但如果需要调试系统中已经 运行的进程,那就必须首先获取它们的句柄才行 | |
本站网友 基本养老保险 | 29分钟前 发表 |
szTerminate | |
本站网友 当梦想照进现实 | 3分钟前 发表 |
124 | |
本站网友 比亚迪汽车销量 | 29分钟前 发表 |
新建一个VC6的Win2应用程序,代码如下: // #include <windows.h> #include <tlhelp2.h> #include resource.h HWD hWinList = ULL; char szTerminate[] = TEXT(无法结束指定进程); void GetProcessList(HWD hWnd); LRESULT CALLBACK DialogProc(HWD hWnd | |
本站网友 平型关路1222号 | 13分钟前 发表 |
LPARAM lParam) { int nItem = 0; LRESULT lRes = 0; HADLE hProcess = ULL; switch ( uMsg ) { case WM_CLOSE | |
本站网友 丰胸最快方法 | 21分钟前 发表 |
&stProcess); } CloseHandle(hSnapShot); EnableWindow(GetDlgItem(hWnd | |
本站网友 多窗口 | 16分钟前 发表 |
一般来说, 除了系统进程以外,可以对其他进程进行任何操作,操作码可以是以下取值的组合: ■ PROCESS_ALL_ACCESS——等于下面全部操作码的组合 | |
本站网友 武汉痘痘医院 | 12分钟前 发表 |
hWinList = GetDlgItem(hWnd | |
本站网友 零陵路 | 22分钟前 发表 |
FALSE); } LRESULT CALLBACK DialogProc(HWD hWnd | |
本站网友 什么人不能吃皮蛋 | 24分钟前 发表 |
97 |