Windows 內核編程

譚文,陳銘霖

買這商品的人也買了...

商品描述

本書前身是《Windows內核安全與驅動開發》,重點圍繞Windows操作系統的機制介紹內核安全編程技術,除了少數特殊章節,大部分內容均適用於Windows 2000至Windows 10操作系統,體系結構覆蓋32位以及64位。同時本書也深入淺出地介紹了匯編基礎和系統內核機制。本書共分為三篇,分別從不同的角度介紹內核編程技術。第1篇面向零基礎的讀者,其中“內核編程環境”“內核驅動運行與調試”“內核編程基礎”重點介紹與內核編程相關的基本知識、開發環境搭建,以及基本的編程機制。“應用與內核通信”和“64位和32位內核開發差異”主要介紹應用層編程與內核編程的數據交互。最後,介紹了編程過程所需註意的事項,以及設計技巧。第2篇結合操作系統的機制,從最簡單的“串口的過濾”開始,介紹了“鍵盤的過濾”‘“磁盤的過濾”“文件系統的過濾”“Windows過濾平臺”“NDIS協議驅動”“NDIS小埠驅動”,以及“NDIS中間層驅動”。覆蓋了整個Windows系統的主流過濾框架,並且深入剖析了文件透明加密解密的原理。第3篇側重安全技術,重點介紹了安全編程所需要使用的知識,如“IA-32匯編基礎”“Windows內核掛鉤”“Windows通知與回調”“保護進程”,以及“代碼註入與防註入”。本書由具有十多年終端安全開發經驗的從業人員編寫,以簡潔實用為準則,理論與實際案例相結合。適用於電腦軟件安全從業人員、有一定C語言基礎且對電腦安全感興趣的愛好者。

作者簡介

譚文

網名楚狂人,已有十七年客戶端安全軟件開發經驗。先後在NEC、英特爾亞太研發有限公司、騰訊科技任職。
曾經從事過企業安全軟件、x86版Android的houdini項目、騰訊電腦管家、騰訊遊戲安全等開發工作。
對Windows內核有深入研究,現任騰訊科技遊戲安全團隊驅動程序開發負責人,專家工程師。

陳銘霖

十餘年終端開發經驗,先後任深信服科技架構師、騰訊科技高級工程師;
曾主導騰訊電腦管家內核安全驅動開發,以及疑難病毒打擊項目、騰訊Windows服務器安全開發項目;
對Windows及macOS系統有深入研究,在To C以及To B行業有豐富的開發經驗,
現任數篷科技高級架構師,終端安全負責人。

目錄大綱

第1篇基礎篇
第1章內核編程環境002
1.1下載開發編譯環境002
1.1.1編譯環境介紹002
1.1.2下載Visual Studio與WDK 004
1.2編寫第一個C文件006
1.2.1通過Visual Studio新建工程006
1.2.2內核入口函數007
1.2.3編寫入口函數體008
1.3編譯第一個驅動010
1.3.1通過Visual Studio編譯010
1.3.2通過WDK直接編譯011

第2章內核驅動運行與調試013
2.1驅動的運行013
2.2服務的基本操作015
2.2.1打開服務管理器015
2.2.2服務的註冊016
2.2.3服務的啟動與停止018
2.2.4服務的刪除019
2.2.5服務的例子020
2.2.6服務小結022
2.3驅動的調試022
2.3 .1基於VS+WDK環境調試022
2.3.2基於Windbg調試026

第3章內核編程基礎029
3.1上下文環境029
3.2中斷請求級別031
3.3驅動異常033
3.4字符串操作034
3.5鍊錶036
3.5.1頭節點初始化038
3.5.2節點插入038
3.5.3鍊錶遍歷039
3.5.4節點移除040
3.6自旋鎖040
3.6.1使用自旋鎖040
3.6.2在雙向鍊錶中使用自旋鎖041
3.6.3使用隊列自旋鎖提高性能042
3.7內存分配043
3.7.1常規內存分配043
3.7.2旁視列表045
3.8對象與句柄049
3.9註冊表054
3.9.1註冊表的打開與關閉054
3.9.2註冊表的修改056
3.9.3註冊表的讀取057
3.10文件操作060
3.10.1文件的打開與關閉060
3.10.2文件的讀寫063
3.11線程與事件066
3.11.1使用系統線程066
3.11.2使用同步事件067

第4章應用與內核通信070
4.1內核方面的編程071
4.1.1生成控制設備071
4.1.2控制設備的名字和符號鏈接073
4.1.3控制設備的刪除074
4.1.4分發函數074
4.1.5請求的處理076
4 .2應用方面的編程077
4.2.1基本的功能需求077
4.2.2在應用程序中打開與關閉設備077
4.2.3設備控制請求078
4.2.4內核中的對應處理080
4.2.5結合測試的效果082

第5章64位和32位內核開發差異083
5.1 64位系統新增機制083
5.1.1 WOW64子系統083
5.1.2 PatchGuard技術086
5.1.3 64位驅動的編譯、安裝與運行086
5.2編程差異087
5.2.1彙編嵌入變化087
5.2.2預處理與條件編譯088
5.2.3數據結構調整088

第6章內核編程技巧090
6.1初始化賦值問題090
6.2有效性判斷091
6.3一次性申請092
6.4獨立性與最小化原則095
6.5嵌套陷阱097
6.6穩定性處理098
6.6.1事前處理098
6.6.2事中處理100
6.6.3事後處理104

第2篇過濾篇
第7章串口的過濾106
7.1過濾的概念106
7.1.1設備綁定的內核API之一106
7.1.2設備綁定的內核API之二107
7.1.3生成過濾設備並綁定108
7.1.4從名字獲得設備對象110
7.1.5綁定所有串口111
7.2獲得實際數據112
7.2.1請求的區分112
7.2.2請求的結局113
7.2.3寫請求的數據114
7.3完整的代碼114
7.3 .1完整的分發函數114
7.3.2如何動態卸載116
7.3.3代碼的編譯與運行117

第8章鍵盤的過濾119
8.1技術原理120
8.1.1預備知識120
8. 1.2 Windows中從擊鍵到內核120
8.1.3鍵盤硬件原理122
8.2鍵盤過濾的框架122
8.2.1找到所有的鍵盤設備122
8.2.2應用設備擴展125
8.2.3鍵盤過濾模塊的DriverEntry 127
8.2.4鍵盤過濾模塊的動態卸載127
8.3鍵盤過濾的請求處理129
8.3.1通常的處理129
8.3.2 PNP的處理130
8.3.3讀的處理131
8.3.4讀完成的處理132
8.4從請求中打印出按鍵信息133
8.4.1從緩衝區中獲得KEYBOARD_INPUT_DATA 133
8.4.2從KEYBOARD_INPUT_DATA中得到鍵134
8.4.3從MakeCode到實際字符134
8.5 Hook分發函數136
8.5.1獲得類驅動對象136
8.5.2修改類驅動的分發函數指針137
8.5.3類驅動之下的端口驅動138
8.5.4端口驅動和類驅動之間的協作機制139
8.5.5找到關鍵的回調函數的條件140
8.5.6定義常數和數據結構140
8. 5.7打開兩種鍵盤端口驅動尋找設備141
8.5.8搜索在KbdClass類驅動中的地址143
8.6 Hook鍵盤中斷反過濾145
8.6.1中斷:IRQ和INT 146
8.6.2如何修改IDT 147
8.6.3替換IDT中的跳轉地址148
8.6.4 QQ的PS/2反過濾措施149
8.7直接用端口操作鍵盤150
8.7.1讀取鍵盤數據和命令端口150
8.7.2 p2cUserFilter的最終實現151

第9章磁盤的虛擬153
9.1虛擬的磁盤153
9.2一個具體的例子153
9.3入口函數154
9.3.1入口函數的定義154
9.3.2 Ramdisk驅動的入口函數155
9.4 EvtDriverDeviceAdd函數156
9.4.1 EvtDriverDeviceAdd的定義156
9.4.2局部變量的聲明157
9.4.3磁盤設備的創建157
9.4.4如何處理髮往設備的請求158
9.4.5用戶配置的初始化160
9.4.6鏈接給應用程序161
9.5 FAT12 /16磁盤捲初始化163
9.5.1磁盤捲結構簡介163
9.5.2 Ramdisk對磁盤的初始化164
9.6驅動中的請求處理170
9.6.1請求的處理170
9.6.2讀/寫請求171
9.6.3 DeviceIoControl請求172
9.7 Ramdisk的編譯和安裝175
9.7.1編譯175
9.7.2安裝175
9.7.3對安裝的深入探究175

第10章磁盤的過濾177
10.1磁盤過濾驅動的概念177
10.1.1設備過濾和類過濾177
10.1.2磁盤設備和磁盤捲設備過濾驅動177
10.1.3註冊表和磁盤捲設備過濾驅動178
10.2具有還原功能的磁盤捲過濾驅動178
10.2.1簡介178
10.2.2基本思想179
10.3驅動分析179
10.3.1 DriverEntry函數179
10. 3.2 AddDevice函數180
10.3.3 PnP請求的處理184
10.3.4 Power請求的處理188
10.3.5 DeviceIoControl請求的處理189
10.3.6 bitmap的作用和分析192
10.3 .7 boot驅動完成回調函數和稀疏文件198
10.3.8讀/寫請求的處理200

第11章文件系統的過濾與監控209
11.1文件系統的設備對象210
11.1.1控制設備與卷設備210
11.1.2生成自己的一個控制設備211
11.2文件系統的分發函數212
11.2.1普通的分發函數212
11.2.2文件過濾的快速IO分發函數213
11.2.3快速IO分發函數的一個實現215
11.2.4快速IO分發函數逐個簡介216
11 .3設備的綁定前期工作217
11.3.1動態地選擇綁定函數217
11.3.2註冊文件系統變動回調219
11.3.3文件系統變動回調的一個實現220
11.3.4文件系統識別器221
11.4文件系統控制設備的綁定222
11.4.1生成文件系統控制設備的過濾設備222
11.4.2綁定文件系統控制設備223
11.4.3利用文件系統控制請求225
11.5文件系統卷設備的綁定227
11.5.1從IRP中獲得VPB指針227
11.5.2設置完成函數並等待IRP完成228
11.5.3卷掛載IRP完成後的工作231
11.5.4完成函數的相應實現233
11.5.5綁定卷的實現234
11.6讀/寫操作的過濾236
11.6.1設置一個讀處理函數236
11.6.2設備對象的區分處理237
11.6.3解析讀請求中的文件信息238
11.6.4讀請求的完成241
11.7其他操作的過濾244
11.7.1文件對象的生存週期244
11.7. 2文件的打開與關閉245
11.7.3文件的刪除247
11.8路徑過濾的實現248
11.8.1取得文件路徑的三種情況248
11.8.2打開成功後獲取路徑249
11. 8.3在其他時刻獲得文件路徑250
11.8.4在打開請求完成之前獲得路徑名251
11.8.5把短名轉換為長名253
11.9把sfilter編譯成靜態庫254
11.9 .1如何方便地使用sfilter 254
11.9.2初始化回調、卸載回調和綁定回調254
11.9.3綁定與回調256
11.9.4插入請求回調257
11.9.5如何利用sfilter .lib 259

第12章文件系統透明加密263
12.1文件透明加密的應用263
12.1.1防止企業信息洩密263
12.1.2文件透明加密防止企業信息洩密263
12.1.3文件透明加密軟件的例子264
12.2區分進程265
12.2.1機密進程與普通進程265
12.2.2找到進程名字的位置266
12.2.3得到當前進程的名字267
12.3內存映射與文件緩衝268
12.3.1記事本的內存映射文件268
12.3.2 Windows的文件緩衝269
12.3.3文件緩衝:明文還是密文的選擇270
12.3.4清除文件緩衝271
12.4加密標識274
12.4.1保存在文件外、文件頭還是文件尾274
12.4.2隱藏文件頭的大小275
12.4.3隱藏文件頭的設置偏移277
12.4.4隱藏文件頭的讀/寫偏移277
12.5文件加密表278
12.5.1何時進行加密操作278
12.5.2文件控制塊與文件對象279
12.5.3文件加密表的數據結構與初始化280
12.5.4文件加密表的操作:查詢281
12.5.5文件加密表的操作:添加282
12.5.6文件加密表的操作:刪除283
12.6文件打開處理284
12. 6.1直接發送IRP進行查詢與設置操作285
12.6.2直接發送IRP進行讀/寫操作287
12.6.3文件的非重入打開288
12.6.4文件的打開預處理291
12 .7讀/寫加密和解密296
12.7.1在讀取時進行解密296
12.7.2分配與釋放MDL 297
12.7.3寫請求加密298
12.8 crypt_file的組裝300
12.8 .1 crypt_file的初始化300
12.8.2 crypt_file的IRP預處理301
12.8.3 crypt_file的IRP後處理304

第13章文件系統微過濾驅動308
13.1文件系統微過濾驅動簡介308
13.1 .1文件系統微過濾驅動的由來308
13.1.2 Minifilter的優點與不足309
13.2 Minifilter的編程框架309
13.2.1微文件系統過濾的註冊310
13.2.2微過濾器的數據結構311
13.2.3卸載回調函數314
13.2.4預操作回調函數314
13.2.5後操作回調函數317
13.2.6其他回調函數318
13.3 Minifilter如何與應用程序通信320
13.3.1建立通信端口的方法320
13.3.2在用戶態通過DLL使用通信端口的範例322
13.4 Minifilter的安裝與加載325
13.4. 1安裝Minifilter的INF文件325
13.4.2啟動安裝完成的Minifilter 326

第14章網絡傳輸層過濾328
14.1 TDI概要328
14.1.1為何選擇TDI 328
14.1.2從socket到Windows內核329
14.1.3 TDI過濾的代碼例子330
14.2 TDI的過濾框架330
14.2.1綁定TDI的設備330
14.2.2唯一的分發函數331
14.2.3過濾框架的實現333
14.2.4主要過濾的請求類型335
14.3生成請求:獲取地址336
14.3.1過濾生成請求336
14.3.2準備解析IP地址與端口337
14.3.3獲取生成的IP地址和端口338
14.3.4連接終端的生成與相關信息的保存340
14.4控制請求341
14.4. 1 TDI_ASSOCIATE_ADDRESS的過濾341
14.4.2 TDI_CONNECT的過濾343
14.4.3其他的次功能號344
14.4.4設置事件的過濾345
14.4.5 TDI_EVENT_CONNECT類型的設置事件的過濾346
14. 4.6直接獲取發送函數的過濾348
14.4.7清理請求的過濾350
14.5本書例子tdifw.lib的應用351
14.5.1 tdifw庫的回調接口351
14.5.2 tdifw庫的使用例子353

第15章Windows過濾平台355
15.1 WFP簡介355
15.2 WFP框架355
15.3基本對象模型357
15.3.1過濾引擎357
15.3.2墊片357
15.3.3呼出接口357
15.3.4分層358
15.3.5子層359
15.3.6過濾器360
15.3.7呼出接口回調函數364
15.4 WFP操作369
15.4.1呼出接口的註冊與卸載369
15.4.2呼出接口的添加與移除370
15 .4.3子層的添加與移除371
15.4.4過濾器的添加372
15.5 WFP過濾例子372

第16章NDIS協議驅動380
16.1以太網包和網絡驅動架構380
16.1 .1以太網包和協議驅動380
16.1.2 NDIS網絡驅動381
16.2協議驅動的DriverEntry 382
16.2.1生成控制設備382
16.2.2註冊協議383
16.3協議與網卡的綁定385
16.3.1協議與網卡的綁定概念385
16.3.2綁定回調處理的實現386
16.3.3協議綁定網卡的API 388
16.3.4解決綁定競爭問題389
16.3.5分配接收和發送的包池與緩衝池390
16.3.6 OID請求的發送和請求完成回調391
16.3.7 ndisprotCreateBinding的最終實現395
16.4綁定的解除400
16.4.1解除綁定使用的API 400
16.4.2 ndisprotShutdownBinding的實現402
16.5在用戶態操作協議驅動405
16.5.1協議的收包與發包405
16.5.2在用戶態編程打開設備405
16.5.3用DeviceIoControl發送控制請求407
16.5.4用WriteFile發送數據包409
16.5.5用ReadFile發送數據包410
16.6在內核態完成功能的實現412
16.6.1請求的分發與實現412
16.6.2等待設備綁定完成與指定設備名412
16.6.3指派設備的完成413
16.6.4處理讀請求416
16.6.5處理寫請求418
16.7協議驅動的接收回調422
16.7.1和接收包有關的回調函數422
16.7.2 ReceiveHandler的實現423
16.7.3 TransferDataCompleteHandler的實現427
16.7.4 ReceivePacketHandler的實現428
16.7.5接收數據包的入隊430
16.7.6接收數據包的出隊和讀請求的完成432

第17章NDIS小端口驅動437
17.1小端口驅動的應用與概述437
17. 1.1小端口驅動的應用437
17.1.2小端口驅動示例438
17.1.3小端口驅動的運作與編程概述438
17.2小端口驅動的初始化439
17.2.1小端口驅動的DriverEntry 439
17.2.2小端口驅動的適配器結構441
17.2.3配置信息的讀取442
17.2.4設置小端口適配器上下文443
17.2.5 MPInitialize的實現444
17.2. 6 MPHalt的實現447
17.3打開ndisprot設備447
17.3.1 IO目標447
17.3.2給IO目標發送DeviceIoControl請求449
17.3.3打開ndisprot接口並完成配置設備451
17.4使用ndisprot發送包453
17.4.1小端口驅動的發包接口453
17.4.2發送控制塊(TCB) 454
17.4.3遍歷包組並填寫TCB 456
17.4.4寫請求的構建與發送458
17.5使用ndisprot接收包461
17.5.1提交數據包的內核API 461
17.5.2從接收控制塊(RCB)提交包462
17.5.3對ndisprot讀請求的完成函數463
17.5.4讀請求的發送466
17.5.5用於讀包的WDF工作任務467
17.5. 6 ndisedge讀工作任務的生成與入列469
17.6其他的特徵回調函數的實現471
17.6.1包的歸還471
17.6.2 OID查詢處理的直接完成472
17.6.3 OID設置處理475

第18章NDIS中間層驅動477
18.1 NDIS中間層驅動概述477
18.1.1 Windows網絡架構總結477
18.1.2 NDIS中間層驅動簡介478
18.1.3 NDIS中間層驅動的應用479
18.1.4 NDIS包描述符結構深究480
18.2中間層驅動的入口與綁定483
18.2.1中間層驅動的入口函數483
18.2.2動態綁定NIC設備483
18.2.3小端口初始化(MpInitialize) 485
18.3中間層驅動發送數據包486
18.3.1發送數據包原理486
18.3.2包描述符“重利用” 488
18.3.3包描述符“重申請” 490
18.3.4發送數據包的異步完成492
18.4中間層驅動接收數據包494
18.4.1接收數據包概述494
18.4.2用PtReceive接收數據包494
18.4.3用PtReceivePacket接收499
18.4.4對包進行過濾501
18.5中間層驅動程序查詢和設置504
18.5.1查詢請求的處理504
18.5.2設置請求的處理506
18.6 NDIS句柄507
18.6.1不可見的結構指針507
18.6.2常見的NDIS句柄508
18.6.3 NDIS句柄誤用問題510
18.6.4一種解決方案512
18 .7生成普通控制設備512
18.7.1在中間層驅動中添加普通設備512
18.7.2使用傳統方法來生成控制設備515

第3篇應用篇
第19章IA-32彙編基礎522
19.1 x86內存、寄存器與堆棧522
19.1.1 _asm關鍵字522
19.1.2 x86中的mov指令523
19.1.3 x86中的寄存器與內存523
19.1.4賦值語句的實現524
19.2 x86中函數的實現525
19.2.1一個函數的例子525
19.2.2堆棧的介紹526
19.2.3寄存器的備份和恢復527
19.2.4內部變量與返回值529
19.3 x86中函數的調用與返回531
19.3.1函數的調用指令call 531
19.3.2通過堆棧傳遞參數532
19.3.3從函數返回533
19.3.4三種常見的調用協議535
19.4從32位彙編到64位彙編536
19.4.1 Intel 64與IA-32體系架構簡介536
19.4.2 64位指令與32位指令536
19.4.3通用寄存器537
19.5 64位下的函數實現538
19.5.1函數概覽538
19.5.2 32位參數的傳遞539
19.5.3 64位參數與返回值540
19.5.4棧空間的開闢與恢復541

第20章Windows內核掛鉤544
20.1系統服務描述符表掛鉤545
20.1.1系統服務描述符表(SSDT) 545
20.1.2系統服務描述符表掛鉤的意圖546
20.1.3尋找要掛鉤的函數的地址547
20.1.4函數被掛鉤的過程548
20.1.5具體實現的代碼549
20.2函數導出表掛鉤551
20.2.1內核函數的種類551
20.2 .2掛鉤IoCallDriver 553
20.2.3對跳轉地址進行修改554
20.3 Windows 7系統下IofCallDriver的跟踪555
20.4 Windows 7系統下內聯掛鉤558
20.4.1寫入跳轉指令並拷貝代碼558
20.4.2實現中繼函數560
20.5中斷與中斷掛鉤562
20.5.1 IA-32體系結構中的中斷562
20.5.2中斷處理過程563
20.5.3 64位模式下的中斷處理機制564
20.5.4多核下的中斷565
20.5.5 Windows中斷機制570
20.5.6 IDT Hook 573
20.5.7 IDT Hook實現安全防護574

第21章Windows通知與回調577
21.1 Windows的事件通知與回調577
21.2常用的事件通知577
21.2.1創建進程通知578
21.2.2創建線程通知582
21.2.3加載模塊通知583
21.2.4註冊表操作通知586
21.3 Windows回調機制592
21.3.1回調對象593
21.3.2回調對象的創建593
21.3.3回調對象的註冊594
21. 3.4回調的通告595
21.4安全的死角,回調的應用595

第22章保護進程597
22.1內核對像簡介597
22.2內核對象的結構598
22.3保護內核對象599
22.3. 1處理對象的打開600
22.3.2處理句柄的複制601
22.3.3處理句柄的繼承603
22.4進程的保護609
22.4.1保護原理609
22.4.2 Vista以後的進程對象保護611
22.4.3進程的其他保護612

第23章代碼注入與防注入613
23.1注入與防注入簡介613
23.2常用的注入方式614
23.3主動注入614
23.3.1 AppInit注入615
23.3.2 SPI注入618
23.3.3消息事件注入620
23.3.4其他注入621
23.4被動注入621
23.4.1遠線程注入621
23.4.2 APC注入622
23.4.3父子進程注入623
23.5防注入624
23.5.1防止主動注入624
23.5.2防止被動注入629
23.6總結630
附錄A如何使用本書的源碼631
附錄B練習題634