当前位置:中国易下载软件教材中心文章中心编程语言汇编语言 → 汇编语言教学(14)

汇编语言教学(14)

减小字体 增大字体 作者:佚名  来源:不详  发布时间:2007-8-21 1:04:03
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
喜欢这些内容嘛,请告诉你身边的朋友,易下载中心-QQ资源-itnetcn.com一起享受这份乐趣,本站内容来源互联网
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

第十四课 进程rU9海岸线网络安全资讯站
本课中我们将学习:什么是进程?如何产生和终止一个进程? rU9海岸线网络安全资讯站
初步知识rU9海岸线网络安全资讯站
进程是什么?下面是我从WIN32 API指南中节选的解释: rU9海岸线网络安全资讯站
“一个进程是一个正在执行的应用程序,它包含有:私有的虚拟地址空间、代码、数据和其它的操作系统资源,譬如进程可以存取的管道、文件和同步对象等等。”rU9海岸线网络安全资讯站
从上面的定义中您可以看到,一个进程拥有几个对象:地址空间、执行模块和其它该执行程序打开或创建的任何对象或资源。至少,一个进程必须包含可执行模块、私有的地址空间和一个以上的线程。什么是线程呢?一个线程实际上是一个执行单元。当WINDOWS产生一个进程时,它自动为该进程产生一个主线程。该线程通常从模块的第一条指令处开始执行。如果进程需要更多的线程,它可以随后显式地产生。rU9海岸线网络安全资讯站
当WINDWOS 接收到产生进程的消息时,它会为进程生成私有内存地址空间,接着把可执行文件映射到该空间。在WIN32下为进程产生了主进程后,您还可以调用函数CreateProcess来为您的进程产生更多的线程。rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
CreateProcess的原型如下:rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
CreateProcess proto lpApplicationName:DWORD,\ rU9海岸线网络安全资讯站
lpCommandLine:DWORD,\rU9海岸线网络安全资讯站
lpProcessAttributes:DWORD,\ rU9海岸线网络安全资讯站
lpThreadAttributes:DWORD,\ rU9海岸线网络安全资讯站
bInheritHandles:DWORD,\ rU9海岸线网络安全资讯站
dwCreationFlags:DWORD,\ rU9海岸线网络安全资讯站
lpEnvironment:DWORD,\ rU9海岸线网络安全资讯站
lpCurrentDirectory:DWORD,\ rU9海岸线网络安全资讯站
lpStartupInfo:DWORD,\ rU9海岸线网络安全资讯站
lpProcessInformation:DWORD rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
不要被这么多的参数吓倒,其实您可以忽略其中的大多数的参数(让它们有缺省值)。 rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
lpApplicationName --> 可执行文件的名称(含或不含路径)。如果该参数为NULL,那必须在参数lpCommandLine中传递文件名称。rU9海岸线网络安全资讯站
lpCommandLine --> 传递给欲执行的文件的命令行参数。如果lpApplicationName为NULL,那必须在该参数中指定,譬如:"notepad.exe readme.txt" 。rU9海岸线网络安全资讯站
lpProcessAttributes 和 lpthreadAttributes --> 指定进程和主线程的安全属性。您可以把它们都设成为NULL,这样就设置了缺省的安全属性。rU9海岸线网络安全资讯站
bInheritHandles --> 标志位。用来设置新进程是否继承创建进程所有的打开句柄。rU9海岸线网络安全资讯站
dwCreationFlags --> 有几个标志可以在此处设置以决定欲创建进程的行为,譬如:您可能想创建进程后并不想让它立刻运行,这样在它真正运行前可以作一些检查和修改工作。您还可以在此处设置新进程中的所有线程的优先级,通常我们把它设置为NORMAL_PRIORITY_CLASS。rU9海岸线网络安全资讯站
lpEnvironment --> 指向环境块的指针,一般地环境块包含几个环境字符串。如果该参数为NULL,那么新进程继承创建进程的环境块。rU9海岸线网络安全资讯站
lpCurrentDirectory --> 指向当前目录以及为子进程设置的“当前目录”的路径。如果为NULL, 则继承创建进程的“当前目录”路径。rU9海岸线网络安全资讯站
lpStartupInfo --> 指向新进程的启动结构体STARTUPINFO的指针。STARTUPINFO告诉WINDOWS如何显示新进程的外观。该参数有许多的成员变量,如果您不想新进程有什么的特别之处,可以调用GetStartupInfo函数来用创建进程的启动参数来填充STARTUPINFO结构体变量。rU9海岸线网络安全资讯站
lpProcessInformation --> 指向结构体PROCESS_INformATION的指针,该结构体变量包含了一些标识该进程唯一性的一些成员变量: rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
PROCESS_INformATION STRUCT rU9海岸线网络安全资讯站
hProcess HANDLE ? ; handle to the child process rU9海岸线网络安全资讯站
hThread HANDLE ? ; handle to the primary thread of the child process rU9海岸线网络安全资讯站
dwProcessId DWORD ? ; ID of the child process rU9海岸线网络安全资讯站
dwThreadId DWORD ? ; ID of the primary thread of the child process rU9海岸线网络安全资讯站
PROCESS_INformATION ENDSrU9海岸线网络安全资讯站
进程句柄和进程ID是两个不同的概念。进程ID好似一个唯一值,而进程句柄是调用相关的WINDOWS API 后得到的一个返回值。不能用进程句柄来标识一个进程的唯一性,因为这个值并不唯一。在调用CreateProcess产生新进程后,该进程就被创建,而且CerateProcess函数立即返回。您可以调用函数GetExitCodeProcess来检验进程是否结束。该函数的原型如下: rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
GetExitCodeProcess proto hProcess:DWORD, lpExitCode:DWORD rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
如果调用成功,lpExitCode中包含了所查询进程的状态码。如果等于STILL_ACTIVE就表明该进程依旧存在。 您可以调用函数TerminateProcess来强制终止一个进程。该函数的原型如下: rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
TerminateProcess proto hProcess:DWORD, uExitCode:DWORD rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
您可以指定任意一个退出值。用该函数结束一个进程并不好,因为该进程加载的动态连接库并不会得到进程正退出的消息。rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
例子:rU9海岸线网络安全资讯站
在下面的例子中,当用户选择菜单项“crate process”时我们创建一个新进程。它会去执行“"msgbox.exe”。如果用户想要终止新进程,可以选择菜单项“terminate process”。这时,应用程序检查欲终止的进程是否仍存在,若存在则调用TerminateProcess函数来终止它。 rU9海岸线网络安全资讯站
.386 rU9海岸线网络安全资讯站
.model flat,stdcall rU9海岸线网络安全资讯站
option casemap:none rU9海岸线网络安全资讯站
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD rU9海岸线网络安全资讯站
include \masm32\include\windows.inc rU9海岸线网络安全资讯站
include \masm32\include\user32.inc rU9海岸线网络安全资讯站
include \masm32\include\kernel32.inc rU9海岸线网络安全资讯站
includelib \masm32\lib\user32.lib rU9海岸线网络安全资讯站
includelib \masm32\lib\kernel32.lib rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
.const rU9海岸线网络安全资讯站
IDM_CREATE_PROCESS equ 1 rU9海岸线网络安全资讯站
IDM_TERMINATE equ 2 rU9海岸线网络安全资讯站
IDM_EXIT equ 3 rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
.data rU9海岸线网络安全资讯站
ClassName db "Win32ASMProcessClass",0 rU9海岸线网络安全资讯站
AppName db "Win32 ASM Process Example",0 rU9海岸线网络安全资讯站
MenuName db "FirstMenu",0 rU9海岸线网络安全资讯站
processInfo PROCESS_INformATION <> rU9海岸线网络安全资讯站
programname db "msgbox.exe",0 rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
.data? rU9海岸线网络安全资讯站
hInstance HINSTANCE ? rU9海岸线网络安全资讯站
CommandLine LPSTR ? rU9海岸线网络安全资讯站
hMenu HANDLE ? rU9海岸线网络安全资讯站
ExitCode DWORD ? ; contains the process exitcode status from GetExitCodeProcess call. rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
.code rU9海岸线网络安全资讯站
start: rU9海岸线网络安全资讯站
invoke GetModuleHandle, NULL rU9海岸线网络安全资讯站
mov hInstance,eax rU9海岸线网络安全资讯站
invoke GetCommandLine rU9海岸线网络安全资讯站
mov CommandLine,eax rU9海岸线网络安全资讯站
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT rU9海岸线网络安全资讯站
invoke ExitProcess,eax rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD rU9海岸线网络安全资讯站
LOCAL wc:WNDCLASSEX rU9海岸线网络安全资讯站
LOCAL msg:MSG rU9海岸线网络安全资讯站
LOCAL hwnd:HWND rU9海岸线网络安全资讯站
mov wc.cbSize,SIZEOF WNDCLASSEX rU9海岸线网络安全资讯站
mov wc.style, CS_HREDRAW or CS_VREDRAW rU9海岸线网络安全资讯站
mov wc.lpfnWndProc, OFFSET WndProc rU9海岸线网络安全资讯站
mov wc.cbClsExtra,NULL rU9海岸线网络安全资讯站
mov wc.cbWndExtra,NULL rU9海岸线网络安全资讯站
push hInst rU9海岸线网络安全资讯站
pop wc.hInstance rU9海岸线网络安全资讯站
mov wc.hbrBackground,COLOR_WINDOW+1 rU9海岸线网络安全资讯站
mov wc.lpszMenuName,OFFSET MenuName rU9海岸线网络安全资讯站
mov wc.lpszClassName,OFFSET ClassName rU9海岸线网络安全资讯站
invoke LoadIcon,NULL,IDI_APPLICATION rU9海岸线网络安全资讯站
mov wc.hIcon,eax rU9海岸线网络安全资讯站
mov wc.hIconSm,eax rU9海岸线网络安全资讯站
invoke LoadCursor,NULL,IDC_ARROW rU9海岸线网络安全资讯站
mov wc.hCursor,eax rU9海岸线网络安全资讯站
invoke RegisterClassEx, addr wc rU9海岸线网络安全资讯站
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\ rU9海岸线网络安全资讯站
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ rU9海岸线网络安全资讯站
CW_USEDEFAULT,300,200,NULL,NULL,\ rU9海岸线网络安全资讯站
hInst,NULL rU9海岸线网络安全资讯站
mov hwnd,eax rU9海岸线网络安全资讯站
invoke ShowWindow, hwnd,SW_SHOWNORMAL rU9海岸线网络安全资讯站
invoke UpdateWindow, hwnd rU9海岸线网络安全资讯站
invoke GetMenu,hwnd rU9海岸线网络安全资讯站
mov hMenu,eax rU9海岸线网络安全资讯站
.WHILE TRUE rU9海岸线网络安全资讯站
invoke GetMessage, ADDR msg,NULL,0,0 rU9海岸线网络安全资讯站
.BREAK .IF (!eax) rU9海岸线网络安全资讯站
invoke TranslateMessage, ADDR msg rU9海岸线网络安全资讯站
invoke DispatchMessage, ADDR msg rU9海岸线网络安全资讯站
.ENDW rU9海岸线网络安全资讯站
mov eax,msg.wParam rU9海岸线网络安全资讯站
ret rU9海岸线网络安全资讯站
WinMain endp rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM rU9海岸线网络安全资讯站
LOCAL startInfo:STARTUPINFO rU9海岸线网络安全资讯站
.IF uMsg==WM_DESTROY rU9海岸线网络安全资讯站
invoke PostQuitMessage,NULL rU9海岸线网络安全资讯站
.ELSEIF uMsg==WM_INITMENUPOPUP rU9海岸线网络安全资讯站
invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode rU9海岸线网络安全资讯站
.if eax==TRUE rU9海岸线网络安全资讯站
.if ExitCode==STILL_ACTIVE rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_GRAYED rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_ENABLED rU9海岸线网络安全资讯站
.else rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_GRAYED rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
.else rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_GRAYED rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
.ELSEIF uMsg==WM_COMMAND rU9海岸线网络安全资讯站
mov eax,wParam rU9海岸线网络安全资讯站
.if lParam==0 rU9海岸线网络安全资讯站
.if ax==IDM_CREATE_PROCESS rU9海岸线网络安全资讯站
.if processInfo.hProcess!=0 rU9海岸线网络安全资讯站
invoke CloseHandle,processInfo.hProcess rU9海岸线网络安全资讯站
mov processInfo.hProcess,0 rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
invoke GetStartupInfo,ADDR startInfo rU9海岸线网络安全资讯站
invoke CreateProcess,ADDR programname,NULL,NULL,NULL,FALSE,\ rU9海岸线网络安全资讯站
NORMAL_PRIORITY_CLASS,\ rU9海岸线网络安全资讯站
NULL,NULL,ADDR startInfo,ADDR processInfo rU9海岸线网络安全资讯站
invoke CloseHandle,processInfo.hThread rU9海岸线网络安全资讯站
.elseif ax==IDM_TERMINATE rU9海岸线网络安全资讯站
invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode rU9海岸线网络安全资讯站
.if ExitCode==STILL_ACTIVE rU9海岸线网络安全资讯站
invoke TerminateProcess,processInfo.hProcess,0 rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
invoke CloseHandle,processInfo.hProcess rU9海岸线网络安全资讯站
mov processInfo.hProcess,0 rU9海岸线网络安全资讯站
.else rU9海岸线网络安全资讯站
invoke DestroyWindow,hWnd rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
.ELSE rU9海岸线网络安全资讯站
invoke DefWindowProc,hWnd,uMsg,wParam,lParam rU9海岸线网络安全资讯站
ret rU9海岸线网络安全资讯站
.ENDIF rU9海岸线网络安全资讯站
xor eax,eax rU9海岸线网络安全资讯站
ret rU9海岸线网络安全资讯站
WndProc endp rU9海岸线网络安全资讯站
end start rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
分析:rU9海岸线网络安全资讯站
应用程序创建主窗口,保存菜单句柄以备后用。当用户在主菜单中选择了“Process”菜单项后,消息处理过程中接收到WM_INITMENUPOPUP消息,我们在此处修改弹出式菜单中的菜单项的“使能”和“非使能”,以便同一菜单有不同的显示。 rU9海岸线网络安全资讯站
.ELSEIF uMsg==WM_INITMENUPOPUP rU9海岸线网络安全资讯站
invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode rU9海岸线网络安全资讯站
.if eax==TRUE rU9海岸线网络安全资讯站
.if ExitCode==STILL_ACTIVE rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_GRAYED rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_ENABLED rU9海岸线网络安全资讯站
.else rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_GRAYED rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
.else rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_CREATE_PROCESS,MF_ENABLED rU9海岸线网络安全资讯站
invoke EnableMenuItem,hMenu,IDM_TERMINATE,MF_GRAYED rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
我们之所以处理该消息的目的就是让菜单显示时有不同的外观以方便用户的使用。譬如;新进程尚未运行时,我们就变亮(使能)“菜单项“start process”,而变灰(非使能)菜单项“terminate process”。当新进程运行起来后,菜单的外观就应该是相反的。rU9海岸线网络安全资讯站
首先我们调用GetExitCodeProcess函数,其中传入由CreateProcess返回的句柄。如果GetExitCodeProcess返回FALSE,则表示进程尚未运行,我们就让菜单项“terminate process”变灰;如果返回TRUE,表示新进程已经启动了,我们再检测是否正在运行,这通过比较ExitCode是否等于STILL_ACTIVE 来完成,如果相等,表示进程仍在运行,我们就让菜单项“start process”变灰,因为在我们的简单的应用程序中不提供同时运行多个进程的能力。 rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
.if ax==IDM_CREATE_PROCESS rU9海岸线网络安全资讯站
.if processInfo.hProcess!=0 rU9海岸线网络安全资讯站
invoke CloseHandle,processInfo.hProcess rU9海岸线网络安全资讯站
mov processInfo.hProcess,0 rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
invoke GetStartupInfo,ADDR startInfo rU9海岸线网络安全资讯站
invoke CreateProcess,ADDR programname,NULL,NULL,NULL,FALSE,\ rU9海岸线网络安全资讯站
NORMAL_PRIORITY_CLASS,\ rU9海岸线网络安全资讯站
NULL,NULL,ADDR startInfo,ADDR processInfo rU9海岸线网络安全资讯站
invoke CloseHandle,processInfo.hThread rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
当用户选择了菜单项“start process”时,我们先检测结构体PROCESS_INformATION中的成员变量hPRocess是否已经关闭。如果是第一次启动应用程序,那该变量为0,因为我们在.data分段定义结构体时已经初始化该值为0。如果该值不为0,则表明新进程已经结束,但是我们尚未关闭该进程的句柄(以减少该进程的引用记数),我们在此处完成该动作。rU9海岸线网络安全资讯站
我们调用GetStartupInfo函数来填充启动信息的结构体变量,而该变量将被传递到CreateProcess函数中去。调用CreateProcess生成新进程,我们不检查该函数的返回值为的是让问题简化一些,在实际应用中,必须做该项工作。在调用CreateProcess后,我们立即关闭在进程信息结构体参数中返回的主线程句柄,关闭线程句柄为的是减少该内核对象的引用记数,否则即使该线程退出后,其内核对象仍惨存在内核中得不到释放,这会引起资源泄露。进程其实也是一样,之所以我们不在该处关闭进程的句柄是因为稍后我们还要用该句柄去得到一些和进程相关的信息,至于线程,我们的应用程序不需要其相关信息。 rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
.elseif ax==IDM_TERMINATE rU9海岸线网络安全资讯站
invoke GetExitCodeProcess,processInfo.hProcess,ADDR ExitCode rU9海岸线网络安全资讯站
.if ExitCode==STILL_ACTIVE rU9海岸线网络安全资讯站
invoke TerminateProcess,processInfo.hProcess,0 rU9海岸线网络安全资讯站
.endif rU9海岸线网络安全资讯站
invoke CloseHandle,processInfo.hProcess rU9海岸线网络安全资讯站
mov processInfo.hProcess,0 rU9海岸线网络安全资讯站
rU9海岸线网络安全资讯站
当用户选择了菜单项“terminate process”后,我们调用函数GetExitCodeProcess来检查新进程是否还存在,如果还存在我们就调用函数TerminateProcess来结束它。另外我们把它的句柄关闭掉,因为我们再也不用它了。rU9海岸线网络安全资讯站