Windows編程之進程篇

    Windows系統中,進程是一個很重要的部分,進程與進程內核對象對應,同時也擁有許多屬性,咱們必須一一地去熟悉他們,從而來感知系統。windows

  • 進程屬性                                                                                                                                                       進程屬性進程擁有許多屬性,此處講解關鍵屬性。 
    1. 進程對話;會話(session)是由進程和其餘的系統對象(好比窗口站、桌面和窗口)構成的,它們表明了一個用戶的工做站登陸會話。用戶登錄到windows系統以後,無論該用戶是本地登錄的,仍是遠程登錄,系統都會爲這個用戶分配一個新的會話ID(SID),也就是說會話與用戶的登陸是相關連的,沒有用戶登陸就不存在會話。      
    2. 進程名稱
    3. 進程命令行;CreateProcess()中最終以命令行爲具體啓動目標,命令行中非程序名內容做爲參數啓動命令行行傳遞給子進程
    4. 進程的環境變量;若是CreateProcess()中傳入NULL,子進程繼承父進程的環境字符串。其實,子進程之因此和父進環境字符串(公共)部分相同,是由於session ID相同而致使的,session ID相同,則環境變量會(公共)部分相同,由於進程是爲了內部的執行的線程提供一個空間和環境,而session則是爲內部全部的進程提供一個執行的空間和環境,因此具備相同session ID的進程具備相同的(公共)環境字符串。        
    5. 進程當前驅動器和目錄;同理,當傳入NULL時,子進程與父進程的目錄同樣。      
    6. 進程的STARTUPINFO中的hStdInput等句柄;此I/O句柄僅僅用於控制檯,指定到控制檯輸入輸出緩衝區句柄,子進程I/O重定向時科直接運用。PS:須要設置爲可繼承 
    7. 進程優先級;表示進程在系統中的優先級,可用於爭取執行時間
    8. 進程完整性;默認狀況下,系統會爲普通進程分配級別爲「中」的完整性級別。級別低的進程沒法訪問或修改級別高的進程的資源。進程完整性是訪問資源的第二道門檻。                             
  • 終止進程                                                                                                                                  
    1. 經過主線程入口的函數返回;只有經過入口的函數返回,C++對象資源才能被正確析構和釋放,以後C++運行庫纔會再調用ExitProcess()  
    2. 進程中一個線程調用ExitProcess();線程調用此函數時,不再會返回到當前函數調用,系統直接清理全部進程資源                                                                                
    3. 另外一個進程的線程調用TerminateProcess();任何線程均可以調用TerminateProcess()終止另外一個進程或本身的進程,同時TerminateProcess()是異步的,調用以後不能立刻終止進程  
      • ​​PS:進程在終止以後絕對不會泄露任何東西,同時進程終止運行時,內核對象的計數減一,狀態變爲已觸發狀態
  • 進程權限控制                                                                                                                           Windows中,進程權限控制主要靠3個部分。安全描述符、訪問控制列表(Access Control List ACL)和完整性級別;其中安全描述符(SID)由User產生的,這表面每個session ID都會對應一個獨一無二的SID,這意味着每一個進程由用戶(啓動者)賦予權限。當進程訪問資源時,系統會檢查ACL來覈對當前SID是否擁有權限訪問資源,若是經過檢查以後再進行完整性檢驗。查看進程的完整性級別和訪問目標的完整性級別,若是後者高於前者,則拒絕訪問,不然訪問成功。簡而言之,Windows經過SID來標識用戶賦予進程的權限,又經過完整性檢驗來進行第二道訪問檢查。
  • 枚舉進程以及進程模塊                                                                                                              
    //設置當前進程優先級爲Real-time
    	if (!SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS))
    		cout << "Failed to set priority of current process!" << endl;
    	DWORD parent_exp_PID = -1;
    	string parent_name = "";
    
    	HANDLE snap_handle = NULL;
    	snap_handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    	if (snap_handle == INVALID_HANDLE_VALUE)
    		cout << "Create process snapshot unsuccessfully!" << "\t Error Code: " << GetLastError() << endl;
    
    	PROCESSENTRY32 process_info = { 0 };
    	MODULEENTRY32 module_info = { 0 };
    	process_info.dwSize = sizeof(PROCESSENTRY32);
    	module_info.dwSize = sizeof(MODULEENTRY32);
    	cout << "Process Name" << "\t\t" << "Process ID" << "Parent PID" << endl;
    	if (Process32First(snap_handle, &process_info))
    	{
    		//經過進程快照句柄,遍歷枚舉進程
    		do
    		{
    			cout << process_info.szExeFile << "\t\t" << process_info.th32ProcessID << "\t" << process_info.th32ParentProcessID << endl;
    			//經過進程句柄,遍歷枚舉每一個進程有關的模塊
    			//當調用進程是一個32-bit程序,而快照進程是一個64-bit程序時候,CreateToolHelp32Snashot將會失敗,GetLastError獲得ERROR_PARTIAL_COPY (299)
    			HANDLE mod_snap_handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, process_info.th32ProcessID);
    			if (INVALID_HANDLE_VALUE==mod_snap_handle)
    			{
    				DWORD error_code = GetLastError();
    				continue;
    			}
    			if (Module32First(mod_snap_handle, &module_info))
    			{
    				do 
    				{
    					cout <<"\t"<< module_info.szModule << endl;
    				} while (Module32Next(mod_snap_handle,&module_info));
    			}
    			CloseHandle(mod_snap_handle);
    			if (0==strcmp(process_info.szExeFile,TEXT("explorer.exe")))
    				parent_exp_PID = process_info.th32ParentProcessID;
    			if (parent_exp_PID != -1 && process_info.th32ProcessID == parent_exp_PID)
    				parent_name = process_info.szExeFile;
    		} while (Process32Next(snap_handle, &process_info));
    		CloseHandle(snap_handle);
    	}
    	else
    		cout << "Failed to get process information in the beginning." << "\t Error Code: " << GetLastError() << endl;
    
    	cout << "Explorer's father process: " << parent_name << "\t" << "PID: " << parent_exp_PID << endl;

     

  • 進程I/O重定向                                                                                                                          
    string file_name = TEXT("Fucker.txt");
    	HANDLE output_file_handle=NULL, input_file_handle=NULL;
    	SECURITY_ATTRIBUTES handle_sec_attributes = { { 0 } };
    	handle_sec_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
    	handle_sec_attributes.bInheritHandle = TRUE;                  //指定這個輸出文件句柄是可繼承的
    	handle_sec_attributes.lpSecurityDescriptor = NULL;
    
    	output_file_handle = CreateFile(file_name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, &handle_sec_attributes, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
    	if (INVALID_HANDLE_VALUE == output_file_handle)
    	{
    		cout << "Failed to create file !" << endl;
    		return -1;
    	}
    
    	TCHAR exe_name[] = TEXT("4s.exe");
    	STARTUPINFO start_info = { 0 };
    	start_info.cb = sizeof(STARTUPINFO);
    	start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    	start_info.hStdOutput = output_file_handle;
    	start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
    	start_info.dwFlags = STARTF_USESTDHANDLES;
    	PROCESS_INFORMATION process_info = { 0 };
    	//isInheritable要設置成TRUE,這樣子進程才能繼承到I/O文件句柄,進而使用它們
    	if (!CreateProcess(exe_name, NULL, NULL, NULL, TRUE, REALTIME_PRIORITY_CLASS|CREATE_NEW_CONSOLE, NULL, NULL, &start_info, &process_info))
    		cout << "Failed to create process !" << endl;
    
    	CloseHandle(output_file_handle);
    	CloseHandle(process_info.hThread);
    	CloseHandle(process_info.hProcess);

    PS:若有不對,敬請指出,謝謝~安全

​​​​

相關文章
相關標籤/搜索