1. 程式人生 > >win32_4-程序建立&控制

win32_4-程序建立&控制

在這裡插入圖片描述 當系統啟動後,建立一個程序:Explorer.exe 也就是桌面程序. 當用戶雙擊某一個EXE時,Explorer 程序使用CreateProcess函式建立被雙擊的EXE,也就是說,我們在桌面上雙擊建立的程序都是Explorer程序的子程序.

BOOL CreateProcess(
	LPCTSTR lpApplicationName,                 // name of executable module								
	LPTSTR lpCommandLine,                      // command line string								
	LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD								
	LPSECURITY_ATTRIBUTES lpThreadAttributes,  // SD								
	BOOL bInheritHandles,                      // handle inheritance option								
	DWORD dwCreationFlags,                     // creation flags								
	LPVOID lpEnvironment,                      // new environment block								
	LPCTSTR lpCurrentDirectory,                // current directory name								
	LPSTARTUPINFO lpStartupInfo,               // startup information								
	LPPROCESS_INFORMATION lpProcessInformation // process information								
);

建立程序之核心控制代碼表 在這裡插入圖片描述

當程序的空間建立完畢,EXE與匯入表中的DLL都正確載入完畢後,會建立一個執行緒

當執行緒得到CPU的時候,程式就正開始指向了,EIP的初始值設定為:ImageBase + OEP

HANDLE CreateThread(
	PSECURITY_ATTRIBUTES psa,
	DWORD cbStack,
	PTHREAD_START_ROUTINE pfnStartAddr,
	PVOID pvParam,
	DWORD fdwCreate,
	PDWORD pdwThreadID);

當程序建立成功後,會將程序控制代碼、主執行緒控制代碼、程序ID以及主執行緒ID儲存在

typedef struct _PROCESS_INFORMATION
{
	HANDLE hProcess;				//程序控制代碼					
	HANDLE hThread;				//主執行緒控制代碼					
	DWORD dwProcessId;				//程序ID					
	DWORD dwThreadId;				//執行緒ID					
} PROCESS_INFORMATION;

也就是,CreateProcess的最後一個 OUT 引數 到此,整個程序建立結束

例項程式碼:

	STARTUPINFO si = { 0 };
	PROCESS_INFORMATION pi;

	si.cb = sizeof(si);

	TCHAR szCmdline[] = TEXT(" http://www.ifeng.com");

	BOOL res = CreateProcess(
		TEXT("c://program files//internet explorer//iexplore.exe"),
		szCmdline,
		NULL,
		NULL,
		FALSE,
		CREATE_NEW_CONSOLE,
		NULL,
		NULL, &si, &pi);

用來設定要建立的應用程式的屬性,比如可以指定新建立的控制檯程式的標題等待。

一般情況,只要為第一個成員賦值就可以了.

si.cb = sizeof(si);

關於控制代碼和ID

  1. 都是系統分配的一個編號,控制代碼是客戶程式使用 ID主要是系統排程時使用.

  2. 呼叫CloseHandle關閉程序或者執行緒控制代碼的時候,只是讓核心計數器減少一個,並不是終止程序或者執行緒.程序或執行緒將繼續執行,直到它自己終止執行。

  3. 程序ID與執行緒ID 是不可能相同。但不要通過程序或者執行緒的ID來操作程序或者執行緒,因為,這個編號是會重複使用的,也就是說,當你通過ID = 100這個編號去訪問一個程序的時候,它已經結束了,而且系統將這個編號賦給了另外一個程序或者執行緒.

終止程序的三種方式:

  1. VOID ExitProcess(UINT fuExitCode) //程序自己呼叫

  2. BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode); //終止其他程序

  3. ExitThread //終止程序中的所有執行緒,程序也會終止

獲取程序的退出碼:

BOOL GetExitCodeProcess(HANDLE hProcess, PDWORD pdwExitCode);

程序終止時相關操作:

  1. 程序中剩餘的所有執行緒全部終止執行

  2. 程序指定的所有使用者物件均被釋放,所有核心物件均被關閉

  3. 程序核心物件的狀態變成收到通知的狀態

  4. 程序核心物件的使用計數遞減1

在這裡插入圖片描述