每个进程都有一个与它关联的环境块(environment block),这是在进程地址空间内分配的一块内存,其中包含字符串类似于:
=::=::\...
VarName=VarValue\0...
除第一个=::=::\外,块中可能还有其他字符串是以等号开头的,这种字符串不作为环境变量使用。
访问环境块的两种方式:
1)调用GetEnvironmentStrings获取完整的环境块
2)CUI程序专用,通过应用程序main入口点函数所接收的TCHAR* env[]参数来实现
2.调用GetEnvironmentStrings获取完整的环境块
1)不论是不是环境变量,暂且都打印出来
void DumpEnvStrings()
PTSTR pEnvBlock = GetEnvironmentStrings();
PTSTR pszCurrent = pEnvBlock;
int current = 0;
while (pszCurrent != NULL)
// 不论是不是环境变量,暂且都打印
_tprintf(TEXT("[%u] %s\r\n"), current, pszCurrent);
current++;
// 指针移动到字符串末尾
while (*pszCurrent != TEXT('\0'))
pszCurrent++;
pszCurrent++;
// 是否是最后一个字符串
if (*pszCurrent == TEXT('\0'))
break;
// 释放内存
FreeEnvironmentStrings(pEnvBlock);
// 将变量名拷贝到szName
size_t cbNameLength = (size_t)pszPos - (size_t)pszCurrent - sizeof(TCHAR);
hr = StringCbCopyN(szName, MAX_PATH, pszCurrent, cbNameLength);
if (FAILED(hr)) {
break;
// 获取值
hr = StringCbCopyN(szValue, MAX_PATH, pszPos, _tcslen(pszPos)+1);
if (SUCCEEDED(hr)) {
_tprintf(TEXT("[%u] %s=%s\r\n"), current, szName, szValue);
else if (hr == STRSAFE_E_INSUFFICIENT_BUFFER){
// 发生错误,检查截断
_tprintf(TEXT("[%u] %s=%s...\r\n"), current, szName, szValue);
else {
// 这里应该不能发生
_tprintf(TEXT("[%u] %s=???\r\n"), current, szName);
break;
else {
_tprintf(TEXT("[%u] %s\r\n"), current, pszCurrent);
current++;
// 指针移动到字符串末尾
while (*pszCurrent != TEXT('\0'))
pszCurrent++;
pszCurrent++;
// 是否是最后一个字符串
if (*pszCurrent == TEXT('\0'))
break;
// 释放内存
FreeEnvironmentStrings(pEnvBlock);
注:源码为学习《Windows核心编程》的一些尝试,非原创。若能有助于一二访客,幸甚。1.进程的环境变量每个进程都有一个与它关联的环境块(environment block),这是在进程地址空间内分配的一块内存,其中包含字符串类似于:=::=::\...VarName=VarValue\0...\0除第一个=::=::\外,块中可能还有其他字符串是以等号开头的,
本书从Windows内核编程出发,全面系统地介绍了串口、键盘、磁盘、文件系统、网络等相关的Windows内核模块的编程技术,以及基于这些技术实现的密码保护、防毒引擎、文件加密、网络嗅探、网络防火墙等信息安全软件的核心组件的具体编程。主要知识重点包括:Windows串口与键盘过滤驱动、Windows虚拟存储设备与存储设备过滤驱动、Windows文件系统过滤驱动、文件系统透明加密/解密驱动、Windows各类网络驱动(包括TDI过滤驱动及三类NDIS驱动),以及最新的WDF驱动开发模型。有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。
本书适合大专院校计算机系的学生、普通Windows程序员、Windows内核程序员、信息安全行业的程序员,以及希望了解Windows系统底层知识的计算机编程爱好者使用。阅读本书,需要读者有C语言、数据结构、操作系统和计算机网络的基础知识。
封面 -25
扉页 -24
内容简介 -23
序 -22
关于本书作者和贡献者 -20
前言 -18
阅读注意 -16
目录 -12
第1章 内核上机指导 1
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
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
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
本章的示例代码 160
练习题 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 取得文件路径的三种情况 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
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
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
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 ndisportShutdownBinding的实现 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
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 使用ndisproot接收包 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
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
精品图书免费试读 488
封底 489
1.2.1 安装Visual Studio 3
1.2.2 安装Microsoft Platform SDK 4
1.2.3 集成Microsoft Platform SDK与Visual C++速成版 5
1.2.4 Vista SDK与Visual Studio 2008 6
1.2.5 Visual Studio专业版或团队系统版 7
1.2.6 使用图形化IDE建立工程、进行编译 7
1.2.7 “解决方案”与“工程” 8
1.2.8 使用命令行工具编译 8
第2章 Windows API概要 10
2.1 Windows数据类型 10
2.1.1 Windows数据类型示例 10
2.1.2 Windows数据类型与标准C数据类型的关系 14
2.1.3 Windows数据类型与Windows API 14
2.1.4 Windows中的数据结构 15
2.2 Windows API的功能分类 15
2.2.1 系统基本服务 15
2.2.2 系统管理 17
2.2.3 用户界面 17
2.2.4 图像和多媒体 20
2.2.5 网络 20
2.2.6 系统安全 20
2.2.7 其他功能 21
2.3 Windows API核心DLL 21
2.3.1 Kernel32.dll 21
2.3.2 User32.dll 21
2.3.3 Gdi32.dll 22
2.3.4 标准C函数 22
2.3.5 其他Dll 22
2.4 Unicode和多字节 22
2.4.1 W版本和A版本的API 24
2.4.2 Unicode与ASCII的转换 24
2.5 对Windows程序设计规范的建议 25
第3章 开发工具配置与使用 26
3.1 使用Visual C/C++编译链接工具 26
3.1.1 编译器cl.exe 27
3.1.2 资源编译器rc.exe 31
3.1.3 链接器link.exe 32
3.1.4 其他工具 38
3.1.5 编译链接工具依赖的环境变量 39
3.1.6 示例:使用/D选项进行条件编译 42
3.2 使用Platform SDK 43
3.2.1 Platform SDK的目录结构与功能 43
3.2.2 为编译链接工具设置环境变量 45
3.2.3 Platform SDK工具集 46
3.2.4 Windows Vista SDK 48
3.3 编写Makefile 48
3.3.1 使用nmake.exe构建工程 48
3.3.2 Makefile实例 50
3.3.3 注释 50
3.3.4 宏 50
3.3.5 描述块:目标、依赖项和命令 53
3.3.6 makefile预处理 55
3.3.7 在Platform SDK的基础上使用nmake 56
3.4 使用WinDbg调试 57
3.4.1 安装WinDbg 57
3.4.2 编译可调试的程序 58
3.4.3 WinDbg命令 59
3.4.4 调试过程演示 59
3.5 集成开发环境 Visual Studio 62
3.5.1 工程类型选择与配置 62
3.5.2 Visual Studio快捷方式 64
3.5.3 生成项目 64
3.5.4 调试 65
3.5.5 选项与设置 65
3.6 开发环境配置总结 66
第4章 文件系统 67
4.1 概述 67
4.1.1 文件系统的基本概念 67
4.1.2 文件系统主要API 68
4.2 磁盘和驱动器管理 70
4.2.1 遍历卷并获取属性 70
4.2.2 操作驱动器挂载点 76
4.2.3 判断光驱中是否有光盘 81
4.2.4 获取磁盘分区的总容量、空闲容量、簇、扇区信息 83
4.3 文件和目录管理 86
4.3.1 删除、复制、重命名、移动文件 87
4.3.2 创建、打开、读写文件,获取文件大小 90
4.3.3 创建目录 96
4.3.4 获取程序所在的目录、程序模块路径,获取和设置当前目录 97
4.3.5 查找文件、遍历指定目录下的文件和子目录 100
4.3.6 递归遍历目录树 103
4.3.7 获取、设置文件属性和时间 105
4.4 内存映射文件 110
4.4.1 使用Mapping File提高文件读写的效率 110
4.4.2 通过Mapping File在进程间传递和共享数据 115
4.4.3 通过文件句柄获得文件路径 118
4.5 总结 121
第5章 内存管理 122
5.1 Windows内存管理原理 122
5.1.1 基本概念 122
5.1.2 分页与分段内存管理、内存映射与地址转换 123
5.1.3 进程的内存空间 125
5.1.4 虚拟内存布局、内存的分工、堆与栈 127
5.1.5 内存的保护属性和存取权限 127
5.1.6 本章API列表 127
5.2 堆管理 129
5.2.1 获取堆句柄、分配与再分配堆 129
5.2.2 获取堆中内存块的大小信息 133
5.2.3 释放内存、销毁堆 134
5.3 全局(Global)和局部(Local)内存管理 136
5.3.1 Global函数 136
5.3.2 Local函数 137
5.3.3 使用全局和局部函数分配和释放内存、改变内存块属性 137
5.4 虚拟内存管理 138
5.4.1 虚拟地址空间与内存分页 139
5.4.2 分配和释放可读可写的虚拟内存页面 139
5.4.3 修改内存页面状态和保护属性、将页面锁定在物理内存中 142
5.4.4 管理其他进程的虚拟内存 143
5.5 内存操作与内存信息管理 144
5.5.1 复制、填充、移动、清零内存块、防止缓冲区溢出 144
5.5.2 获得当前系统内存使用情况 146
5.5.3 判断内存指针的可用性 147
5.6 各种内存分配方式的关系与比较 148
5.6.1 标准C内存管理函数与Windows内存管理API的关系 149
5.6.2 功能性区别 149
5.6.3 效率的区别 149
第6章 进程、线程和模块 150
6.1 基本概念 150
6.1.1 应用程序与进程 150
6.1.2 控制台应用程序与图形用户界面应用程序 151
6.1.3 动态链接库、模块 151
6.1.4 线程、纤程与作业 152
6.1.5 权限与优先级 153
6.2 进程管理 153
6.2.1 创建进程、获取进程相关信息、获取启动参数 153
6.2.2 编写控制台程序和图形用户界面应用程序 158
6.2.3 获取和设置环境变量 158
6.3 线程、纤程 162
6.3.1 创建线程、退出线程、获取线程信息 162
6.3.2 挂起、恢复、切换、终止线程 164
6.3.3 创建远程线程、将代码注入其他进程中执行 167
6.3.4 创建纤程、删除纤程、调度纤程 170
6.3.5 纤程与线程的互相转换 171
6.4 进程状态信息 176
6.4.1 PS API与Tool help API 176
6.4.2 遍历系统中的进程 178
6.4.3 列举进程的模块、线程 182
6.4.4 进程的堆使用、内存占用、虚拟内存大小,页面错误情况 184
6.5 动态链接库 185
6.5.1 加载、释放DLL、通过句柄获取DLL相关信息 186
6.5.2 编写动态链接库、导出函数 186
6.5.3 创建动态链接库工程,配置DLL编译链接选项 188
6.5.4 运行时动态获取DLL导出函数地址并调用 189
6.5.5 声明导出函数、创建lib库,为其他模块提供导入表调用接口 190
6.5.6 通过构建导入表调用DLL导出函数 191
第7章 线程同步 192
7.1 基本原理 192
7.1.1 线程同步的过程 193
7.1.2 同步对象 193
7.1.3 等待函数 193
7.2 同步对象示例 194
7.2.1 使用事件对象(Event) 194
7.2.2 使用互斥对象(Mutex) 199
7.2.3 使用信号量控制访问共享数据的线程数量 202
7.2.4 使用可等待计时器(Timer) 206
7.3 等待进程和线程的执行完成 209
第8章 服务 210
8.1 基本概念 210
8.1.1 服务控制器(SCM) 211
8.1.2 服务程序 211
8.1.3 服务控制管理程序 211
8.1.4 系统服务管理工具 211
8.1.5 服务的属性 211
8.2 编写服务程序 212
8.2.1 入口函数 212
8.2.2 服务主函数 212
8.2.3 控制处理函数 213
8.3 实现对服务的控制和管理 216
8.3.1 创建、删除服务 216
8.3.2 启动、停止服务,向服务发送控制请求 219
8.3.3 管理服务状态、配置服务、服务的依赖关系 222
第9章 图形用户界面 229
9.1 字符界面程序 229
9.1.1 基本概念 230
9.1.2 控制台读写 231
9.1.3 控制台字体、颜色等属性,操作屏幕缓存 234
9.1.4 控制台事件 244
9.2 图形用户界面:基本概念 246
9.2.1 窗口 246
9.2.2 窗口类 246
9.2.3 消息和消息处理函数 247
9.2.4 控件 247
9.2.5 资源 248
9.2.6 对话框 248
9.3 图形用户界面:窗口 248
9.3.1 注册窗口类 249
9.3.2 创建窗口 251
9.3.3 窗口消息处理函数 253
9.3.4 窗口属性、位置和大小 256
9.3.5 窗口显示方式 257
9.3.6 线程消息队列和消息循环 258
9.4 图形用户界面:控件 258
9.4.1 Tree View控件 258
9.4.2 为Tree View控件增加节点 260
9.4.3 Tree View右键菜单 262
9.4.4 List View控件 263
9.4.5 为List View控件增加分栏 265
9.4.6 为List View控件增加项 266
9.4.7 文本框控件 267
9.4.8 为文本框控件设置文字 268
9.5 界面资源 269
9.5.1 资源脚本(.rc) 269
9.5.2 资源ID定义和头文件 272
9.5.3 在程序中使用资源 273
9.6 菜单 273
9.6.1 菜单资源和菜单句柄 273
9.6.2 动态增加、删除、设置菜单及菜单项 274
9.6.3 菜单消息处理 274
9.7 对话框 275
9.7.1 创建对话框 275
9.7.2 对话框消息处理函数 276
第10章 系统信息的管理 277
10.1 Windows系统信息 277
10.1.1 获取系统版本 277
10.1.2 获取计算机硬件信息 279
10.1.3 获取系统目录等信息 281
10.1.4 用户名、计算机名、域名 282
10.1.5 处理系统颜色信息、尺度信息等 284
10.1.6 鼠标、键盘等外设信息 285
10.2 时间信息 286
10.2.1 设置、获取系统时间 286
10.2.2 获取开机至现在持续的时间 287
10.2.3 文件时间与系统时间的转换 287
10.3 注册表 288
10.3.1 注册表的作用及组织形式 288
10.3.2 键、子键、键属性及键值的相关操作 289
10.3.3 列举注册表项及键值 292
10.3.4 通过注册表设置一个自启动的程序 293
10.3.5 设置随程序启动而启动的调试器(任何程序) 294
10.3.6 指定程序崩溃实时调试器 294
第11章 进程间通信 295
11.1 邮槽(MailSlot) 295
11.1.1 创建邮槽、从邮槽中读取消息 296
11.1.2 通过邮槽发送消息 299
11.2 管道(Pipe) 300
11.2.1 创建命名管道 300
11.2.2 管道监听 302
11.2.3 使用异步I/O进行读写 303
11.2.4 关闭管道实例 307
11.2.5 客户端 307
11.3 剪贴板 310
11.3.1 获取、设置剪贴板数据 310
11.3.2 监视剪贴板 317
11.3.3 剪贴板数据格式 325
11.4 数据复制消息(WM_COPYDATA) 327
11.4.1 数据发送端 327
11.4.2 数据接收端 330
11.5 其他进程间通信方式 332
11.5.1 动态数据交换(DDE)和网络动态数据交换(NDDE) 332
11.5.2 通过File Mapping在进程间共享数据 333
11.5.3 Windows Socket 333
第12章 Windows Shell程序设计 334
12.1 Windows Shell目录管理 335
12.1.1 Shell对目录和文件的管理形式 335
12.1.2 “我的文档”等特殊目录相关操作 335
12.1.3 绑定、遍历、属性获取 337
12.1.4 浏览文件对话框 339
12.2 文件协助(File Associations) 340
12.2.1 文件类型相关注册表键值 340
12.2.2 为文件指定默认打开程序 341
12.2.3 定制文件类型的图标 342
12.3 Shell扩展 343
12.3.1 对象及概念 343
12.3.2 CLSID,处理例程的GUID 344
12.3.3 注册Shell扩展 345
12.3.4 COM程序开发基础 346
12.3.5 编写Handler程序 346
12.3.6 Shell扩展程序的调试 362
12.3.7 总结 363
12.4 任务栏通知区域(Tray)图标 363
12.4.1 创建图标窗口 364
12.4.2 创建图标和图标菜单 367
12.4.3 最小化主窗口到通知区域 370
12.4.4 弹出气泡通知 372
12.4.5 动态图标 374
12.4.6 其他功能 376
第13章 Windows GDI 379
13.1 GDI编程接口概述 379
13.1.1 Windows GDI的功能 379
13.1.2 链接库与头文件 380
13.2 设备上下文(DC)、输出操作与图形对象 380
13.2.1 设备上下文类型与关联设备 380
13.2.2 图形对象的作用及与DC的关系 380
13.2.3 各类图形对象的具体属性与作用 383
13.2.4 绘制、填充、写入等图形输出操作 384
13.2.5 修剪与坐标变换 385
13.2.6 设备上下文的图形模式 385
13.3 一个最简单的GDI程序 386
13.3.1 示例 386
13.3.2 DC的操作 387
13.3.3 颜色的表示 388
13.3.4 图形对象:画刷和画笔 389
13.3.5 输出操作:绘制图形和线条 390
13.4 文字和字体 391
13.4.1 选择、设置字体 393
13.4.2 选择字体图形对象 394
13.4.3 文字的颜色 394
13.4.4 输出文字 395
13.4.5 DC图形模式设置 395
13.4.6 遍历字体 396
13.4.7 为系统安装、删除字体文件 398
13.5 绘制线条 398
13.5.1 选择画笔对象 399
13.5.2 直线 399
13.5.3 绘制任意曲线 399
13.5.4 跟踪鼠标轨迹 399
13.5.5 弧线 405
13.6 绘制图形 405
13.6.1 填充颜色与边缘勾勒 406
13.6.2 绘制矩形、椭圆、圆角矩形 406
13.6.3 椭圆弓形和椭圆扇形 411
13.6.4 多边形 411
13.6.5 RECT结构及对RECT的操作 412
13.7 位图操作 414
13.7.1 截取屏幕、保存位图文件 414
13.7.2 将位图显示在界面上 419
13.8 区域(Regions)、路径(Paths)与修剪(Clip)操作 422
13.8.1 区域的创建及形状、位置等属性 422
13.8.2 区域边沿、区域填充、反转与勾勒操作 423
13.8.3 组合、比较、移动等操作 426
13.8.4 点击测试(Hit Testing) 427
13.8.5 路径的创建与操作 431
13.8.6 路径转换为区域 432
13.8.7 使用区域和路径进行修剪操作,限制输出 432
13.9 坐标变换 438
13.9.1 缩放 439
13.9.2 旋转 440
13.10 调色板 440
第14章 网络通信与配置 443
14.1 Socket通信 444
14.1.1 客户端 444
14.1.2 服务端 449
14.1.3 处理并发的客户端连接 455
14.1.4 网络通信的异步I/O模式 456
14.2 IP Helper 456
第15章 程序安装与设置 463
15.1 创建cab文件 463
15.1.1 makecab.exe 463
15.1.2 压缩多个文件 464
15.1.3 Cabinet软件开发工具包(CABSDK) 466
15.2 编写INF文件 466
15.2.1 INF文件格式 466
15.2.2 Install节 468
15.2.3 CopyFiles和AddReg等安装过程 468
15.2.4 源路径和目的路径 469
15.2.5 字符串表 469
15.3 安装程序setup.exe的编号 469
15.4 使用msi文件进行安装 472
15.4.1 Windows Installer Service 472
15.4.2 msi文件的创建与修改工具orca.exe 474
15.4.3 准备工作 475
15.4.4 编辑表组 475
第16章 设备驱动管理与内核通信 476
16.1 设备管理 476
16.1.1 列举设备接口 477
16.1.2 监控设备的加载和卸载 483
16.2 I/O控制、内核通信 488
16.2.1 加载驱动程序 488
16.2.2 控制驱动程序、与驱动程序进行通信 495
16.3 编写设备驱动程序 498
16.3.1 驱动程序开发包:DDK 499
16.3.2 开发驱动程序 499
16.4 I/O模式,同步与异步 504
第17章 用户、认证和对象安全 506
17.1 基本概念 506
17.1.1 访问令牌、权限和用户标识 506
17.1.2 进程的系统操作权限 507
17.1.3 安全对象 508
17.1.4 访问控制列表(ACL) 508
17.2 安全机制程序示例 509
17.2.1 列举进程访问令牌内容和权限 509
17.2.2 修改进程的权限 514
17.2.3 列举安全对象的安全描述符 515
17.2.4 修改安全描述符 521
17.3 用户 522
17.3.1 创建用户 522
17.3.2 用户组 523
17.3.3 删除用户 525
17.3.4 列举用户和用户组、获取用户信息 525
第18章 Windows API的内部原理 532
18.1 关于API的补充说明 532
18.1.1 Windows API的版本演进和Vista新增API 532
18.1.2 64位操作系统的接口 533
18.2 Windows系统中的对象封装 533
18.2.1 什么是对象 534
18.2.2 面向对象的思想 534
18.2.3 Windows系统中的对象:内核对象、GDI对象等 534
18.3 Windows程序设计参考:文档资源与样例代码 534
18.3.1 SDK文档和MSDN 534
18.3.2 SDK示例代码 535
18.4 x86平台程序函数调用原理 535
18.4.1 函数调用的真实过程 535
18.4.2 函数调用约定 539
18.4.3 为什么通过参数返回数据时只能使用指针 540
18.4.4 缓冲区溢出 540
18.4.5 程序运行错误的调试技巧 540
18.5 可执行程序结构与API函数接口内部机理 541
18.5.1 Windows可执行程序结构 541
18.5.2 导入表、导出表、动态链接 543
18.5.3 NTDLL.DLL、NATIVE API和SSDT 544
18.5.4 API HOOK 546
18.6 发布程序 546
18.6.1 合理选择编译链接选项 546
18.6.2 构建到指定路径 546
18.7 模块化,向Windows API学习接口定义 547
18.7.1 lib文件 547
18.7.2 头文件 547
18.7.3 为第三方应用软件提供SDK 547
本书从Windows内核编程出发,全面系统地介绍了串口、键盘、磁盘、文件系统、网络等相关的Windows内核模块的编程技术,以及基于这些技术实现的密码保护、防毒引擎、文件加密、网络嗅探、网络防火墙等信息安全软件的核心组件的具体编程。主要知识重点包括:Windows串口与键盘过滤驱动、Windows虚拟存储设备与存储设备过滤驱动、Windows文件系统过滤驱动、文件系统透明加密/解密驱动、Windows各类网络驱动(包括TDI过滤驱动及三类NDIS驱动),以及最新的WDF驱动开发模型。有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。
本书适合大专院校计算机系的学生、普通Windows程序员、Windows内核程序员、信息安全行业的程序员,以及希望了解Windows系统底层知识的计算机编程爱好者使用。阅读本书,需要读者有C语言、数据结构、操作系统和计算机网络的基础知识。
封面 -25
扉页 -24
内容简介 -23
序 -22
关于本书作者和贡献者 -20
前言 -18
阅读注意 -16
目录 -12
第1章 内核上机指导 1
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
首先要给大家介绍的是进程内核对象。进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象是与进程相关联的一个数据结构。操作系统内核通过它管理进程,也是操作系统原理上介绍的进程控制块(PCB)。举个例子,它相当于每个学生都有的学籍,学校管理我们都是通过学籍,什么记过了,处分了,开除学籍了,都是在学籍上做文章。
进程一般被定义为一个正在运行的程序的一个实例,它由两部分组成:
1:内核对象,操作系统用它来管理进程。内核对象也是系统保存进程统计信息的地方。
2:一个地址空间,其中包含所有可执行文件或DLL模块的代码和数据。
Windows支持两种类型的应用程序:GU
3.2.4 object.tostring方法 79
3.2.5 object.memberwiseclone方法 79
3.2.6 object.referenceequals方法 80
3.3 employee类 81
3.4 实现继承 82
3.5 重写继承的行为 83
3.5.1 virtual和override关键字 84
3.5.2 重载与重写 84
3.5.3 重写事件 85
3.5.4 扩展方法 86
3.6 new修饰符 87
3.7 抽象类 90
3.8 密封类 92
3.9 构造函数和析构函数 92
3.10 接口 95
3.10.1 实现接口 97
3.10.2 显式接口成员实现 98
3.10.3 接口的再实现 101
3.11 多态性 103
3.11.1 接口多态性 106
3.11.2 new修饰符和多态性 107
3.12 强制类型转换 108
3.13 属性继承 112
3.14 visual studio 2008预览 113
第ii部分 核心技术
第4章 visual studio 2008简介 117
4.1 迁移到visual studio 2008 117
4.2 集成开发环境 119
4.2.1 起始页 119
4.2.2 创建项目 120
4.2.3 多目标 120
4.2.4 解决方案资源管理器 121
4.2.5 项目类型 123
4.2.6 添加引用 123
4.2.7 visual studio中的窗口管理 124
4.2.8 自动恢复 125
4.3 类层次结构 125
4.3.1 “类视图”窗口 126
4.3.2 对象浏览器 127
4.3.3 类关系图 127
4.3.4 “错误列表”窗口 136
4.4 代码编辑器 137
4.4.1 intellisense 137
4.4.2 外侧代码 138
4.4.3 字体和颜色格式化 138
4.4.4 源代码格式设置 139
4.4.5 修改跟踪 139
4.5 代码段 140
4.5.1 插入代码段 140
4.5.2 默认的代码段 142
4.5.3 代码段管理器 143
4.5.4 创建代码段 144
4.5.5 复制和粘贴 149
4.6 重构 149
4.7 生成和部署 153
4.7.1 msbuild 154
4.7.2 clickonce部署 158
4.8 数组和集合预览 163
第5章 数组和集合 165
5.1 数组 167
5.1.1 数组元素 168
5.1.2 多维数组 169
5.1.3 交错数组 171
5.1.4 system.array 172
5.1.5 system.array属性 179
5.1.6 params关键字 185
5.1.7 数组转换 187
5.2 集合 188
5.2.1 arraylist集合 189
5.2.2 bitarray集合 192
5.2.3 hashtable集合 194
5.2.4 queue集合 198
5.2.5 sortedlist 199
5.2.6 stack集合 202
5.2.7 专用集合 203
5.3 linq预览 204
第6章 linq简介 205
6.1 c#扩展 206
6.1.1 类型推断 206
6.1.2 对象初始值设定项 207
6.1.3 匿名类型 207
6.1.4 扩展方法 208
6.1.5 lambda表达式 208
6.1.6 表达式目录树 209
6.2 linq基础 210
6.2.1 核心要素 210
6.2.2 转换运算符 213
6.2.3 linq查询表达式语法 214
6.2.4 linq在哪里 215
6.3 linq to objects 216
6.4 linq运算符 219
6.4.1 聚合运算符 219
6.4.2 连接运算符 220
6.4.3 数据类型转换运算符 220
6.4.4 元素运算符 222
6.4.5 等于运算符 223
6.4.6 筛选运算符 223
6.4.7 生成运算符 223
6.4.8 分组运算符 224
6.4.9 联接运算符 224
6.4.10 分区运算符 225
6.4.11 量词运算符 226
6.4.12 集合运算符 226
6.4.13 排序运算符 227
6.5 泛型预览 228
第7章 泛型 229
7.1 泛型类型 231
7.1.1 类型形参 232
7.1.2 类型实参 232
7.1.3 构造类型 235
7.1.4 重载方法 236
7.2 泛型方法 237
泛型类型的this引用 238
7.3 约束 238
7.3.1 派生约束 239
7.3.2 接口约束 243
7.3.3 值类型约束 244
7.3.4 引用类型约束 245
7.3.5 默认的构造函数约束 246
7.4 强制类型转换 246
7.5 继承 247
7.5.1 重写泛型方法 248
7.5.2 嵌套类型 249
7.6 静态成员 250
7.6.1 运算符函数 251
7.6.2 序列化 252
7.6.3 泛型本质 254
7.6.4 泛型集合 255
7.7 枚举器预览 256
第8章 枚举器 257
8.1 可枚举的对象 258
8.1.1 枚举器 258
8.1.2 枚举器实例 260
8.1.3 枚举器实例(版本化集合) 261
8.1.4 ienumerator问题 263
8.2 泛型枚举器 263
8.2.1 ienumerable[t]接口 264
8.2.2 ienumerator[t]接口 264
8.2.3 泛型枚举器实例(版本化集合) 265
8.3 迭代器 267
8.4 运算符重载预览 274
第iii部分 c#语言详解
第9章 运算符重载 277
9.1 数学运算符和逻辑运算符 278
9.1.1 实现 279
9.1.2 自增和自减运算符 281
9.1.3 左移和右移运算符.. 282
9.1.4 true和false运算符 283
9.1.5 成对运算符 284
9.2 转换运算符 288
9.3 实例 291
9.4 运算符重载的本质 294
9.5 委托和事件预览 296
第10章 委托和事件 297
10.1 委托 297
10.1.1 定义委托 298
10.1.2 创建委托 299
10.1.3 逆变和协变 300
10.1.4 激活委托 300
10.1.5 委托数组 301
10.1.6 system.multicastdelegate类 302
10.1.7 调用列表 303
10.1.8 泛型和委托 306
10.1.9 异步调用 307
10.1.10 异步委托图 310
10.1.11 异常 311
10.2 匿名方法 312
10.2.1 外部变量 314
10.2.2 泛型匿名方法 316
10.2.3 匿名方法的局限性 316
10.3 事件 317
10.3.1 发布事件 317
10.3.2 订阅者 318
10.3.3 引发事件 318
10.4 linq编程预览 320
第11章 linq编程 321
11.1 linq to xml 321
11.1.1 xml架构 322
11.1.2 验证 322
11.1.3 导航 323
11.1.4 显式的强制类型转换 327
11.1.5 xml修改 328
11.1.6 xml查询表达式 330
11.2 linq to sql 331
11.2.1 实体类 331
11.2.2 linq to sql查询表达式 333
11.2.3 linq to dataset 334
11.2.4 关联 335
11.2.5 linq to sql更新 337
11.3 异常处理预览 339
第12章 异常处理 340
12.1 异常示例 340
12.2 标准异常模型 341
12.3 结构化异常处理 342
12.3.1 try语句 342
12.3.2 catch语句 343
12.3.3 异常的传播 344
12.3.4 finally语句 346
12.3.5 异常信息表 346
12.3.6 嵌套的try块 347
12.4 system.exception 348
12.4.1 system.exception函数 349
12.4.2 system.exception属性 350
12.4.3 应用程序异常 351
12.4.4 异常转换 353
12.4.5 com互操作性异常 353
12.5 远程异常 357
12.6 未处理的异常 358
12.6.1 application.threadexception 360
12.6.2 appdomain.unhandledexception 360
12.7 在visual studio中管理异常 361
12.7.1 异常助手 362
12.7.2 “异常”对话框 362
12.8 元数据和反射预览 363
第iv部分 调试
第13章 元数据和反射 367
13.1 元数据 367
13.1.1 元数据标记 369
13.1.2 元数据堆 369
13.1.3 流 370
13.1.4 元数据验证 370
13.1.5 ildasm 371
13.2 反射 375
13.2.1 获得type对象 376
13.2.2 加载程序集 378
13.2.3 浏览类型信息 380
13.2.4 动态调用 383
13.2.5 类型的创建 387
13.2.6 晚期绑定委托 389
13.2.7 函数调用性能 391
13.3 反射和泛型 391
13.3.1 isgeneric和isgenerictypedefinition 392
13.3.2 typeof 393
13.3.3 gettype 393
13.3.4 getgenerictypedefinition 394
13.3.5 getgenericarguments 394
13.3.6 创建泛型类型 395
13.3.7 反射的安全性 396
13.3.8 属性 397
13.3.9 程序员定义的自定义属性 399
13.3.10 属性和反射 403
13.4 msil预览 405
第14章 msil编程 406
14.1 “hello world”应用程序 408
14.2 计算堆栈 409
14.3 msil详解 410
14.4 复杂任务 419
14.5 分支 424
14.6 数组 428
14.7 算术指令 430
14.8 转换运算 430
14.9 异常处理 431
14.10 其他操作 432
14.11 进程执行 432
14.12 用visual studio 2008进行调试预览 436
第15章 用visual studio 2008进行调试 437
15.1 调试概述 438
15.1.1 调试windows窗体项目 438
15.1.2 附加到运行进程 438
15.1.3 调试控制台应用程序项目 440
15.1.4 调试类库项目 440
15.2 调试配置 441
15.2.1 debug和release配置 441
15.2.2 配置管理器 441
15.3 调试设置 442
15.3.1 visual studio环境调试设置 442
15.3.2 解决方案的调试设置 447
15.3.3 项目的调试设置 448
15.4 断点 449
15.4.1 函数断点 449
15.4.2 “断点”窗口 450
15.4.3 跟踪点 454
15.5 代码逐步调试 456
15.5.1 逐步调试命令 456
15.5.2 “设置下一条语句”实例 456
15.6 “调试”工具栏 457
15.7 数据提示 458
15.8 调试窗口 460
15.8.1 “断点”窗口 460
15.8.2 “输出”窗口 460
15.8.3 “监视”窗口和其他变量窗口 461
15.8.4 自动窗口 463
15.8.5 “局部变量”窗口 463
15.8.6 “即时”窗口 463
15.8.7 “调用堆栈”窗口 466
15.8.8 “线程”窗口 467
15.8.9 “模块”窗口 468
15.8.10 “进程”窗口 468
15.8.11 “内存”窗口 469
15.8.12 “反汇编”窗口 469
15.8.13 “寄存器”窗口 470
15.9 跟踪 471
15.9.1 跟踪实例 478
15.9.2 配置文件 481
15.9.3 使用配置文件进行跟踪的示例 482
15.10 debuggerdisplayattribute 484
15.11 debuggerbrowsableattribute 486
15.12 debuggertypeproxyattribute 488
15.13 转储文件 488
15.14 高级调试预览 490
第16章 高级调试 491
16.1 debuggableattribute属性 492
16.2 调试器 493
16.3 托管调试器(mdbg) 493
16.3.1 mdbg实例 494
16.3.2 mdbg命令 497
16.4 windbg 499
16.5 son of strike(sos) 505
16.5.1 sos实例——第1部分 506
16.5.2 sos实例——第2部分 508
16.6 转储文件 510
16.7 内存管理 512
16.7.1 对象图 513
16.7.2 代 515
16.7.3 终结进程 519
16.7.4 可靠性和性能监视器 519
16.8 线程 520
16.9 异常 526
16.10 符号 527
16.10.1 symsrv符号服务器 528
16.10.2 应用程序符号 529
16.11 内存管理预览 529
第v部分 高级特性
第17章 内存管理 533
17.1 非托管资源 534
17.1.1 垃圾回收概述 535
17.1.2 gc风格 538
17.2 终结器 539
17.3 idisposable.dispose 551
17.3.1 disposable模式 554
17.3.2 disposable模式的考虑因素 555
17.4 弱引用 560
17.4.1 弱引用内部机理 562
17.4.2 weakreference类 563
17.4.3 可靠的代码 563
17.4.4 管理非托管资源 566
17.5 gc类 569
17.6 不安全的代码预览 569
第18章 不安全的代码 570
18.1 unsafe关键字 572
18.1.1 指针 573
18.1.2 指针参数和指针返回值 575
18.1.3 p/invoke 578
18.2 小结 590
索引... 591
PEB(Process Environment Block,进程环境块)是存放进程信息的结构体,尺寸非常大,其大部分内容都已被文档化
PEB访问方法
TEB.ProcessEnvironmentBlock成员就是PEB 结构体的地址。TEB结构体位于FS段选择符所指的段内存的起始地址处,且ProcessEnvironmentBlock成员位于距TEB结构体Offest 30的位置。
即如下式子成立:
FS:[30]=TEB.ProcessEnvironmentBlock=address of PEB
设置和获取所在进程的环境变量,使用API函数
GetEnvironmentStrings,GetEnvironmentVariable和SetEnvironmentVariable等.
1.GetEnvironmentStrings
GetEnviro
本书从Windows内核编程出发,全面系统地介绍了串口、键盘、磁盘、文件系统、网络等相关的Windows内核模块的编程技术,以及基于这些技术实现的密码保护、防毒引擎、文件加密、网络嗅探、网络防火墙等信息安全软件的核心组件的具体编程。主要知识重点包括:Windows串口与键盘过滤驱动、Windows虚拟存储设备与存储设备过滤驱动、Windows文件系统过滤驱动、文件系统透明加密/解密驱动、Windows各类网络驱动(包括TDI过滤驱动及三类NDIS驱动),以及最新的WDF驱动开发模型。有助于读者熟悉Windows内核驱动的体系结构,并精通信息安全类的内核编程技术。本书的大部分代码具有广泛的兼容性,适合从Windows 2000 一直到目前最新的Windows 7 Beta 版。
本书适合大专院校计算机系的学生、普通Windows程序员、Windows内核程序员、信息安全行业的程序员,以及希望了解Windows系统底层知识的计算机编程爱好者使用。阅读本书,需要读者有C语言、数据结构、操作系统和计算机网络的基础知识。
封面 -25
扉页 -24
内容简介 -23
序 -22
关于本书作者和贡献者 -20
前言 -18
阅读注意 -16
目录 -12
第1章 内核上机指导 1
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 定义常数和数据结构
CUI程序专用
win32控制台程序中可在main函数参数列表中加入TCHAR*env[] 参数,进入main函数时,env参数被赋值,含义为当前进程环境变量,数据类型为字符串指针数组,每个指针都指向一个不同的环境变量(其定义采用常规的“名称=值”的形式)。在此数组中,指向最后一个环境变量字符串的指针后面,会有一个NULL指针,表明这是数组的末尾。
GetEnvironmentStrings
AP...
《Windows核心编程第五版》是一本深入讲解Windows操作系统内部机制的经典图书,其中包含了大量的源代码示例。这些源代码示例覆盖了Windows系统的各个方面,包括进程管理、内存管理、线程调度、文件系统、网络通信等。
这本书的源码具有非常高的参考价值,不仅可以用来学习Windows系统的内部原理,还可以作为开发人员快速开发Windows应用程序的工具。
在学习Windows核心编程的过程中,读者需要具备较强的C++语言基础和操作系统原理基础。通过对源代码进行阅读和理解,读者能够更加深入地了解Windows系统的内部机制和运作原理,对于解决实际开发中遇到的问题也具有非常重要的指导意义。
总的来说,Windows核心编程第五版源码是一份非常宝贵的学习资料,可以提高开发人员的技能水平和开发效率,值得广大读者认真学习和使用。
Your python3 install is corrupted. Please fix the '/usr/bin/python3' symlink.
chenxiangneu:
babyos2(1)——boot
Alix_sz:
Your python3 install is corrupted. Please fix the '/usr/bin/python3' symlink.
Man in Himself:
Your python3 install is corrupted. Please fix the '/usr/bin/python3' symlink.
写代码那些事儿:
Python+pyGame 拼图游戏
m0_62471092: