自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

網(wǎng)絡(luò)安全編程:創(chuàng)建進(jìn)程

安全
當(dāng)運行一個程序的時候,操作系統(tǒng)就會將這個程序從磁盤文件裝入內(nèi)存,分配各種運行程序所需的資源,創(chuàng)建主線程等一系列的工作。進(jìn)程是運行當(dāng)中的程序,進(jìn)程是向操作系統(tǒng)申請資源的基本單位。運行一個記事本程序時,操作系統(tǒng)就會創(chuàng)建一個記事本的進(jìn)程。當(dāng)關(guān)閉記事本時,記事本進(jìn)程也隨即結(jié)束。

[[382723]]

微信公眾號:計算機(jī)與網(wǎng)絡(luò)安全

ID:Computer-network

當(dāng)運行一個程序的時候,操作系統(tǒng)就會將這個程序從磁盤文件裝入內(nèi)存,分配各種運行程序所需的資源,創(chuàng)建主線程等一系列的工作。進(jìn)程是運行當(dāng)中的程序,進(jìn)程是向操作系統(tǒng)申請資源的基本單位。運行一個記事本程序時,操作系統(tǒng)就會創(chuàng)建一個記事本的進(jìn)程。當(dāng)關(guān)閉記事本時,記事本進(jìn)程也隨即結(jié)束。對進(jìn)程感性上的認(rèn)識,這么多也就夠了。

如果要觀察系統(tǒng)中正在運行的進(jìn)程,那么同時按下鍵盤上的Ctrl+Shift+Esc組合鍵就可以打開“任務(wù)管理器”,也就看到了系統(tǒng)中正常的進(jìn)程列表,如圖1所示。對于任務(wù)管理器中的眾多列,主要關(guān)心的是“映像名稱”“PID”和“線程數(shù)”3項,這3項在編程中都會用到和涉及。

 

 

 

 

圖1 任務(wù)管理器

任何一個計算機(jī)文件都是一個二進(jìn)制文件。對于可執(zhí)行程序來說,它的二進(jìn)制數(shù)據(jù)是可以被CPU執(zhí)行的。程序是一個靜態(tài)的概念,本身只是存在于硬盤上的一個二進(jìn)制文件。當(dāng)用鼠標(biāo)雙擊某個可執(zhí)行程序以后,這個程序被加載入內(nèi)存,這時就產(chǎn)生了一個進(jìn)程。操作系統(tǒng)通過裝載器將程序裝入內(nèi)存時,會為其分配各種進(jìn)程所需的各種資源,并產(chǎn)生一個主線程,主線程會擁有CPU執(zhí)行時間,占用進(jìn)程申請的內(nèi)存……在編程的時候也經(jīng)常需要通過運行中的程序再去創(chuàng)建一個新的進(jìn)程,本文介紹常見的用于創(chuàng)建進(jìn)程的API函數(shù)。

1. 簡單下載者的演示

在Windows下創(chuàng)建進(jìn)程的方法有多種,這里通過一個例子先介紹最簡單的一種方法。該方法用到的API函數(shù)為WinExec(),其定義如下:

  1. UINT WinExec( 
  2.  LPCSTR lpCmdLine, // command line 
  3.  UINT uCmdShow // window style 
  4. ); 

參數(shù)說明如下。

lpCmdLine:指向一個要執(zhí)行的可執(zhí)行文件的字符串。

uCmdShow:程序運行后的窗口狀態(tài)。

第1個參數(shù)比較好理解,比如要執(zhí)行“記事本”程序,那么這個參數(shù)就可以是“C:\Windows\ System32\Notepad.exe”。第2個參數(shù)是指明程序運行后窗口的狀態(tài),常用的參數(shù)有兩個,一個是SW_SHOW,另一個是SW_HIDE。SW_SHOW表示程序運行后窗口狀態(tài)為顯示狀態(tài),SW_HIDE表示程序運行后窗口狀態(tài)為隱藏狀態(tài)??梢栽囍鴦?chuàng)建一個隱藏顯示狀態(tài)的“記事本”程序,方法如下:

  1. WinExec("c:\\windows\\system32\\notepad.exe", SW_HIDE); 

這樣創(chuàng)建的“記事本”進(jìn)程在“任務(wù)管理器”中可以看到“notepad.exe”這個進(jìn)程,但是無法看到其窗口界面。

WinExec()函數(shù)在很多“下載者”中使用,“下載者”的英文名字為“Downloader”,也就是下載器的意思。它是一種惡意程序,其功能較為單一(相對木馬、后門來說,功能單一)。下載者程序的功能是讓受害者計算機(jī)到黑客指定的URL地址去下載更多的病毒文件或木馬文件并運行。下載者的體積較小,容易傳播。當(dāng)下載者下載到病毒或木馬后,通常都會使用WinExec()來運行下載到本地的惡意程序,調(diào)用它的原因是只有兩個參數(shù)且參數(shù)非常簡單。

下面簡單來做一個下載者進(jìn)行演示,這僅僅只是一個演示。如果心懷歹意的話,不要企圖拿它來做任何壞事,因為演示代碼會很輕易地被殺毒軟件干掉。記住,目的是學(xué)習(xí)編程知識。

要完成一個模擬的下載者,就要讓程序可以從網(wǎng)絡(luò)上某個地址下載程序。文件下載的方式比較多,相對簡單而又比較常用的函數(shù)是URLDownloadToFile()。這個函數(shù)也是被下載者進(jìn)程使用的函數(shù),其定義如下:

  1. HRESULT URLDownloadToFile( 
  2.  LPUNKNOWN pCaller, 
  3.  LPCTSTR szURL, 
  4.  LPCTSTR szFileName, 
  5.  DWORD dwReserved, 
  6.  LPBINDSTATUSCALLBACK lpfnCB 
  7. ); 

在這個函數(shù)中,只會用到兩個參數(shù),分別是szURL和szFileName。這兩個參數(shù)的說明如下。

szURL:指向下載地址的 URL 的字符串。

szFileName:指向要保存到本地位置的字符串。

其余的參數(shù)賦值為0或NULL即可。

使用URLDownloadToFile()函數(shù),需要包含Urlmon.h頭文件和Urlmon.lib導(dǎo)入庫文件,否則在編譯和連接時會無法通過。

已經(jīng)了解了需要用到的API函數(shù),那么完成代碼也就非常簡單了。具體代碼不過幾行而已,具體如下:

  1. #include <windows.h> 
  2. #include <urlmon.h> 
  3. #pragma comment (lib, "urlmon"
  4. int main() 
  5.   char szUrl[MAX_PATH] = "c:\\windows\\system32\\notepad.exe"
  6.   char szVirus[MAX_PATH] = "d:\\virus.exe"
  7.   URLDownloadToFile(NULL, szUrl, szVirus, 0, NULL); 
  8.   // 為了模擬方便看到效果,這里使用參數(shù) SW_SHOW 
  9.   // 一般可以傳遞 SW_HIDE 參數(shù) 
  10.   WinExec(szVirus, SW_SHOW); 
  11.   return 0; 

這里的模擬是把C盤系統(tǒng)目錄下的記事本程序下載到D盤并保存成名為virus.exe,然后運行它。如果是從網(wǎng)絡(luò)上某個地址處進(jìn)行下載,那么只要修改szUrl變量保存的字符串即可。我們的代碼是一個簡單的模擬代碼,如果真正完成一個“下載者”的話,要比這個代碼復(fù)雜很多,如果要在源代碼上進(jìn)行“免殺”,那么要考慮到問題也會很多。我們還是以學(xué)習(xí)編程知識為目的,不要進(jìn)行破壞,否則隨時可能會被“查水表”。

2. CreateProcess()函數(shù)介紹與程序的啟動

通常情況下,創(chuàng)建一個進(jìn)程會選擇使用CreateProcess()函數(shù),該函數(shù)的參數(shù)非常多,功能強(qiáng)大,使用也更為靈活。對于WinExec()函數(shù)來說,其使用簡單,也只能完成簡單的進(jìn)程創(chuàng)建工作。如果要對被創(chuàng)建的進(jìn)程具有一定的控制能力,那么必須使用功能更為強(qiáng)大的CreateProcess()函數(shù)。

在介紹CreateProcess()函數(shù)之前,先來介紹一個內(nèi)容。通常,在編寫C語言的程序時,如果是控制臺下的程序,那么編寫程序的入口函數(shù)是main()函數(shù),也就是通常所說的主函數(shù)。如果編寫一個Windows下程序,那么入口函數(shù)是WinMain()。即使是使用MFC進(jìn)行開發(fā),其實也是有WinMain()函數(shù)的,只不過是被龐大的MFC框架封裝了。那么程序真的是從main()函數(shù)或者是WinMain()函數(shù)開始執(zhí)行的嗎?在寫控制臺程序時,如果需要給程序提供參數(shù),那么這個參數(shù)是從哪里來的,主函數(shù)為什么會有返回值,它會返回哪里去呢?

使用VC6來寫一個簡單的程序。通過調(diào)試這個簡單的程序,看看C語言程序是否真的由main()函數(shù)開始執(zhí)行。寫一個簡單的輸出“Hello World”的程序來進(jìn)行調(diào)試。程序代碼如下:

  1. #include <stdio.h> 
  2. int main() 
  3.   printf("Hello World!!! \r\n"); 
  4.   return 0; 

這是非常簡單的一個程序,按下F7鍵進(jìn)行編譯和連接,然后按下F10鍵開始進(jìn)行單步調(diào)試狀態(tài),打開VC6的CallStack窗口(調(diào)用棧窗口),觀察其內(nèi)容,如圖2所示。

 

 

 

 

圖2 CallStack窗口內(nèi)容

在調(diào)用棧中有3行記錄,雙擊第2行“mainCRT Startup() line 206 + 25 bytes”,查看代碼編輯窗口的內(nèi)容,此時的代碼為調(diào)用主函數(shù)main()的C運行時啟動函數(shù)(簡稱啟動函數(shù))。代碼編輯窗口內(nèi)容如圖3所示。

 

 

 

 

圖3 啟動函數(shù)

可以看到,在代碼編輯窗口的左側(cè)有一個綠色的三角,表示這行代碼調(diào)用了主函數(shù)main()。并且通過該行代碼可以發(fā)現(xiàn),main()函數(shù)的返回值賦值給了mainret變量。將代碼上移,找到定義mainret變量的代碼處。mainret的定義如下:

int mainret;

該變量的類型為int型。通常在定義main()函數(shù)時,main()函數(shù)的返回值是int型。從上面的調(diào)用過程可以看出,main()函數(shù)只是程序員編程時的入口函數(shù),程序的啟動并不是從main()函數(shù)開始。在執(zhí)行main()函數(shù)前,操作系統(tǒng)及C語言的啟動代碼已經(jīng)為程序做了很多工作。

上面的內(nèi)容只是一個簡單的小插曲?;貧w正題,開始介紹CreateProcess()函數(shù)的使用。CreateProcess()函數(shù)的定義如下:

  1. BOOL CreateProcess( 
  2.  LPCTSTR lpApplicationName, // name of executable module 
  3.  LPTSTR lpCommandLine, // command line string 
  4.  LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD 
  5.  LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD 
  6.  BOOL bInheritHandles, // handle inheritance option 
  7.  DWORD dwCreationFlags, // creation flags 
  8.  LPVOID lpEnvironment, // new environment block 
  9.  LPCTSTR lpCurrentDirectory, // current directory name 
  10.  LPSTARTUPINFO lpStartupInfo, // startup information 
  11.  LPPROCESS_INFORMATION lpProcessInformation // process information 
  12. ); 

參數(shù)說明如下。

lpApplicationName:指定可執(zhí)行文件的文件名。

lpCommandLine:指定欲傳給新進(jìn)程的命令行的參數(shù)。

lpProcessAttributes:進(jìn)程安全屬性,該值通常為 NULL,表示為默認(rèn)安全屬性。

lpThreadAttributes:線程安全屬性,該值通常為 NULL,表示為默認(rèn)安全屬性。

bInheritHandlers:指定當(dāng)前進(jìn)程中的可繼承句柄是否被新進(jìn)程繼承。

dwCreationFlags:指定新進(jìn)程的優(yōu)先級以及其他創(chuàng)建標(biāo)志。

該參數(shù)一般情況下可以為0。

如果要創(chuàng)建一個被調(diào)試進(jìn)程的話,需要把該參數(shù)設(shè)置為DEBUG_PROCESS。創(chuàng)建進(jìn)程的進(jìn)程稱為父進(jìn)程,被創(chuàng)建的進(jìn)程稱為子進(jìn)程。也就是說,父進(jìn)程要對子進(jìn)程進(jìn)行調(diào)試的話,需要在調(diào)用CreateProcess()函數(shù)時傳遞DEBUG_PROCESS參數(shù)。在傳遞DEBUG_PROCESS參數(shù)后,子進(jìn)程創(chuàng)建的“孫”進(jìn)程同樣也處在被調(diào)試狀態(tài)中。如果不希望子進(jìn)程創(chuàng)建的“孫”進(jìn)程也處在被調(diào)試狀態(tài),那么在父進(jìn)程創(chuàng)建子進(jìn)程時傳遞DEBUG_ONLY_THIS_PROCESS和DEBUG_PROCESS。

在有些情況下,希望被創(chuàng)建子進(jìn)程的主線程暫時不要運行,那么可以指定CREATE _SUSPENDED參數(shù)。事后希望該子進(jìn)程的主線程運行的話,可以使用ResumeThread()函數(shù)使子進(jìn)程的主線程恢復(fù)運行。

lpEnvironment:指定新進(jìn)程的環(huán)境變量,通常這里指定為 NULL 值。

lpCurrentDirectory:指定新進(jìn)程使用的當(dāng)前目錄。

lpStartupInfo:指向 STARTUPINFO 結(jié)構(gòu)體的指針,該結(jié)構(gòu)體指定新進(jìn)程的啟動信息。

該參數(shù)是一個結(jié)構(gòu)體,該結(jié)構(gòu)體決定進(jìn)程啟動的狀態(tài)。該結(jié)構(gòu)體的定義如下:

  1. typedef struct _STARTUPINFO { 
  2.  DWORD cb; 
  3.  LPTSTR lpReserved; 
  4.  LPTSTR lpDesktop; 
  5.  LPTSTR lpTitle; 
  6.  DWORD dwX; 
  7.  DWORD dwY; 
  8.  DWORD dwXSize; 
  9.  DWORD dwYSize; 
  10.  DWORD dwXCountChars; 
  11.  DWORD dwYCountChars; 
  12.  DWORD dwFillAttribute; 
  13.  DWORD dwFlags; 
  14.  WORD wShowWindow; 
  15.  WORD cbReserved2; 
  16.  LPBYTE lpReserved2; 
  17.  HANDLE hStdInput; 
  18.  HANDLE hStdOutput; 
  19.  HANDLE hStdError; 
  20. } STARTUPINFO, *LPSTARTUPINFO; 

該結(jié)構(gòu)體在使用前,需要對cb成員變量進(jìn)行賦值,該成員變量用于保存結(jié)構(gòu)體的大小。一般創(chuàng)建一個進(jìn)程,只需要初始化其中幾個參數(shù)即可,如果要對新進(jìn)程的輸入輸出重定向的話,會用到該結(jié)構(gòu)體的更多成員變量等。

lpProcessInformation:指向PROCESS_INFORMATION結(jié)構(gòu)體的指針,該結(jié)構(gòu)體用于返回新創(chuàng)建進(jìn)程和主線程的相關(guān)信息。該結(jié)構(gòu)體的定義如下:

  1. typedef struct _PROCESS_INFORMATION { 
  2.  HANDLE hProcess; 
  3.  HANDLE hThread; 
  4.  DWORD dwProcessId; 
  5.  DWORD dwThreadId; 
  6. } PROCESS_INFORMATION; 

該結(jié)構(gòu)體用于返回新創(chuàng)建進(jìn)程的句柄和進(jìn)程ID,進(jìn)程主線程的句柄和主線程ID。

下面通過一個實例來對CreateProcess()函數(shù)進(jìn)行演示。

  1. #include <windows.h> 
  2. #include <stdio.h> 
  3. #define EXEC_FILE "c:\\windows\\system32\\notepad.exe" 
  4. int main() 
  5.  PROCESS_INFORMATION pi = { 0 }; 
  6.  STARTUPINFO si = { 0 }; 
  7.  si.cb = sizeof(STARTUPINFO); 
  8.  BOOL bRet = CreateProcess(EXEC_FILE, 
  9.  NULLNULLNULLFALSE
  10.  NULLNULLNULL, &si, &pi); 
  11.  if ( bRet == FALSE ) 
  12.  { 
  13.  printf("CreateProcess Error ! \r\n"); 
  14.  return -1; 
  15.  } 
  16.  CloseHandle(pi.hThread); 
  17.  CloseHandle(pi.hProcess); 
  18.  return 0; 

進(jìn)程創(chuàng)建后,PROCESS_INFORMATION結(jié)構(gòu)體變量的兩個句柄需要使用CloseHandle()函數(shù)進(jìn)行關(guān)閉。

 

 

責(zé)任編輯:龐桂玉 來源: 計算機(jī)與網(wǎng)絡(luò)安全
相關(guān)推薦

2021-02-23 10:20:07

網(wǎng)絡(luò)安全進(jìn)程代碼

2021-06-24 08:37:34

網(wǎng)絡(luò)安全內(nèi)核代碼

2021-03-01 11:38:15

網(wǎng)絡(luò)安全進(jìn)程代碼

2021-03-03 12:20:42

網(wǎng)絡(luò)安全DLL編程

2021-03-05 13:46:56

網(wǎng)絡(luò)安全遠(yuǎn)程線程

2021-01-26 13:45:03

網(wǎng)絡(luò)安全Winsock編程

2021-01-22 10:58:16

網(wǎng)絡(luò)安全進(jìn)程間碼如

2016-10-10 00:18:27

2021-06-18 09:55:09

網(wǎng)絡(luò)安全目錄監(jiān)控

2011-03-17 13:32:45

2021-02-04 10:50:11

網(wǎng)絡(luò)安全非阻塞模Winsock編程

2021-05-12 14:57:13

網(wǎng)絡(luò)安全密碼代碼

2021-06-15 11:16:24

網(wǎng)絡(luò)安全U盤軟件

2021-04-19 10:26:41

網(wǎng)絡(luò)安全PE文件

2021-05-24 11:55:55

網(wǎng)絡(luò)安全Windows鉤子函數(shù)

2021-01-18 10:35:18

網(wǎng)絡(luò)安全Windows代碼

2021-03-01 11:20:13

網(wǎng)絡(luò)安全多線程代碼

2023-07-13 07:10:20

2021-12-28 00:11:40

網(wǎng)絡(luò)安全攻擊

2021-04-26 10:32:38

網(wǎng)絡(luò)安全PE編程工具
點贊
收藏

51CTO技術(shù)棧公眾號