使用Native API 建立程序

2021-09-24 18:52:55 字數 2459 閱讀 7657

使用 native api 建立程序

最近幾個星期一直在研究這個題目。因為關於方面的資料比較多(可以看下面的參考文章),所以開始時以為很快就結束了。誰知道真正動起手來才發現有很多要考慮的地方,不過還好今天終於成功了,還是很高興的。寫下來,做個小結吧。(紙上得來終覺淺 , 須知此事要躬行。)

我們一般是使用 createprocess 來建立程序的,而使用 native api 來建立程序其實說白了就是模擬 createprocess 的實現。一開始我以為 createprocess 就是呼叫 ntcreateprocess 的(畢竟和 createprocess 名稱一樣嘛),但是讀了許多文章後才知道ntcreateprocess 只是完成了 createprocess 一小部分工作。 createprocess 是由下面幾個步驟完成的:

1.       使用 zwopenfile 開啟檔案,建立對映 zwcreatesection.

本步驟開啟檔案,並建立乙個屬性為 sec_image 的 section 物件。

2.       呼叫 zwcreateprocess

本步驟主要是建立程序的 peb 、 eprocess 、 vad 等核心核心結構。

3.       建立堆疊、 context 、程序引數等,並建立主線程 zwcreatethread(suspend)

儘管 zwcreateprocess 建立了程序物件,但是並沒有同時建立乙個主線程。主線程需要呼叫函式 zwcreatethread 來建立,這個過程同時會建立堆疊、 context 、程序的引數等等。有點要注意的是:建立的程序 createsuspended 為 true ,於是執行緒建立後是不能立即執行的。

1)    堆疊的建立

一般情況我們都會從可執行檔案( pe )檔案頭中取出需要堆疊的大小,這個大小是在程式編譯的時候指定的。

我們將需要堆疊的結構放到乙個 initial_teb 結構中:

typedef struct _initial_tebinitial_teb, *pinitial_teb;

分配堆疊記憶體後,將位址填入上面的結構中,下面是堆疊的結構 :

2)    程序引數

我們使用 rtlcreateprocessparameters 來建立乙個資料結構:

ulong ntsysapi winapi rtlcreateprocessparameters(

out prtl_user_process_parameters *pprocessparameters,

in punicode_string imagepathname,

in punicode_string dllpath optional,

in punicode_string currentdirectory optional,

in punicode_string commandline optional,

in pvoid environment optional,

in punicode_string windowtitle optional,

in punicode_string desktopinfo optional,

in punicode_string shellinfo optional,

in punicode_string runtimedata optional

結構如下:

typedef struct _rtl_user_process_parameters rtl_user_process_parameters, *prtl_user_process_parameters;

呼叫這個函式後返回乙個當前程序(非新建的程序)的記憶體塊,該記憶體中除了上面的這個結構還包括該結構中指標成員所指向的內容。只有乙個成員除外: environment 。函式僅僅將引數拷貝進這個指標成員中,並沒有分配其他空間。所以你需要在新建程序中呼叫 zwallocatevirtualmemory 分配 environment 內容的記憶體空間,然後呼叫 zwwritevirtualmemory 寫進去,並將記憶體空間更新到 environment 成員。

由於函式返回的記憶體空間是在當前程序中,所以下面需要呼叫 zwallocatevirtualmemory 分配一塊記憶體空間,並呼叫 zwwritevirtualmemory 將函式的返回空間拷貝進去,最後還得呼叫 rtldestroyprocessparameters 來清除記憶體空間。

4.       通知 csrss.exe

每個新建立的程序都需要通知 csrss.exe 子系統。使用的引數結構如下:

5.       呼叫 zwresumethread 恢復執行緒的執行。

上面的一切都完成了,就可以呼叫 zwresumethread 恢復執行緒的執行了。

使用Native API 建立程序

使用 native api 建立程序 最近幾個星期一直在研究這個題目。因為關於方面的資料比較多 可以看下面的參考文章 所以開始時以為很快就結束了。誰知道真正動起手來才發現有很多要考慮的地方,不過還好今天終於成功了,還是很高興的。寫下來,做個小結吧。紙上得來終覺淺 須知此事要躬行。我們一般是使用 cr...

使用fork 函式建立程序

如果程式呼叫fork 成功,fork 函式會返回兩次的值,兩次的值都不相同,返回0是給子程序的,父程序返回非負整數。呼叫不成功返回 1 具體怎樣會呼叫不成功,我現在也不知道,以後學到了再來補充 include include include intmain else if repid 0 else ...

C 的程序建立和使用

最近在做乙個訊息中介軟體裡面涉及到多執行緒程式設計,由於跨平台的原因我採用了boost執行緒庫。在建立執行緒時遇到了幾種執行緒建立方式現總結如下 首先看看boost thread的建構函式吧,boost thread有兩個建構函式 1 thread 構造乙個表示當前執行執行緒的執行緒物件 2 exp...