Win32ASM-进程学习【1】
? 關(guān)于一些進(jìn)程的概念就不說了。。。
?
一創(chuàng)建進(jìn)程GreateProcess
(1).當(dāng)一個(gè)進(jìn)程被創(chuàng)建時(shí):
①.系統(tǒng)為進(jìn)程創(chuàng)建一個(gè)內(nèi)核對象,并將這個(gè)對象的計(jì)數(shù)設(shè)置為1,進(jìn)程對象只是一個(gè)比較小的數(shù)據(jù)結(jié)構(gòu),可以通過進(jìn)程句柄來引用
②.系統(tǒng)為進(jìn)程創(chuàng)建一個(gè)虛擬地址空間,并將可執(zhí)行文件裝載到這個(gè)地址空間中,系統(tǒng)同時(shí)處理可執(zhí)行文件的導(dǎo)入表,將導(dǎo)入表中所有dll文件裝入.
每個(gè)dll被裝入的時(shí)候,dll入口函數(shù)被執(zhí)行,如果入口函數(shù)返回初始化失敗信息的話 ,進(jìn)程的初始化失敗.
可執(zhí)行文件的每個(gè)dll都被看作單獨(dú)的模塊,都被分配了一個(gè)實(shí)例句柄(實(shí)例句柄在數(shù)值上等于模塊裝入到地址空間中的線性地址)
③.系統(tǒng)為進(jìn)程建立一個(gè)主線程,主線程將從可執(zhí)行文件的的入口地址開始執(zhí)行
④.對于進(jìn)程來說,每一個(gè)進(jìn)程對應(yīng)一個(gè)進(jìn)程句柄和一個(gè)進(jìn)程ID
?
(2).和創(chuàng)建進(jìn)程有關(guān)的一些結(jié)構(gòu)
①STARTUPINFO
typedef struct _STARTUPINFO {
? DWORD cb;????????????????????????????????????? ;結(jié)構(gòu)的長度
? LPTSTR lpReserved;?????????????????????????? ;保留字段
? LPTSTR lpDesktop;??????????????????????????? ;NT下使用,指定桌面名稱
? LPTSTR lpTitle;????????????????????????????????? ;控制臺使用指定控制臺窗口標(biāo)題
? DWORD dwX;?????????????????????????????????? ;當(dāng)新進(jìn)程使用CW_USEDEFAULT參數(shù)創(chuàng)建
? DWORD dwY;?????????????????????????????????? ;窗口的時(shí)候?qū)⑹褂眠@些位置和大小屬性
? WORD dwXSize;???????????????????????????????
? ORD dwYSize;
? DWORD dwXCountChars;?????????????????;控制臺程序使用,指定控制臺窗口行數(shù)
? DWORD dwYCountChars;?????????????????;
? DWORD dwFillAttribute;???????????????????;控制臺程序使用,指定控制臺窗口背景色
? DWORD dwFlags;?????????????????????????????;標(biāo)志
? WORD wShowWindow;????????????????????;窗口的顯示方式
? WORD cbReserved2;
? LPBYTE lpReserved2;
? HANDLE hStdInput;??????????????????????? ;控制臺程序使用:幾個(gè)標(biāo)準(zhǔn)句柄
? ANDLE hStdOutput;
? HANDLE hStdError;
} STARTUPINFO,
?*LPSTARTUPINFO;
在需要指定新進(jìn)程的窗口時(shí),才需要手動(dòng)填寫STARTUPINFO結(jié)構(gòu)(比如需要控制臺程序的輸入輸出重定位時(shí)候,可以改寫hStdInput和hStdOutput字段)
在大多數(shù)情況下,并不需要新進(jìn)程的窗口有什么特殊之處,這時(shí)只需要使用GetStartupInfo獲取當(dāng)前進(jìn)程的STARTUPINFO結(jié)構(gòu)并使用他就可以了
invoke GetStartupInfo,addr stStartupInfo
?
②.PROCESS_INFOMATION
typedef struct _PROCESS_INFORMATION
?{?
HANDLE hProcess;?
HANDLE hThread;?
DWORD dwProcessId;
DWORD dwThreadId;??? 主線程句柄
PROCESS_INFORMATION,?
*LPPROCESS_INFORMATION;
?
(3).CreateProcess
BOOL WINAPI CreateProcess(
? __in_opt??????? LPCTSTR? lpApplicationName,
? __inout_opt? LPTSTR? lpCommandLine,
? __in_opt??????? LPSECURITY_ATTRIBUTES lpProcessAttributes,
? __in_opt??????? LPSECURITY_ATTRIBUTES lpThreadAttributes,
? __in??????????????? BOOL bInheritHandles,
? __in??????????????? DWORD dwCreationFlags,
? __in_opt?????? LPVOID lpEnvironment,
? __in_opt??????? LPCTSTR lpCurrentDirectory,
? __in??????????????? LPSTARTUPINFO lpStartupInfo,
? __out???????????? LPPROCESS_INFORMATION lpProcessInformation
);
①lpApplicationName
指向一個(gè)以0結(jié)尾的字符串,指明可執(zhí)行文件名,如果這個(gè)參數(shù)為NULL,那么文件名可以在老婆CommandLine參數(shù)指定的命令行參數(shù)中包含
②lpCommandLine
用來指定命令行參數(shù),如果 lpApplicationName為NULL,那么命令行參數(shù)的第一個(gè)組成部分用來指定可執(zhí)行文件名;
如果2個(gè)參數(shù)都為空,那么lpApplicationName為文件名,lpCommandLine作為命令行參數(shù)
③lpProcessAtrributes
指向一個(gè)SECURITY_ATTRIBUTES結(jié)構(gòu),用來指定新進(jìn)程的安全屬性,如果進(jìn)程句柄不需要被其他子進(jìn)程繼承,可以在這里使用NULL
④lpThreadAtrributes
指向一個(gè)SECURITY_ATTRIBUTES結(jié)構(gòu),用來指定新進(jìn)程的安全屬性,如果進(jìn)程句柄不需要被其他線程繼承,可以在這里使用NULL
⑤bInheritHandles
指定當(dāng)前進(jìn)程句柄是否可以被新進(jìn)程繼承,如果指定為TRUE,那么可以繼承,一般在這里使用FALSE
⑥dwCreationFlags
創(chuàng)建標(biāo)志,指定新進(jìn)程的優(yōu)先級以及其他標(biāo)志,這個(gè)參數(shù)類似于CreateThread函數(shù)中的同名參數(shù)它可以是一些標(biāo)志的組合,下面列舉一些常用的標(biāo)志
CREATE_NEW_CONSOLE 如果新進(jìn)程是控制臺程序,那么為他新建一個(gè)控制臺窗口,而不是使用父進(jìn)程的窗口
CREATE_SUSPENED? 新建進(jìn)程的主線程一開始處于掛起狀態(tài)需要以后用ResumeThread函數(shù)來恢復(fù)它的執(zhí)行
DEBUG_PROCESS?????????????????????? ;調(diào)試有關(guān)
DEBUG_ONLY_THIS_PROCESS
HIGH_PRIORITY_CLASS?????????????? ;指定新進(jìn)程的優(yōu)先級
NORMAL_PRIORITY_CLASS
REALTIME_PRIORIY_CLASS
⑦lpEnvironment
指向新進(jìn)程的環(huán)境變量塊,如果這個(gè)參數(shù)指定為NULL,表示讓W(xué)indows拷貝當(dāng)前進(jìn)程的環(huán)境塊當(dāng)做子進(jìn)程的環(huán)境塊,如果程序需要將修改過的環(huán)境塊傳給子進(jìn)程,可以設(shè)置這個(gè)參數(shù)
⑧l(xiāng)pCurrentDirectory
指向一個(gè)字符路徑,用來指定子進(jìn)程的當(dāng)前驅(qū)動(dòng)器和當(dāng)前目錄,如果指定為NULL,子進(jìn)程將引用父進(jìn)程的當(dāng)前路徑
⑨后面2個(gè)參數(shù)分別指向前面介紹的2個(gè)結(jié)構(gòu)體
---------------------------------------------------------------------------------------------------------------------------------------------------
二.結(jié)束進(jìn)程
(1)ExitProcess? dwExitCode
ExitProcess只能用來結(jié)束當(dāng)前進(jìn)程,不能用來結(jié)束其他進(jìn)程,包括當(dāng)前進(jìn)程創(chuàng)建的子進(jìn)程
?
(2)TerminateProcess hProcess,dwExitCode
這個(gè)函數(shù)不推薦使用,一般僅在很極端的條件下使用,(如任務(wù)管理器用來結(jié)束響應(yīng)的進(jìn)程)
因?yàn)槟繕?biāo)進(jìn)程無條件結(jié)束,沒有機(jī)會(huì)進(jìn)行掃尾工作,同時(shí)目標(biāo)進(jìn)程使用的dll文件也不會(huì)收到結(jié)束通知,所以極有可能 造成數(shù)據(jù)丟失
?
當(dāng)前進(jìn)程被結(jié)束時(shí),系統(tǒng)將做如下工作
①進(jìn)程創(chuàng)建或打開的所有對象句柄被關(guān)閉
②進(jìn)程的所有線程被終止
③進(jìn)程和進(jìn)程中所有的線程狀態(tài)被改為置位狀態(tài),以便讓W(xué)aitForSingleObject函數(shù)正常的檢測
④進(jìn)程對象中的退出碼字段從STILL_ACTIVE被改為指定的退出碼
?
(3)要檢測一個(gè)進(jìn)程的退出碼可以使用
GetExitCodeProcess hProcess,lpExitCode
如果函數(shù)執(zhí)行成功返回退出碼到lpExitCode
如果失敗返回STILL_ACTIVE到lpExitCode
通過檢測一個(gè)子進(jìn)程的退出碼是否為STILL_ACTIVE,就可以得知子進(jìn)程是否已經(jīng)結(jié)束,但如果需要在父進(jìn)程中等待子進(jìn)程結(jié)束時(shí),就沒有必要不停的檢測退出碼
可以使用WaitForSingleObject hProcess,dwMilliseconds
dwMilliseconds指定為INFINITE就可以了,表示子進(jìn)程結(jié)束前函數(shù)不會(huì)返回
?
當(dāng)一個(gè)進(jìn)程被結(jié)束時(shí),并不影響它所創(chuàng)建的子進(jìn)程,進(jìn)程對象也不會(huì)馬上從內(nèi)存中刪除,因?yàn)榭赡芷渌M(jìn)程還需要通過進(jìn)程句柄檢測進(jìn)程狀態(tài),直到使用CloseHandle函數(shù)將進(jìn)程句柄關(guān)閉以后,
進(jìn)程對象才是真正的被刪除了,所以當(dāng)不在使用進(jìn)程句柄的時(shí)候,不要忘記關(guān)閉PROCESS_INFORMATION中的進(jìn)程句柄 和主線程句柄
?
?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的Win32ASM-进程学习【1】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 地下城与勇士游戏具有几大阵营?分别是什么
- 下一篇: Win32ASM-进程学习【2】