windows內核安全編程源碼
1. windows內核方面的書籍有哪些
Windows內核原理與實現(第一本用真實的源代碼剖析Windows操作系統核心原理的原創著作此外還有Inside Windows 2000;Microsoft Windows Internals。這兩本書分別是同一套Windows內核架構分析書籍的第三版和第四版,兩位作者在編寫本書的過程中被授權察看Windows的相關源碼,所以可以說這兩本書是Windows內核分析的第一手資料;
Programming the Microsoft Windows Driver Model,本書的第二本也已經出版。本書系統地介紹了Windows WDM驅動程序設計的相關理論和技術。本書的特點是論述詳盡,結構清晰,內容全面。閱讀本書可系統了解WDM相關技術;
Undocumented Windows NT,較早的一本介紹Windows內核程序設計技術的書籍。雖然早但是其中的絕大部分技術並沒有落伍。本書的特點是實驗內容豐富實用,尤其是內存管理和Hook技術的相關內容很有參考價值,此書在網上已有中文版流傳;
Undocumented Windows 2000 Secrets,本書最有價值的內容有四個部分,分別是Exploring Windows 2000 Memory,Monitoring Native API Calls,Calling Kernel API Functions from User-Mode和Windows 2000 Object Management,尤其是本書提出的通用的API Monitor技術可說是本書的原創,很有啟發意義。此書在網上也有中文版流傳;
Windows NT File System Internals。本書是目前唯一一本詳細介紹Windows下文件系統架構和實現技術的書籍,雖說主要是NT下的文件系統,但是其中的絕大部分內容對2000/XP/2003同樣適用;
The Windows 2000 Device Driver Book, A Guide for Programmers,第二版。本書也比較全面地介紹了WDM驅動程序的相關技術。如果仔細閱讀並消化了Programming the Microsoft Windows Driver Model的內容,本書就需要瀏覽一下就可以了。 中文書不多 大部分是英文的 還有畢竟windows不是開源的
2. windows系統的源代碼,為什麼沒人反編譯出來
Windows內核級別的文件(如ntoskrnl.exe、hal.dll、子系統等),即使編譯出來了正常人也看不懂,而且反編譯後源代碼會有所缺失,沒用
3. 寒江獨釣:Windows內核安全編程的圖書目錄
第1章 內核上機指導 1
Windows內核編程的動手有點麻煩,並不是僅僅安裝一個獨立的軟體(比如VC)之後就可以安然地開始編寫代碼,然後運行了。需要下載開發包、配置開發環境、准備調試工具,可能還需要一些小工具協同工作。這一步攔住了不少的初學者。本章以詳細圖文攻略,來引導讀者完成這一麻煩的步驟。
1.1 下載和使用WDK 2
1.1.1 下載安裝WDK 2
1.1.2 編寫第一個C文件 3
1.1.3 編譯一個工程 5
1.2 安裝與運行 6
1.2.1 下載一個安裝工具 6
1.2.2 運行與查看輸出信息 7
1.2.3 在虛擬機中運行 9
1.3 調試內核模塊 9
1.3.1 下載和安裝WinDbg 9
1.3.2 設置Windows XP調試執行 10
1.3.3 設置Vista調試執行 11
1.3.4 設置VMWare的管道虛擬串口 11
1.3.5 設置Windows內核符號表 13
1.3.6 實戰調試first 14
練習題 16
第2章 內核編程環境及其特殊性 17
編寫過驅動程序的讀者可能會很熟悉這一切,但是對只從事過應用程序的讀者而言,要理解內核編程環境的特殊性,就很需要一些功夫和悟性了。在應用程序中,多線程的情況已經帶來了一定理解的困難;而內核代碼呢?幾乎無時無刻不運行在多線程之下。它從哪裡開始?從哪裡結束?它在什麼進程內運行?這些問題一言難盡。
2.1 內核編程的環境 18
2.1.1 隔離的應用程序 18
2.1.2 共享的內核空間 19
2.1.3 無處不在的內核模塊 20
2.2 數據類型 21
2.2.1 基本數據類型 21
2.2.2 返回狀態 22
2.2.3 字元串 23
2.3 重要的數據結構 23
2.3.1 驅動對象 23
2.3.2 設備對象 25
2.3.3 請求 26
2.4 函數調用 28
2.4.1 查閱幫助 28
2.4.2 幫助中有的幾類函數 30
2.4.3 幫助中沒有的函數 32
2.5 Windows的驅動開發模型 32
2.6 WDK編程中的特殊點 33
2.6.1 內核編程的主要調用源 33
2.6.2 函數的多線程安全性 34
2.6.3 代碼的中斷級 36
2.6.4 WDK中出現的特殊代碼 37
練習題 38
第3章 串口的過濾 40
在安全軟體的開發中,串口驅動的應用並不常見。但是本書以串口驅動作為第一個介紹的實例。為何?僅僅是因為串口簡單。從簡單的例子入手,可以為讀者帶來稍許輕松的感受。
3.1 過濾的概念 41
3.1.1 設備綁定的內核API之一 41
3.1.2 設備綁定的內核API之二 43
3.1.3 生成過濾設備並綁定 43
3.1.4 從名字獲得設備對象 45
3.1.5 綁定所有串口 46
3.2 獲得實際數據 47
3.2.1 請求的區分 47
3.2.2 請求的結局 48
3.2.3 寫請求的數據 49
3.3 完整的代碼 50
3.3.1 完整的分發函數 50
3.3.2 如何動態卸載 52
3.3.3 完整的代碼 53
本章的示例代碼 53
練習題 54
第4章 鍵盤的過濾 56
鍵盤是很重要的輸入設備!這是因為我們用鍵盤錄入信息、用鍵盤輸入密碼,甚至用鍵盤編程,也用鍵盤著書立說。對於黑客來說,使用龐大的計算機資源去破解那些堅不可摧的加密演算法,哪如偷偷地記下用戶用鍵盤輸入的密鑰更加簡單呢?本章專注於鍵盤的保護。
4.1 技術原理 57
4.1.1 預備知識 57
4.1.2 Windows中從擊鍵到內核 58
4.1.3 鍵盤硬體原理 60
4.2 鍵盤過濾的框架 61
4.2.1 找到所有的鍵盤設備 61
4.2.2 應用設備擴展 64
4.2.3 鍵盤過濾模塊的DriverEntry 65
4.2.4 鍵盤過濾模塊的動態卸載 66
4.3 鍵盤過濾的請求處理 68
4.3.1 通常的處理 68
4.3.2 PNP的處理 69
4.3.3 讀的處理 70
4.3.4 讀完成的處理 71
4.4 從請求中列印出按鍵信息 72
4.4.1 從緩沖區中獲得KEYBOARD_INPUT_DATA 72
4.4.2 從KEYBOARD_INPUT_DATA中得到鍵 73
4.4.3 從MakeCode到實際字元 74
4.5 Hook分發函數 75
4.5.1 獲得類驅動對象 76
4.5.2 修改類驅動的分發函數指針 77
4.5.3 類驅動之下的埠驅動 78
4.5.4 埠驅動和類驅動之間的協作機制 79
4.5.5 找到關鍵的回調函數的條件 80
4.5.6 定義常數和數據結構 80
4.5.7 打開兩種鍵盤埠驅動尋找設備 81
4.5.8 搜索在KbdClass類驅動中的地址 83
4.6 Hook鍵盤中斷反過濾 86
4.6.1 中斷:IRQ和INT 86
4.6.2 如何修改IDT 87
4.6.3 替換IDT中的跳轉地址 88
4.6.4 QQ的PS/2反過濾措施 90
4.7 利用IOAPIC重定位中斷處理函數 90
4.7.1 什麼是IOAPIC 90
4.7.2 如何訪問IOAPIC 91
4.7.3 編程修改IOAPIC重定位表 92
4.7.4 插入新的中斷處理 93
4.7.5 驅動入口和卸載的實現 95
4.8 直接用埠操作鍵盤 96
4.8.1 讀取鍵盤數據和命令埠 96
4.8.2 p2cUserFilter的最終實現 97
本章的示例代碼 98
練習題 99
第5章 磁碟的虛擬 100
CPU是計算機的核心,但是它不保存信息。如果它被竊,我們可以簡單地購買一個新的。但是如果裝滿了機密信息的硬碟被竊了,那可就不是買一個新的就能彌補得了的。本章介紹硬碟內核魔術:虛擬硬碟。虛擬硬碟可以不被盜竊者利用嗎?良好的設計可以做到這一點。
5.1 虛擬的磁碟 101
5.2 一個具體的例子 101
5.3 入口函數 102
5.3.1 入口函數的定義 102
5.3.2 Ramdisk驅動的入口函數 103
5.4 EvtDriverDeviceAdd函數 104
5.4.1 EvtDriverDeviceAdd的定義 104
5.4.2 局部變數的聲明 105
5.4.3 磁碟設備的創建 105
5.4.4 如何處理發往設備的請求 107
5.4.5 用戶配置的初始化 108
5.4.6 鏈接給應用程序 110
5.4.7 小結 111
5.5 FAT12/16磁碟卷初始化 111
5.5.1 磁碟卷結構簡介 111
5.5.2 Ramdisk對磁碟的初始化 113
5.6 驅動中的請求處理 119
5.6.1 請求的處理 119
5.6.2 讀/寫請求 120
5.6.3 DeviceIoControl請求 122
5.7 Ramdisk的編譯和安裝 124
5.7.1 編譯 124
5.7.2 安裝 125
5.7.3 對安裝的深入探究 125
練習題 126
第6章 磁碟過濾 127
很多網吧的老闆、公司的IT管理部門以及讀者自己都很厭惡硬碟總是被病毒和木馬搞得一團糟。一些簡單的還原軟體可以搞定這個問題:重啟之後,對硬碟的修改都奇跡般地消失了。這是怎麼實現的呢?本章告訴您答案。
6.1 磁碟過濾驅動的概念 128
6.1.1 設備過濾和類過濾 128
6.1.2 磁碟設備和磁碟卷設備過濾驅動 128
6.1.3 注冊表和磁碟卷設備過濾驅動 129
6.2 具有還原功能的磁碟卷過濾驅動 129
6.2.1 簡介 129
6.2.2 基本思想 130
6.3 驅動分析 130
6.3.1 DriverEntry函數 130
6.3.2 AddDevice函數 132
6.3.3 PnP請求的處理 136
6.3.4 Power請求的處理 140
6.3.5 DeviceIoControl請求的處理 140
6.3.6 bitmap的作用和分析 144
6.3.7 boot驅動完成回調函數和稀疏文件 150
6.3.8 讀/寫請求的處理 152
6.3.9 示例代碼 160
6.3.10 練習題 161
第7章 文件系統的過濾與監控 162
硬碟是硬碟,而文件系統是文件系統,可是有的人總是把它們當做一回事。其實硬碟很簡單,硬碟就是一個很簡單的保存信息的盒子;而復雜的是文件系統,它很精妙地把簡單的數據組織成復雜的文件。作為信息安全的專家,我們當然不能讓文件系統脫離我們的控制之外。
7.1 文件系統的設備對象 163
7.1.1 控制設備與卷設備 163
7.1.2 生成自己的一個控制設備 165
7.2 文件系統的分發函數 166
7.2.1 普通的分發函數 166
7.2.2 文件過濾的快速IO分發函數 167
7.2.3 快速IO分發函數的一個實現 169
7.2.4 快速IO分發函數逐個簡介 170
7.3 設備的綁定前期工作 172
7.3.1 動態地選擇綁定函數 172
7.3.2 注冊文件系統變動回調 173
7.3.3 文件系統變動回調的一個實現 175
7.3.4 文件系統識別器 176
7.4 文件系統控制設備的綁定 177
7.4.1 生成文件系統控制設備的過濾設備 177
7.4.2 綁定文件系統控制設備 178
7.4.3 利用文件系統控制請求 180
7.5 文件系統卷設備的綁定 183
7.5.1 從IRP中獲得VPB指針 183
7.5.2 設置完成函數並等待IRP完成 184
7.5.3 卷掛載IRP完成後的工作 187
7.5.4 完成函數的相應實現 190
7.5.5 綁定卷的實現 191
7.6 讀/寫操作的過濾 193
7.6.1 設置一個讀處理函數 193
7.6.2 設備對象的區分處理 194
7.6.3 解析讀請求中的文件信息 195
7.6.4 讀請求的完成 198
7.7 其他操作的過濾 202
7.7.1 文件對象的生存周期 202
7.7.2 文件的打開與關閉 203
7.7.3 文件的刪除 205
7.8 路徑過濾的實現 206
7.8.1 取得文件路徑的3種情況 206
7.8.2 打開成功後獲取路徑 207
7.8.3 在其他時刻獲得文件路徑 209
7.8.4 在打開請求完成之前獲得路徑名 209
7.8.5 把短名轉換為長名 211
7.9 把sfilter編譯成靜態庫 212
7.9.1 如何方便地使用sfilter 212
7.9.2 初始化回調、卸載回調和綁定回調 213
7.9.3 綁定與回調 215
7.9.4 插入請求回調 216
7.9.5 如何利用sfilter.lib 218
本章的示例代碼 221
練習題 221
第8章 文件系統透明加密 223
如何阻止企業的機密文件被主動泄密,但是又不用關閉網路、禁止U盤等手段重重束縛大家?很多跡象表明,文件系統透明加密是最優的選擇。既然從前一章讀者已經學會了控制文件系統,那麼現在,該是我們摩拳擦掌,用它來保護我們的機密信息的時候了。
8.1 文件透明加密的應用 224
8.1.1 防止企業信息泄密 224
8.1.2 文件透明加密防止企業信息泄密 224
8.1.3 文件透明加密軟體的例子 225
8.2 區分進程 226
8.2.1 機密進程與普通進程 226
8.2.2 找到進程名字的位置 227
8.2.3 得到當前進程的名字 228
8.3 內存映射與文件緩沖 229
8.3.1 記事本的內存映射文件 229
8.3.2 Windows的文件緩沖 230
8.3.3 文件緩沖:明文還是密文的選擇 232
8.3.4 清除文件緩沖 233
8.4 加密標識 236
8.4.1 保存在文件外、文件頭還是文件尾 236
8.4.2 隱藏文件頭的大小 237
8.4.3 隱藏文件頭的設置偏移 239
8.4.4 隱藏文件頭的讀/寫偏移 240
8.5 文件加密表 241
8.5.1 何時進行加密操作 241
8.5.2 文件控制塊與文件對象 242
8.5.3 文件加密表的數據結構與初始化 243
8.5.4 文件加密表的操作:查詢 244
8.5.5 文件加密表的操作:添加 245
8.5.6 文件加密表的操作:刪除 246
8.6 文件打開處理 248
8.6.1 直接發送IRP進行查詢與設置操作 248
8.6.2 直接發送IRP進行讀/寫操作 250
8.6.3 文件的非重入打開 252
8.6.4 文件的打開預處理 255
8.7 讀寫加密/解密 260
8.7.1 在讀取時進行解密 260
8.7.2 分配與釋放MDL 261
8.7.3 寫請求加密 262
8.8 crypt_file的組裝 265
8.8.1 crypt_file的初始化 265
8.8.2 crypt_file的IRP預處理 266
8.8.3 crypt_file的IRP後處理 269
本章的示例代碼 272
練習題 272
第9章 文件系統微過濾驅動 273
從來都不原地踏步的微軟,早就准備好了下一代的文件系統過濾的框架、文檔、代碼例子。雖然本書的前兩章的範例在Windows 7上都還可以正常運行,但是如果不學習一下最新的介面,讀者一定會覺得不自在。但是讀者可以放心,在前面學習的基礎上,了解新的介面是易如反掌的。
9.1 文件系統微過濾驅動簡介 274
9.1.1 文件系統微過濾驅動的由來 274
9.1.2 Minifilter的優點與不足 275
9.2 Minifilter的編程框架 275
9.2.1 微文件系統過濾的注冊 276
9.2.2 微過濾器的數據結構 277
9.2.3 卸載回調函數 280
9.2.4 預操作回調函數 281
9.2.5 後操作回調函數 284
9.2.6 其他回調函數 285
9.3 Minifilter如何與應用程序通信 288
9.3.1 建立通信埠的方法 288
9.3.2 在用戶態通過DLL使用通信埠的範例 290
9.4 Minifilter的安裝與載入 292
9.4.1 安裝Minifilter的INF文件 293
9.4.2 啟動安裝完成的Minifilter 294
本章的示例代碼 295
練習題 295
第10章 網路傳輸層過濾 296
筆者常常使用防火牆,它們看上去真的很神奇。如果懷疑自己的機器上有見不得人的進程打開了網路埠盜走機密信息,防火牆將提醒您,雖然防火牆並不知道它是否是一個木馬。這是怎麼做到的?本章為您揭曉謎底。
10.1 TDI概要 297
10.1.1 為何選擇TDI 297
10.1.2 從socket到Windows內核 297
10.1.3 TDI過濾的代碼例子 299
10.2 TDI的過濾框架 299
10.2.1 綁定TDI的設備 299
10.2.2 唯一的分發函數 300
10.2.3 過濾框架的實現 302
10.2.4 主要過濾的請求類型 304
10.3 生成請求:獲取地址 305
10.3.1 過濾生成請求 305
10.3.2 准備解析IP地址與埠 307
10.3.3 獲取生成的IP地址和埠 308
10.3.4 連接終端的生成與相關信息的保存 310
10.4 控制請求 311
10.4.1 TDI_ASSOCIATE_ADDRESS的過濾 311
10.4.2 TDI_CONNECT的過濾 313
10.4.3 其他的次功能號 314
10.4.4 設置事件的過濾 316
10.4.5 TDI_EVENT_CONNECT類型的設置事件的過濾 318
10.4.6 直接獲取發送函數的過濾 320
10.4.7 清理請求的過濾 322
10.5 本書例子tdifw.lib的應用 323
10.5.1 tdifw庫的回調介面 323
10.5.2 tdifw庫的使用例子 325
本章的示例代碼 326
練習題 327
第11章 NDIS協議驅動 328
網路的連接只是外表而已,實際上,最終它們變成了一個個在網線上往返的網路包。高明的黑客是不會去用Socket來生成連接的。把黑暗的信息隱藏在單個的數據包里,你還可以發現它們嗎?本章介紹的NDIS協議驅動,是Windows網路抓包工具的基礎。
11.1 乙太網包和網路驅動架構 329
11.1.1 乙太網包和協議驅動 329
11.1.2 NDIS網路驅動 330
11.2 協議驅動的DriverEntry 331
11.2.1 生成控制設備 331
11.2.2 注冊協議 333
11.3 協議與網卡的綁定 335
11.3.1 協議與網卡的綁定概念 335
11.3.2 綁定回調處理的實現 335
11.3.3 協議綁定網卡的API 338
11.3.4 解決綁定競爭問題 339
11.3.5 分配接收和發送的包池與緩沖池 340
11.3.6 OID請求的發送和請求完成回調 342
11.3.7 ndisprotCreateBinding的最終實現 345
11.4 綁定的解除 351
11.4.1 解除綁定使用的API 351
11.4.2 ndisprotShutdownBinding的實現 353
11.5 在用戶態操作協議驅動 356
11.5.1 協議的收包與發包 356
11.5.2 在用戶態編程打開設備 357
11.5.3 用DeviceIoControl發送控制請求 358
11.5.4 用WriteFile發送數據包 360
11.5.5 用ReadFile發送數據包 362
11.6 在內核態完成功能的實現 363
11.6.1 請求的分發與實現 363
11.6.2 等待設備綁定完成與指定設備名 364
11.6.3 指派設備的完成 365
11.6.4 處理讀請求 368
11.6.5 處理寫請求 370
11.7 協議驅動的接收回調 374
11.7.1 和接收包有關的回調函數 374
11.7.2 ReceiveHandler的實現 376
11.7.3 TransferDataCompleteHandler的實現 380
11.7.4 ReceivePacketHandler的實現 381
11.7.5 接收數據包的入隊 383
11.7.6 接收數據包的出隊和讀請求的完成 385
本章的示例代碼 388
練習題 389
第12章 NDIS小埠驅動 390
如果厭煩了漏洞百出的乙太網,還有什麼可以充當我的網路介面嗎?當然,一切能通信的設備,皆有替代乙太網的潛質。即使您不願意修改無數通過TCP介面編程的應用程序,我們依然可以用其他通信設備來虛擬網卡。本章介紹小埠驅動來虛擬網卡的技術。
12.1 小埠驅動的應用與概述 391
12.1.1 小埠驅動的應用 391
12.1.2 小埠驅動的實例 392
12.1.3 小埠驅動的運作與編程概述 393
12.2 小埠驅動的初始化 393
12.2.1 小埠驅動的DriverEntry 393
12.2.2 小埠驅動的適配器結構 396
12.2.3 配置信息的讀取 397
12.2.4 設置小埠適配器上下文 398
12.2.5 MPInitialize的實現 399
12.2.6 MPHalt的實現 402
12.3 打開ndisprot設備 403
12.3.1 I/O目標 403
12.3.2 給IO目標發送DeviceIoControl請求 404
12.3.3 打開ndisprot介面並完成配置設備 406
12.4 使用ndisprot發送包 409
12.4.1 小埠驅動的發包介面 409
12.4.2 發送控制塊(TCB) 409
12.4.3 遍歷包組並填寫TCB 412
12.4.4 寫請求的構建與發送 415
12.5 使用ndisprot接收包 417
12.5.1 提交數據包的內核API 417
12.5.2 從接收控制塊(RCB)提交包 418
12.5.3 對ndisprot讀請求的完成函數 420
12.5.4 讀請求的發送 422
12.5.5 用於讀包的WDF工作任務 424
12.5.6 ndisedge讀工作任務的生成與入列 426
12.6 其他的特徵回調函數的實現 428
12.6.1 包的歸還 428
12.6.2 OID查詢處理的直接完成 429
12.6.3 OID設置處理 432
本章的示例代碼 433
練習題 434
第13章 NDIS中間層驅動 435
當我們不滿足於抓包和發包,而試圖控制本機上流入和流出的所有數據包的時候,NDIS中間層驅動是最終的選擇。防火牆的功能在這里得到加強:我們不再滿足於看到連接、埠、對方IP地址,而是要看到每一個數據包的原始結構。本章介紹NDIS中間層驅動。
13.1 NDIS中間層驅動概述 436
13.1.1 Windows網路架構總結 436
13.1.2 NDIS中間層驅動簡介 437
13.1.3 NDIS中間層驅動的應用 438
13.1.4 NDIS包描述符結構深究 439
13.2 中間層驅動的入口與綁定 442
13.2.1 中間層驅動的入口函數 442
13.2.2 動態綁定NIC設備 443
13.2.3 小埠初始化(MpInitialize) 445
13.3 中間層驅動發送數據包 447
13.3.1 發送數據包原理 447
13.3.2 包描述符「重利用」 448
13.3.3 包描述符「重申請」 451
13.3.4 發送數據包的非同步完成 453
13.4 中間層驅動接收數據包 455
13.4.1 接收數據包概述 455
13.4.2 用PtReceive接收數據包 456
13.4.3 用PtReceivePacket接收 461
13.4.4 對包進行過濾 463
13.5 中間層驅動程序查詢和設置 466
13.5.1 查詢請求的處理 466
13.5.2 設置請求的處理 468
13.6 NDIS句柄 470
13.6.1 不可見的結構指針 470
13.6.2 常見的NDIS句柄 471
13.6.3 NDIS句柄誤用問題 473
13.6.4 一種解決方案 475
13.7 生成普通控制設備 476
13.7.1 在中間層驅動中添加普通設備 476
13.7.2 使用傳統方法來生成控制設備 478
本章的示例代碼 483
練習題 483
附錄A 如何使用本書的源碼光碟 485
4. 誰知道<<WINDOWS核心編程>>第5版的目錄,微軟強人寫的
目 錄
譯者序
前言
第一部分 程序員必讀
第1章 對程序錯誤的處理 1
1.1 定義自己的錯誤代碼 4
1.2 ErrorShow示例應用程序 5
第2章 Unicode 11
2.1 字元集 11
2.1.1 單位元組與雙位元組字元集 11
2.1.2 Unicode:寬位元組字元集 12
2.2 為什麼使用Unicode 13
2.3 Windows 2000與Unicode 13
2.4 Windows 98與Unicode 13
2.5 Windows CE與Unicode 14
2.6 需要注意的問題 14
2.7 對COM的簡單說明 14
2.8 如何編寫Unicode源代碼 15
2.8.1 C運行期庫對Unicode的支持 15
2.8.2 Windows定義的Unicode數據類型 17
2.8.3 Windows中的Unicode函數和ANSI
函數 17
2.8.4 Windows字元串函數 19
2.9 成為符合ANSI和Unicode的應用程序 19
2.9.1 Windows字元串函數 19
2.9.2 資源 22
2.9.3 確定文本是ANSI文本還是Unicode
文本 22
2.9.4 在Unicode與ANSI之間轉換字元串 23
第3章 內核對象 27
3.1 什麼是內核對象 27
3.1.1 內核對象的使用計數 27
3.1.2 安全性 28
3.2 進程的內核對象句柄表 30
3.2.1 創建內核對象 30
3.2.2 關閉內核對象 32
3.3 跨越進程邊界共享內核對象 32
3.3.1 對象句柄的繼承性 32
3.3.2 改變句柄的標志 35
3.3.3 命名對象 36
3.3.4 終端伺服器的名字空間 39
3.3.5 復制對象句柄 39
第二部分 編程的具體方法
第4章 進程 45
4.1 編寫第一個Windows應用程序 46
4.1.1 進程的實例句柄 49
4.1.2 進程的前一個實例句柄 50
4.1.3 進程的命令行 50
4.1.4 進程的環境變數 51
4.1.5 進程的親緣性 54
4.1.6 進程的錯誤模式 54
4.1.7 進程的當前驅動器和目錄 54
4.1.8 進程的當前目錄 55
4.1.9 系統版本 56
4.2 CreateProcess函數 58
4.2.1 pszApplicationName和
pszCommandLine 59
4.2.2 psa Process、psa Thread和
binherit Handles 60
4.2.3 fdwCreate 62
4.2.4 pvEnvironment 64
4.2.5 pszCurDir 64
4.2.6 psiStartInfo 64
4.2.7 ppiProcInfo 67
4.3 終止進程的運行 69
4.3.1 主線程的進入點函數返回 69
4.3.2 ExitProcess函數 69
4.3.3 TerminateProcess函數 70
4.3.4 進程終止運行時出現的情況 71
4.4 子進程 72
4.5 枚舉系統中運行的進程 73
第5章 作業 91
5.1 對作業進程的限制 93
5.2 將進程放入作業 99
5.3 終止作業中所有進程的運行 99
5.4 查詢作業統計信息 100
5.5 作業通知信息 103
5.6 JobLab示例應用程序 104
第6章 線程的基礎知識 121
6.1 何時創建線程 121
6.2 何時不能創建線程 122
6.3 編寫第一個線程函數 123
6.4 CreateThread函數 124
6.4.1 psa 124
6.4.2 cbStack 124
6.4.3 pfnStartAddr和pvParam 125
6.4.4 fdwCreate 126
6.4.5 pdwThreadID 126
6.5 終止線程的運行 127
6.5.1 線程函數返回 127
6.5.2 ExitThread函數 127
6.5.3 TerminateThread函數 127
6.5.4 在進程終止運行時撤消線程 128
6.5.5 線程終止運行時發生的操作 128
6.6 線程的一些性質 129
6.7 C/C++運行期庫的考慮 131
6.7.1 Oops—錯誤地調用了Create Thread 138
6.7.2 不應該調用的C/C++運行期庫函數 138
6.8 對自己的ID概念應該有所了解 139
第7章 線程的調度、優先順序和親緣性 142
7.1 暫停和恢復線程的運行 143
7.2 暫停和恢復進程的運行 144
7.3 睡眠方式 145
7.4 轉換到另一個線程 145
7.5 線程的運行時間 146
7.6 運用環境結構 148
7.7 線程的優先順序 152
7.8 對優先順序的抽象說明 153
7.9 程序的優先順序 156
7.9.1 動態提高線程的優先順序等級 158
7.9.2 為前台進程調整調度程序 159
7.9.3 Scheling Lab示例應用程序 160
7.10 親緣性 167
第8章 用戶方式中線程的同步 172
8.1 原子訪問:互鎖的函數家族 172
8.2 高速緩存行 177
8.3 高級線程同步 178
8.4 關鍵代碼段 180
8.4.1 關鍵代碼段准確的描述 182
8.4.2 關鍵代碼段與循環鎖 185
8.4.3 關鍵代碼段與錯誤處理 185
8.4.4 非常有用的提示和技巧 186
第9章 線程與內核對象的同步 190
9.1 等待函數 191
9.2 成功等待的副作用 194
9.3 事件內核對象 195
9.4 等待定時器內核對象 204
9.4.1 讓等待定時器給APC項排隊 207
9.4.2 定時器的鬆散特性 209
9.5 信標內核對象 210
9.6 互斥對象內核對象 211
9.6.1 釋放問題 213
9.6.2 互斥對象與關鍵代碼段的比較 214
9.6.3 Queue示例應用程序 214
9.7 線程同步對象速查表 223
9.8 其他的線程同步函數 224
9.8.1 非同步設備I/O 224
9.8.2 WaitForInputIdle 224
9.8.3 MsgWaitForMultipleObjects (Ex) 225
9.8.4 WaitForDebugEvent 225
9.8.5 SingleObjectAndWait 226
第10章 線程同步工具包 228
10.1 實現關鍵代碼段:Optex 228
10.2 創建線程安全的數據類型和反信標 239
10.3 單個寫入程序/多個閱讀程序的保護 251
10.4 實現一個WaitForMultipleExpressions
函數 259
第11章 線程池的使用 274
11.1 方案1:非同步調用函數 275
11.2 方案2:按規定的時間間隔調用函數 277
11.3 方案3:當單個內核對象變為已通知狀態
時調用函數 283
11.4 方案4:當非同步I/O請求完成運行時調用
函數 285
第12章 纖程 287
12.1 纖程的操作 287
12.2 Counter示例應用程序 289
第三部分 內 存 管 理
第13章 Windows的內存結構 299
13.1 進程的虛擬地址空間 299
13.2 虛擬地址空間如何分區 300
13.2.1 NuLL 指針分配的分區—適用於
Windows 2000和Windows 98 300
13.2.2 MS-DOS/16位Windows 應用程序兼容
分區—僅適用於Windows 98 301
13.2.3 用戶方式分區—適用於Windows 2000
和Windows 98 301
13.2.4 64 KB禁止進入的分區—僅適用
於Windows 2000 302
13.2.5 共享的MMF分區—僅適用於
Windows 98 303
13.2.6 內核方式分區—適用於Windows
2000和Windows 98 303
13.3 地址空間中的區域 303
13.4 提交地址空間區域中的物理存儲器 304
13.5 物理存儲器與頁文件 304
13.6 保護屬性 307
13.6.1 Copy-On-Write 訪問 308
13.6.2 特殊的訪問保護屬性的標志 309
13.7 綜合使用所有的元素 309
13.7.1 區域的內部情況 312
13.7.2 與Windows 98地址空間的差別 315
13.8 數據對齊的重要性 319
第14章 虛擬內存 323
14.1 系統信息 323
14.2 虛擬內存的狀態 330
14.3 確定地址空間的狀態 336
14.3.1 VMQuery函數 337
14.3.2 虛擬內存表示例應用程序 343
第15章 在應用程序中使用虛擬內存 354
15.1 在地址空間中保留一個區域 354
15.2 在保留區域中的提交存儲器 355
15.3 同時進行區域的保留和內存的提交 356
15.4 何時提交物理存儲器 357
15.5 回收虛擬內存和釋放地址空間區域 358
15.5.1 何時回收物理存儲器 359
15.5.2 虛擬內存分配的示例應用程序 360
15.6 改變保護屬性 368
15.7 清除物理存儲器的內容 369
15.8 地址窗口擴展—適用於
Windows 2000 372
第16章 線程的堆棧 385
16.1 Windows 98下的線程堆棧 387
16.2 C/C++運行期庫的堆棧檢查函數 389
16.3 Summation示例應用程序 390
第17章 內存映射文件 397
17.1 內存映射的可執行文件和DLL
文件 397
17.1.1 可執行文件或DLL的多個實例
不能共享靜態數據 398
17.1.2 在可執行文件或DLL的多個實
例之間共享靜態數據 400
17.1.3 AppInst示例應用程序 404
17.2 內存映射數據文件 409
17.2.1 方法 1:一個文件,一個緩存 409
17.2.2 方法 2:兩個文件,一個緩存 409
17.2.3 方法 3:一個文件,兩個緩存 410
17.2.4 方法 4:一個文件,零緩存 410
17.3 使用內存映射文件 410
17.3.1 步驟 1:創建或打開文件內核
對象 411
17.3.2 步驟 2:創建一個文件映射內核
對象 412
17.3.3 步驟 3:將文件數據映射到進程
的地址空間 414
17.3.4 步驟4:從進程的地址空間中撤消
文件數據的映像 416
17.3.5 步驟 5和步驟 6:關閉文件映射對象
和文件對象 417
17.3.6 文件倒序示例應用程序 418
17.4 使用內存映射文件來處理大文件 426
17.5 內存映射文件與數據視圖的相關性 427
17.6 設定內存映射文件的基地址 428
17.7 實現內存映射文件的具體方法 429
17.8 使用內存映射文件在進程之間共享
數據 431
17.9 頁文件支持的內存映射文件 431
17.10 稀疏提交的內存映射文件 438
第18章 堆棧 451
18.1 進程的默認堆棧 451
18.2 為什麼要創建輔助堆棧 452
18.2.1 保護組件 452
18.2.2 更有效的內存管理 453
18.2.3 進行本地訪問 453
18.2.4 減少線程同步的開銷 453
18.2.5 迅速釋放堆棧 453
18.3 如何創建輔助堆棧 454
18.3.1 從堆棧中分配內存塊 455
18.3.2 改變內存塊的大小 456
18.3.3 了解內存塊的大小 456
18.3.4 釋放內存塊 457
18.3.5 撤消堆棧 457
18.3.6 用C++程序來使用堆棧 457
18.4 其他堆棧函數 460
第四部分 動態鏈接庫
第19章 DLL基礎 463
19.1 DLL與進程的地址空間 464
19.2 DLL的總體運行情況 465
19.3 創建DLL模塊 467
19.3.1 輸出的真正含義是什麼 469
19.3.2 創建用於非Visual C++工具
的DLL 471
19.4 創建可執行模塊 472
19.5 運行可執行模塊 474
第20章 DLL的高級操作技術 477
20.1 DLL模塊的顯式載入和
符號鏈接 477
20.1.1 顯式載入DLL模塊 478
20.1.2 顯式卸載DLL模塊 479
20.1.3 顯式鏈接到一個輸出符號 480
20.2 DLL的進入點函數 481
20.2.1 DLL_PROCESS_ATTACH通知 482
20.2.2 DLL_PROCESS_DETACH通知 483
20.2.3 DLL_THREAD_ATTACH通知 485
20.2.4 DLL_THREAD_DETACH通知 485
20.2.5 順序調用DllMain 486
20.2.6 DllMain與C/C++運行期庫 488
20.3 延遲載入DLL 489
20.4 函數轉發器 499
20.5 已知的DLL 499
20.6 DLL轉移 500
20.7 改變模塊的位置 501
20.8 綁定模塊 506
第21章 線程本地存儲器 509
21.1 動態TLS 509
21.2 靜態TLS 513
第22章 插入DLL和掛接API 515
22.1 插入DLL:一個例子 515
22.2 使用注冊表來插入DLL 517
22.3 使用Windows掛鉤來插入DLL 518
22.4 使用遠程線程來插入DLL 531
22.4.1 Inject Library 示例應用程序 534
22.4.2 Image Walk DLL 541
22.5 使用特洛伊DLL來插入DLL 544
22.6 將DLL作為調試程序來插入 544
22.7 用Windows 98上的內存映射文件
插入代碼 544
22.8 用CreateProcess插入代碼 544
22.9 掛接API的一個示例 545
22.9.1 通過改寫代碼來掛接API 546
22.9.2 通過操作模塊的輸入節來掛接API 546
22.9.3 LastMsgBoxInfo示例應用程序 549
第五部分 結構化異常處理
第23章 結束處理程序 565
23.1 通過例子理解結束處理程序 566
23.2 Funcenstein1 566
23.3 Funcenstein2 566
23.4 Funcenstein3 568
23.5 Funcfurter1 568
23.6 突擊測驗:FuncaDoodleDoo 569
23.7 Funcenstein4 570
23.8 Funcarama1 571
23.9 Funcarama2 572
23.10 Funcarama3 572
23.11 Funcarama4:最終的邊界 573
23.12 關於finally塊的說明 574
23.13 Funcfurter2 575
23.14 SEH結束處理示常式序 576
第24章 異常處理程序和軟體異常 578
24.1 通過例子理解異常過濾器和異常處理
程序 578
24.1.1 Funcmeister1 578
24.1.2 Funcmeister2 579
24.2 EXCEPTION_EXECUTE_HANDLER 580
24.2.1 一些有用的例子 581
24.2.2 全局展開 583
24.2.3 暫停全局展開 585
24.3 EXCEPTION_CONTINUE_
EXECUTION 586
24.4 EXCEPTION_CONTINUE_
SEARCH 588
24.5 Get Exception Code 589
24.6 Get Exception Information 592
24.7 軟體異常 595
第25章 未處理異常和C++異常 598
25.1 即時調試 600
25.2 關閉異常消息框 601
25.2.1 強制進程終止運行 601
25.2.2 包裝一個線程函數 601
25.2.3 包裝所有的線程函數 601
25.2.4 自動調用調試程序 602
25.3 程序員自己調用UnhandledException
Filter 602
25.4 UnhandledExceptionFilter函數的一些
細節 603
25.5 異常與調試程序 604
25.6 C++異常與結構性異常的對比 618
第六部分 窗 口
第26章 窗口消息 623
26.1 線程的消息隊列 623
26.2 將消息發送到線程的消息隊列中 625
26.3 向窗口發送消息 626
26.4 喚醒一個線程 630
26.4.1 隊列狀態標志 630
26.4.2 從線程的隊列中提取消息的
演算法 631
26.4.3 利用內核對象或隊列狀態標
志喚醒線程 634
26.5 通過消息發送數據 636
26.6 Windows如何處理ANSI/Unicode
字元和字元串 642
第27章 硬體輸入模型和局部輸入狀態 645
27.1 原始輸入線程 645
27.2 局部輸入狀態 646
27.2.1 鍵盤輸入與焦點 647
27.2.2 滑鼠游標管理 649
27.3 將虛擬輸入隊列同局部輸入狀態掛接
在一起 651
27.3.1 LISLab 示常式序 652
27.3.2 LISWatch 示常式序 666
第七部分 附 錄
附錄A 建立環境 675
附錄B 消息分流器、子控制項宏和API宏 686
5. 哪裡可以看到windows api函數的源代碼
呵呵,一樓回答得0分才對。《Windows內核原理與實現》講的是windows內核代碼,它和api源碼沒有絲毫關系,並且 windows核心代碼的介面是在ntdll.dll中的,windows api 只是導入了這些動態鏈接庫而已,沒有什麼技術難度的。