📄 lion-tutorial14.htm
字号:
<html>
<head>
<link rel="stylesheet" href="../../asm.css">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>
<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center">Tutorial 14: Process</p>
<hr size="1">
We will learn what a process is and how to create and terminate it.
<p>Download the example <a href="files/tut14.zip">here</a>.
<h3> Preliminary:</h3>
What is a process? I quote this definition from Win32 API reference:
<blockquote><i>"A process is an executing application that consists of a private
virtual address space, code, data, and other operating system resources, such
as files, pipes, and synchronization objects that are visible to the process."</i></blockquote>
As you can see from the definition above, a process "owns" several objects: the
address space, the executing module(s), and anything that the executing modules
create or open. At the minimum, a process must consist of an executing module,
a private address space and a thread. Every process must have at least one thread.
What's a thread? A thread is actually an execution queue. When Windows first creates
a process, it creates only one thread per process. This thread usually starts
execution from the first instruction in the module. If the process later needs
more threads, it can explicitly create them. <br>
When Windows receives a command to create a process, it creates the private memory
address space for the process and then it maps the executable file into the space.
After that it creates the primary thread for the process. <br>
Under Win32, you can also create processes from your own programs by calling CreateProcess
function. CreateProcess has the following syntax:
<p><b>CreateProcess proto lpApplicationName:DWORD,\</b> <br>
<b>
lpCommandLine:DWORD,\<br>
lpProcessAttributes:DWORD,\</b> <br>
<b>
lpThreadAttributes:DWORD,\</b> <br>
<b>
bInheritHandles:DWORD,\</b> <br>
<b>
dwCreationFlags:DWORD,\</b> <br>
<b>
lpEnvironment:DWORD,\</b> <br>
<b>
lpCurrentDirectory:DWORD,\</b> <br>
<b>
lpStartupInfo:DWORD,\</b> <br>
<b>
lpProcessInformation:DWORD</b>
<p>Don't be alarmed by the number of parameters. We can ignore most of them.
<p>lpApplicationName --> The name of the executable file with or without pathname
that you want to execute. If this parameter is null, you must provide the name
of the executable file in the lpCommandLine parameter. <br>
lpCommandLine --> The command line arguments to the program you
want to execute. Note that if the lpApplicationName is NULL, this parameter
must contain the name of the executable file too. Like this: "notepad.exe readme.txt"
<br>
lpProcessAttributes and lpthreadAttributes --> Specify the security attributes
for the process and the primary thread. If they're NULLs, the default security
attributes are used. <br>
bInheritHandles --> A flag that specify if you want the new process to inherit
all opened handles from your process. <br>
dwCreationFlags --> Several flags that determine the behavior of the process
you want to created, such as, do you want to process to be created but immediately
suspended so that you can examine or modify it before it runs? You can also
specify the priority class of the thread(s) in the new process. This priority
class is used to determine the scheduling priority of the threads within the
process. Normally we use NORMAL_PRIORITY_CLASS flag. <br>
lpEnvironment --> A pointer to the environment block that contains several environment
strings for the new process. If this parameter is NULL, the new process inherits
the environment block from the parent process. <br>
lpCurrentDirectory --> A pointer to the string that specifies the current drive
and directory for the child process. NULL if you want the child process
to inherit from the parent process. <br>
lpStartupInfo --> Points to a STARTUPINFO structure that specifies how the main
window for the new process should appear. The STARTUPINFO structure contains
many members that specifies the appearance of the main window of the child process.
If you don't want anything special, you can fill the STARTUPINFO structure with
the values from the parent process by calling GetStartupInfo function. <br>
lpProcessInformation --> Points to a PROCESS_INFORMATION structure that receives
identification information about the new process. The PROCESS_INFORMATION
structure has the following members:
<blockquote><b>PROCESS_INFORMATION STRUCT</b> <br>
<b> hProcess
HANDLE ?
; handle to the child process</b> <br>
<b> hThread
HANDLE ?
; handle to the primary thread of the child process</b> <br>
<b> dwProcessId DWORD ?
; ID of the child process</b> <br>
<b> dwThreadId DWORD ?
; ID of the primary thread of the child process</b> <br>
<b>PROCESS_INFORMATION ENDS</b></blockquote>
Process handle and process ID are two different things. A process ID is a unique
identifier for the process in the system. A process handle is a value returned
by Windows for use with other process-related API functions. A process handle
cannot be used to identify a process since it's not unique.
<p>After the CreateProcess call, a new process is created and the CreateProcess
call return immediately. You can check if the new process is still active by
calling GetExitCodeProcess function which has the following syntax:
<p><b>GetExitCodeProcess proto hProcess:DWORD, lpExitCode:DWORD</b>
<p>If this call is successful, lpExitCode contains the termination status of the
process in question. If the value in lpExitCode is equal to <b>STILL_ACTIVE</b>,
then that process is still running.
<p>You can forcibly terminate a process by calling TerminateProcess function.
It has the following syntax:
<p><b>TerminateProcess proto hProcess:DWORD, uExitCode:DWORD</b>
<p>You can specify the desired exit code for the process, any value you like.
TerminateProcess is not a clean way to terminate a process since any dll attached
to the process will not be notified that the process was terminated. <br>
<h3> Example:</h3>
The following example will create a new process when the user selects the "create
process" menu item. It will attempt to execute "msgbox.exe". If the user wants
to terminate the new process, he can select the "terminate process" menu item.
The program will check first if the new process is already destroyed, if it is
not, the program will call TerminateProcess function to destroy the new
process.
<p><b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> <br>
<b>WinMain proto :DWORD,:DWORD,:DWORD,:DWORD</b> <br>
<b>include \masm32\include\windows.inc</b> <br>
<b>include \masm32\include\user32.inc</b> <br>
<b>include \masm32\include\kernel32.inc</b> <br>
<b>includelib \masm32\lib\user32.lib</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b>
<p><b>.const</b> <br>
<b>IDM_CREATE_PROCESS equ 1</b> <br>
<b>IDM_TERMINATE equ 2</b> <br>
<b>IDM_EXIT equ 3</b>
<p><b>.data</b> <br>
<b>ClassName db "Win32ASMProcessClass",0</b> <br>
<b>AppName db "Win32 ASM Process Example",0</b> <br>
<b>MenuName db "FirstMenu",0</b> <br>
<b>processInfo PROCESS_INFORMATION <></b> <br>
<b>programname db "msgbox.exe",0</b>
<p><b>.data?</b> <br>
<b>hInstance HINSTANCE ?</b> <br>
<b>CommandLine LPSTR ?</b> <br>
<b>hMenu HANDLE ?</b> <br>
<b>ExitCode DWORD ?
; contains the process exitcode status from GetExitCodeProcess call.</b>
<p><b>.code</b> <br>
<b>start:</b> <br>
<b> invoke GetModuleHandle, NULL</b>
<br>
<b> mov hInstance,eax</b>
<br>
<b> invoke GetCommandLine</b> <br>
<b> mov CommandLine,eax</b> <br>
<b> invoke WinMain, hInstance,NULL,CommandLine,
SW_SHOWDEFAULT</b> <br>
<b> invoke ExitProcess,eax</b>
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b>
<br>
<b> LOCAL wc:WNDCLASSEX</b> <br>
<b> LOCAL msg:MSG</b> <br>
<b> LOCAL hwnd:HWND</b> <br>
<b> mov wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
<b> mov wc.style, CS_HREDRAW or CS_VREDRAW</b>
<br>
<b> mov wc.lpfnWndProc, OFFSET WndProc</b> <br>
<b> mov wc.cbClsExtra,NULL</b> <br>
<b> mov wc.cbWndExtra,NULL</b> <br>
<b> push hInst</b> <br>
<b> pop wc.hInstance</b> <br>
<b> mov wc.hbrBackground,COLOR_WINDOW+1</b> <br>
<b> mov wc.lpszMenuName,OFFSET MenuName</b> <br>
<b> mov wc.lpszClassName,OFFSET ClassName</b>
<br>
<b> invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
<b> mov wc.hIcon,eax</b> <br>
<b> mov wc.hIconSm,eax</b> <br>
<b> invoke LoadCursor,NULL,IDC_ARROW</b> <br>
<b> mov wc.hCursor,eax</b> <br>
<b> invoke RegisterClassEx, addr wc</b> <br>
<b> invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR
AppName,\</b> <br>
<b> WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\</b>
<br>
<b> CW_USEDEFAULT,300,200,NULL,NULL,\</b>
<br>
<b> hInst,NULL</b>
<br>
<b> mov hwnd,eax</b> <br>
<b> invoke ShowWindow, hwnd,SW_SHOWNORMAL</b> <br>
<b> invoke UpdateWindow, hwnd</b> <br>
<b> invoke GetMenu,hwnd</b> <br>
<b> mov hMenu,eax</b> <br>
<b> .WHILE TRUE</b> <br>
<b>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -