37 Windows API 其它相關原理和注意點

2022-02-12 13:23:44 字數 3453 閱讀 2831

1、

64位作業系統與

32位作業系統最大的不同在於定址空間的大小,

32位作業系統使用

32位資料來表示記憶體位址,因此有

232 (4gb)

的可用空間,而

64位作業系統可以使用

16tb

的記憶體位址空間。在

64位作業系統下,指標和基本資料型別

(int)

所引用的空間是

64位的。

windows系統中包括的物件型別有很多種。核心物件、

gdi圖形物件、使用者物件等。核心物件是與作業系統對系統的管理相關的物件,比如檔案、程序、事件,網路通訊的

socket

等。而gdi

物件是指在圖形輸出的相關物件。

user

物件是指使用者控制項、選單、輸入裝置等。

程式進行相關的操作時,都以這些物件作為操作物件,通常以控制代碼作為引數。

在vs的

debug

版本中,很多情況下,通過跳轉表呼叫函式。呼叫函式時,會使用

call

指令呼叫乙個跳轉表中的位置,這個位置上通常是乙個

jmp強制跳轉指令,跳轉到真實的函式程式段處。在

release

版本中,不採用函式跳轉表,直接呼叫函式**所在的位址。

在函式呼叫過程中棧的結構所示:

函式每呼叫一次,ebp

變化一次。棧中依次儲存著引數、返回位址、呼叫者的

ebp、區域性變數等。

每一次函式呼叫都會產生乙個這樣的結構,隨著呼叫的深入在棧中依次增長,因此又稱為棧幀,每一幀對應著乙個函式呼叫。ebp

在棧幀中起著關鍵作用,引數的定址、區域性變數的定址和函式返回都依賴於

ebp。

呼叫方式影響函式呼叫時引數的傳遞方式和函式返回後棧的恢復方式。如果為「_cdecl

」和「_stdcall

」方式則引數均為從右往左入棧,而「

_fastcall

」使用ecx

和edx

暫存器傳遞,餘下部分的引數從右向左儲存在棧中。

在函式返回後,如果函式是「_cdecl

」呼叫方式,則是呼叫者將

esp和

ebp指令恢復到呼叫前的態;而如果是「

_stdcall

」方式,則由被呼叫函式將棧恢復到呼叫前,以便呼叫函式可以繼續執行。

使用memcpy

、strcpy

等函式將資料複製到緩衝區(從低記憶體位址到高記憶體位址)。

2、windows

系統的可執行程式結構稱作

pe, exe

檔案、dll

檔案、sys

檔案、ocx

檔案等都是

pe格式的檔案。

具體結構可以參見[1

,p565]

中介紹。

3、在進行呼叫函式時,需要知道函式的位址,呼叫指令

(call)

以函式位址或儲存函式位址的指標作為引數。

在同一模組中的函式,**的相對位置都是固定的,call

語句的引數在編譯時都已經計算好,並嵌入到指令中(稱作

靜態鏈結)

。但是位於不同模組的函式要相互呼叫時,被呼叫函式的位址並不確定。

系統使用動態鏈結機制來保證不同模組中函式的正確呼叫。匯入表和匯出表是兩個在動態鏈結中需要使用到的重要結構。

匯入表中儲存了乙個模組所需呼叫的外部模組的函式,包括函式所在的dll

函式名等。匯出表儲存了乙個模組可被其他模組呼叫的函式,包括函式名。

在程序建立、模組載入時,系統會從可執行檔案的匯入表中獲取資訊,知道需要載入哪些dll

,然後再載入這些需要呼叫的

dll,從載入的被呼叫

dll中根據函式名找到需要呼叫的函式位址,然後將匯入表指定的各函式的位址指標陣列的值全部賦值為真實的

dll匯入函式位址。

因此乙個模組的匯入表的位置是相對固定的,但是匯入表中的函式指標的值是在動態鏈結時賦值的。在完成動態連線後,程式就可以通過匯入表中的函式指標呼叫外部函式了。

4、ntdll

.dll所匯入的

api函式稱作本機

api (nativeapi)

。核心中處理系統呼叫的結構稱作ssdt

,ssdt

的全稱是

system service descriptor table

,也就是系統服務描述符表。

由ntdll.dll

匯出的函式介面就是

nativeapi

,由ntdll.dll

匯出的native api

的實質是一系列的

stub

函式,實現了從使用者態向核心態的跳轉,呼叫系統服務實現

api的最終功能。

當從native api

進入核心態以後,系統會根據服務號在

ssdt

中查詢對應的表項,尋找所呼叫系統服務函式的真正位址。之後,系統會根據這個位址呼叫相應的系統服務函式,並返回函式的執行結果。

5、hook

(掛勾)是一種比較高階的應用。

hook

技術是指修改

api的位址或修改

api中的**,使得程式在呼叫

api函式時,可以監視到呼叫,或者可以修改引數或返回值等。

通常有兩種方法可以實現api hook

,一是遍歷程序中各個模組的匯入表,如果匯入表中呼叫了所需

hook

的目標函式,則將跳轉位址修改到自定義的函式中;另一種是在目標函式的位址後,在函式的**處寫入跳轉指令,一旦

api被呼叫,則會跳轉到自定義的函式中。

因此進行api hook

,需要進行兩個步驟的工作:一是編寫用於

hook

的函式,使用這些函式去「替換」正常的

api函式,

hook

函式中,需要呼叫原

api函式;二是

hook

程式,使用系統原有

api的位址或**。

6、lib

檔案中包括鏈結時所需的資訊,指明了鏈結器應該如何處理這些外部函式等(通常是將函式呼叫加入匯入表中)。

如果為第三方應用程式提供程式設計介面,那麼就需要有lib

檔案,lib

檔案指明了在鏈按時,鏈結器如何處理這些外部變數、外部函式等。如果需要通過匯入表呼叫

dll中的函式,就需要在鏈結時將

lib檔案作為鏈結輸入。

為第三方開發人員提供標頭檔案,lib

檔案,dll

檔案等。

參考[1] 精通

windows api

函式、介面、程式設計例項

[2]

(37)除錯幫助

c 程式設計師有時會用到一種類似於標頭檔案保護的技術,以便有選擇地執行除錯 程式可以包含一些用於除錯的 但這些 只在開發程式時使用。當應用程式編寫完成準備發布時,要先遮蔽掉除錯 這種方法用到兩種預處理功能 assert和ndebug。assert是一種預處理巨集。所謂預處理巨集其實是乙個預處理變數,...

3 7學習筆記

debug模式 如何進入debug模式 執行主函式或者單元測試時,ctrl shift d,j 使用debug模式的目的 1.跟蹤程式是否走預期流程 2.檢視執行過程中某些變數值 debug常用快捷鍵 ctrl shift b 開啟 關閉斷點 ctrl alt b 開啟 跳過已存在的所有斷點 ctr...

37 儲存過程

學習目標 1 了解儲存過程的定義和使用 2 了解儲存過程的使用場景 3 能夠根據業務場景編寫儲存過程解決問題 學習過程 一 儲存過程 在大型資料庫系統中,儲存過程和觸發器具有很重要的作用。無論是儲存過程還是觸發器,都是sql 語句和流程控制語句的集合。就本質而言,觸發器也是一種儲存過程。儲存過程在運...