1 從組合語言到Windows核心程式設計筆記 1

2022-02-12 18:53:46 字數 4209 閱讀 5745

彙編部分

1、call

的本質相當於

push+jmp,ret

的本質相當於

pop+jmp。2、

windows中,不管哪種呼叫方式都是返回值放在

eax中,然後返回。外部從

eax中得到值。

3、ebp總是被我們用來儲存這個函式執行之前的

esp的值。

4、把區域性變數區域初始化成全0cccccccch,0cch

實際是int 3

指令的機器碼,這是乙個斷點中斷指令。

5、任何一段中間不加任何跳轉,連續的mov

和加減乘除指令一般都可以還原為乙個

c表示式。

如果有下面的**段,說明可能是含有陣列或結構體。

mov eax,《陣列下標

>

inul eax,eax,《結構大小

>

mov ecx, 《結構陣列開始的位址

>

mov eax, dword ptr [ecx + eax]

6、分析彙編指令時:

與堆疊操作相關的,call,ret

等相關指令,我們叫做函式呼叫

([函式

])指令

:f流程控制**,涉及判斷和跳轉指令:c

資料處理指令,其它一般為資料處理指令:d

。核心基礎

基本概念

首先需要安裝ddk (device driver kit)

,這裡我選擇

microsoft windows server 2003 sp1 ddk

。windows 驅動分成兩類,一類是不支援即插即用的

nt式驅動,一類是支援即插即用的

wdm((windows driver model))

驅動。nt

式驅動的安裝是基於服務的,可以通過修改登錄檔進行,也可以直接通過服務函式,如

createservice

進行安裝;但

wdm

式驅動不同,它安裝的時候需要通過編寫乙個

inf檔案進行控制。

driver.h標頭檔案中包含了開發

nt式驅動所需要的

ntddk.h,

此外還定義了幾個標誌來指明函式和變數分配在分頁記憶體還是非分頁記憶體中。

windows

驅動程式的入口函式是

driverentry

函式。有兩種編譯驅動的辦法,一種是用ddk

環境來編譯,需要在源**所在目錄下建立兩個檔案

makefile

和sources

,功能是引入

ddk的

bin目錄下 的

makefile.def

檔案,然後在開始選單中選擇

「windows xp checked build environment」

編譯環境,進入需要編譯的目錄,輸入

」build「

命令就可以;第二種編譯方式是使用

vc++

進行編譯。

[1]]

為了除錯方便,最好安裝乙個虛擬機器。[2]

windows的驅動模型概念,本來是就驅動程式的行為而言的。比如

wdm驅動,必須要滿足提供

n種被要求的特性(如電源管理、即插即用)才被稱為

wdm驅動。如果不提供這些功能,那麼統一稱為

nt式驅動。同樣的,

wdf驅動也有它的一系列規範。

wdf(windows driver foundation)驅動是可以呼叫傳統型驅動所呼叫的核心

api的,

wdf可以視為傳統型的公升級版。

[3]wdk = ddk (driver development kit) + hct kit (hardware compatibility test) + wdf (windows driver foundation) + dtm (driver test manager) + wdf driver verification tools + ifs kit (installable file systems kit) + free iso image download - visual studio 2005 out of the box integration[4]

基本語法[5]

字串在驅動開發中四處可見的是unicode

字串。因此可以說:

windows

的核心是使用

uincode

編碼的。

ansi_string

僅僅在某些碰到窄字元的場合使用。而且這種場合非常罕見。乙個定義如下:

typedef struct _unicode_string unicode_string, *punicode_string;

unicode_string並不保證

buffer

中的字串是以空結束的。因此,類似下面的做法都是錯誤的,可能會會導致核心崩潰:

unicode_string str;

…len = wcslen(str.buffer); // 試圖求長度。

dbgprint(「%ws」,str.buffer); // 試圖列印

str.buffer

。如果要用以上的方法,必須在編碼中保證buffer

始終是以空結束。但這又是乙個麻煩的問題。所以,使用微軟提供的

rtl系列函式來操作字串,才是正確的方法。

[6]記憶體與鍊錶

exallocatepoolwithtag

記憶體分配:

list_entry中的資料成員

flink

指向下乙個

list_entry

。整個鍊錶中的最後乙個list_entry

的flink

不是空。而是指向頭節點。得到

list_entry

之後,要用

containing_record

來得到鍊錶節點中的資料。

鎖一般不會定義成區域性變數。可以使用靜態變數、全域性變數,或者分配在堆中。

檔案操作

在核心中不能呼叫使用者層的win32 api

函式來操作檔案。在這裡必須改用一系列與之對應的核心函式。

void initializeobjectattributes(

out pobject_attributes initializedattributes,

in punicode_string objectname,

in ulong attributes,

in handle rootdirectory,

in psecurity_descriptor securitydescriptor);

windows核心中,無論是開啟檔案,還是登錄檔,裝置等,都會先呼叫初始化乙個

out pobject_attributes

。obj_kernel_handle表明開啟的檔案控制代碼乙個

「核心控制代碼

」。核心檔案控制代碼比應用層控制代碼使用更方便,可以不受執行緒和程序的限制。在任何執行緒中都可以讀寫。同時開啟核心檔案控制代碼不需要顧及當前程序是否有許可權訪問該檔案的問題(如果是有安全許可權限制的檔案系統)。

路徑並不是像應用層一樣直接寫「c:\\a.dat」

,而是寫成了

「\\??\\c:\\a.dat」

。這是因為

zwcreatefile

使用的是物件路徑。

「c:」

是乙個符號鏈結物件。符號鏈結物件一般都在

「\\??\\」

路徑下。

登錄檔[5]

應用程式設計中對應的子鍵 驅動程式設計中的路徑寫法

hkey_local_machine \registry\machine

hkey_users \registry\user

hkey_classes_root 沒有對應的路徑

hkey_current_user 沒有簡單的對應路徑,但是可以求得

zwopenkey

zwqueryvaluekey

zwsetvaluekey

時間void mygettickcount (pulong msec)

kesettimer

核心的**始終執行在某個「

中斷級」

上。dispatch > apc > passive

參考[1]

[2]

[3 [4]

[5]

windows驅動程式設計基礎教程

.doc

[6] windows ddk

3 從組合語言到Windows核心程式設計筆記 3

windows核心 一 sys放在 drivers 目錄下。執行在 r0層。在wdk 的相應環境中,進行相應 目錄,build.乙個核心程式被看作乙個pe 格式的dll 它是被 windows 整個核心呼叫的乙個 dll,一旦加裁,就成為核心的組成部分。所有的核心記憶體空間是共享的。核心程式崩潰,w...

2 從組合語言到Windows核心程式設計筆記 2

核心執行緒 在驅動中生成的執行緒一般是系統執行緒。系統執行緒所在的程序名為 system ntstatus pscreatesystemthread out phandle threadhandle,in ulong desiredaccess,in pobject attributes objec...

從機器語言到組合語言

機器語言是計算機唯一能接受和執行的語言。機器語言由二進位製碼組成,每一串二進位製碼叫做一條指令。一條指令規定了計算機執行的乙個動作。一台計算機所能懂得的指令的全體,叫做這個計算機的指令系統。不同型號的計算機的指令系統不同。指令通常由幾個位元組組成,第乙個位元組是操作碼,它規定了計算機要執行的基本操作...