资讯
安全
论坛
下载
读书
程序开发
数据库
系统
网络
电子书
微信学院
站长学院
QQ
手机软件
考试
安全
|
web开发
|
软件开发
|
移动开发
|
数据库
|
网络
|
系统
|
网站
|
考试认证
|
其他
|
读书频道
>
网站
>
网页设计
>
网络分析技术揭秘:原理、实践与WinPcap深入解析
3.1.8 内核的注册表操作
12-08-11
叶孤城
收藏
我要投稿
本文所属图书 >
网络分析技术揭秘:原理、实践与WinPcap深入解析
本书结合著名的开源软件库WinPcap来说明网络分析技术的实现原理及使用方法。其中包括WinPcap内核驱动,编译与使用,数据包的捕获、发送、内核过滤与接收,以及网络流量的统计与网络状态的分析等重要内容,而且作...
立即去当当网订购
在驱动程序的开发中,经常会对注册表进行操作。注册表的主要组成如图3-1所示,注册表的五个主要组成部分如下。
图3-1注册表的主要组成
注册表项:注册表中的一个项目,类似于目录。每个项中存储着多个二元结构,即键名-键值。每个项中,可以有若干个子项。
注册表子项:类似于目录中的子目录。
键名:类似于目录下的文件名,可用于索引,通过键名可以寻找到相应的键值。
键值类别:每个键值存储的时候会有不同类别,即键值类别,比如整型、字符串等类型。
键值:键名下对应存储的数据值。
WDK提供了一套对注册表进行操作的函数集,下面对这些函数进行简要介绍。
1. 初始化一个OBJECT_ATTRIBUTES结构体
为了能对注册表进行操作,必须先调用InitializeObjectAttributes函数初始化一个OBJECT_ATTRIBUTES结构体,其原型如下:
VOID InitializeObjectAttributes(
OUT POBJECT_ATTRIBUTES InitializedAttributes,
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN HANDLE RootDirectory,
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
上述函数中,参数InitializedAttributes指向需要初始化的OBJECT_ATTRIBUTES结构体;参数ObjectName 描述需要打开的注册表对象的名称,用Unicode字符串表示;参数Attributes为标识,若将其设置为OBJ_CASE_INSENSITIVE,则在用ObjectName与已存在的对象进行比较时就不区分大小写了;参数RootDirectory用于描述ObjectName参数的根目录,如果ObjectName是一个完全的名称,则设为NULL;参数SecurityDescriptor为一个安全描述,如果把它设为NULL,驱动程序将采用默认的安全设置。
2. 打开注册表
WDK提供了内核函数ZwOpenKey,用来打开一个已存在的注册表项。如果ZwOpenKey指定的项不存在,则其不会创建这个项,而是返回一个错误状态。该函数的原型如下:
NTSTATUS ZwOpenKey(OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
上述函数中,参数KeyHandle返回被打开的句柄;参数DesiredAccess为打开的权限,一般设为KEY_ALL_ACCESS;参数ObjectAttributes是OBJECT_ATTRIBUTES数据结构,用于指示打开的状态。
如果打开成功,函数ZwOpenKey返回STATUS_SUCCESS,否则返回一个错误代码,错误代码可能为STATUS_INVALID_HANDLE或STATUS_ACCESS_DENIED。
3. 关闭注册表
已打开的注册表,如果不再使用,需要采用ZwClose函数关闭它,其原型如下:
NTSTATUS ZwClose( IN HANDLE Handle );
上述函数中,参数Handle为所要关闭的注册表句柄。
4. 查询注册表
驱动程序中有时需要对注册表的项进行查询,从而获取注册表的键值。WDK提供的ZwQueryValueKey函数可以完成这个任务,其原型如下:
NTSTATUS ZwQueryValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
上述函数中,参数KeyHandle为打开的注册表句柄;参数ValueName为要查询的键名;参数KeyValueInformationClass决定不同的查询类别;参数KeyValueInformation用于选择一种查询类别,可选择KeyValueBasicInformation、KeyValueFullInformation或KeyValuePartialInformation类型;参数Length为要查询数据的长度;参数ResultLength为实际查询返回的数据长度。
如果打开成功,函数返回STATUS_SUCCESS,否则返回一个错误代码。
使用ZwQueryValueKey函数查询注册表单时,需要用KeyValueInformationClass参数来选择一种查询方式,可以是KeyValueBasicInformation、KeyValueFullInformation或者KeyValuePartialInformation中的一种。它们分别代表查询基本信息、查询全部信息和查询部分信息,并且每种查询类型会用一种对应的数据结构来获得查询结果。
一般情况下,选择KeyValuePartialInformation参数就可以查询键值的数据了,它对应的查询数据结构是KEY_VALUE_PARTIAL_INFORMATION,具体定义如下:
Typedef struct _KEY_VALUE_PARTIAL_INFORMATION{
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1]; //
}KEY_VALUE_PARTIAL_INFORMATION,
*PKEY_VALUE_PARTIAL_INFORMATION;
注意KEY_VALUE_PARTIAL_INFORMATION数据结构的长度并未固定,所以首先要确定这个长度。
使用ZwQueryValueKey函数时,一般会按下列四个步骤进行操作:
用ZwQueryValueKey函数获取这个数据结构的长度。
分配如此长度的内存,用来查询。
再次调用ZwQueryValueKey函数,获取键值。
回收内存。
如果选择KeyValueFullInformation参数,它对应的是KEY_VALUE_FULL_INFORMATION查询数据结构体,具体定义如下:
Typedef struct _KEY_VALUE_FULL_INFORMATION{
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
WCHAR Name[1]; //
}KEY_VALUE_FULL_INFORMATION,*PKEY_VALUE_FULL_INFORMATION;
5. 枚举子项
在注册表中,经常使用另外两种操作,分别是枚举子项和枚举子键。枚举子项就是事先不知道该项中有多少个子项目,用某个函数将子项一一列举出来。而枚举子键是指事先不知道该项中有多少个子键,用某个函数将子键一一列举出来。
WDK提供了列举子项的ZwQueryKey函数和ZwEnumerateKey函数。ZwQueryKey函数的作用主要是获得某注册表项究竟有多少个子项,而ZwEnumerateKey函数的作用主要是针对某个子项获取其具体信息。接下来看一看这两个函数的原型。
ZwQueryKey函数的原型如下:
NTSTATUS ZwQueryKey(
IN HANDLE KeyHandle,
IN KEY_INFORMATION_CLASS KeyInformationClass,
OUT PVOID KeyInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
上述函数中,参数KeyHandle为注册表项的句柄;参数KeyInformationClass为查询的类别,一般选择KeyFullInformation;参数KeyInformation为查询的数据指针,如果KeyInformationClass是KeyFullInformation,则该指针指向一个KEY_FULL_INFORMATION的数据结构;参数Length为数据长度;参数ResultLength为实际返回数据的长度。
如果函数执行成功,返回STATUS_SUCCESS,否则返回一个错误代码。
ZwEnumerateKey函数的原型如下:
NTSTATUS ZwEnumerateKey(
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_INFORMATION_CLASS KeyInformationClass,
OUT PVOID KeyInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
上述函数中,参数KeyHandle为注册表项句柄;参数Index为从0开始的索引;参数KeyInformationClass为子项的信息类型;参数Length为子项信息的长度;参数ResultLength为返回子键信息的长度。
如果函数执行成功,返回STATUS_SUCCESS,否则返回一个错误代码。
在使用ZwQueryKey函数时,可以将参数KeyInformationClass指定为KeyFullInformation。这样,参数KeyInformation就可对应一个KEY_FULL_INFORMATION的数据结构了,该数据结构中的SubKeys指明了该项中有多少个子项。KEY_FULL_INFORMATION数据结构的长度可变,所以要调用两次ZwQueryKey,第一次获取KEY_FULL_INFORMATION结构的长度,第二次才是真正获取KEY_FULL_INFORMATION结构的数据。
在使用ZwEnumerateKey函数时,需要将参数KeyInformationClass设置为KeyBasicInformation,这样,参数KeyInformation就能对应KEY_BASIC_INFORMATION的数据结构了。KEY_BASIC_INFORMATION数据结构长度也是可变的,故同样需要调用ZwEnumerateKey两次,第一次获取KEY_BASIC_INFORMATION结构的长度,第二次获取KEY_BASIC_INFORMATION结构的数据。
6. 枚举子键
和枚举子项类似,通过ZwQueryKey和ZwEnumerateValueKey这两个函数的配合可以完成对子键的枚举。ZwEnumerateValueKey函数的使用方法和ZwEnumerateKey函数类似,其原型如下:
NTSTATUS ZwEnumerateValueKey(
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
7. WinPcap中的注册表操作实例
下面是在WinPcap中对注册表进行操作的代码片断:
PWCHAR getAdaptersList(void)
{
?
/*
*设置一个OBJECT_ATTRIBUTES类型的参数objAttrs,为了便于后续调用,
*其中NDIS_STRING AdapterListKey =
* NDIS_STRING_CONST("\\Registry\\Machine\\System\\
* CurrentControlSet\\Control\\Class\\
* {4D36E972-E325-11CE-BFC1-08002BE10318}");
*/
InitializeObjectAttributes(&objAttrs, &AdapterListKey,
OBJ_CASE_INSENSITIVE, NULL, NULL);
/*打开注册表表项,返回objAttrs中所描述的注册表表项的句柄*/
status = ZwOpenKey(&keyHandle, KEY_READ, &objAttrs);
if (!NT_SUCCESS(status)) {
//打开失败
}
else { //打开成功
ULONG resultLength;
KEY_VALUE_PARTIAL_INFORMATION valueInfo;
CHAR AdapInfo[1024];
UINT i=0;
/*遍历设备链表,获取一个已打开注册表项的子项信息*/
while((status=ZwEnumerateKey(keyHandle,i,
KeyBasicInformation,AdapInfo,sizeof(AdapInfo),
&resultLength))==STATUS_SUCCESS)
{
?
/*OBJECT_ATTRIBUTES类型的参数objAttrs,为了便于后续调用*/
InitializeObjectAttributes(&objAttrs,
&AdapterKeyName,OBJ_CASE_INSENSITIVE,NULL, NULL);
/*objAttrs*/
status=ZwOpenKey(&ExportKeyHandle,KEY_READ,&objAttrs);
/*揈xport?/
status = ZwQueryValueKey(ExportKeyHandle,
&FinalExportKey,KeyValuePartialInformation,
&valueInfo,sizeof(valueInfo),&resultLength);
if (!NT_SUCCESS(status) && (status != STATUS_BUFFER_OVERFLOW))
{
//查询失败
}
else { //查询成功
/*计算所需的内存大小*/
…
/*分配内存,用于查询*/
…
if (valueInfoP != NULL)
{//分配内存成功
status = ZwQueryValueKey(ExportKeyHandle,
&FinalExportKey,
KeyValuePartialInformation,
valueInfoP,
valueInfoLength, &resultLength);
if (!NT_SUCCESS(status)) {
//查询失败
}
else{//查询成功
…
}
ExFreePool(valueInfoP);
}
else {
//用于查询的内存分配失败
}
}//一次查找“Export”键名的键值信息结束
…
//关闭注册表子项
ZwClose (ExportKeyHandle);
i++;
}//结束while语句
/*关闭注册表项*/
ZwClose (keyHandle);
}
?
}
点击复制链接 与好友分享!
回本站首页
分享到:
更多
您对本文章有什么意见或着疑问吗?请到
论坛讨论
您的关注和建议是我们前行的参考和动力
上一篇:
1.3 功能
下一篇:
1.5 小结
相关文章
图文推荐
JavaScript网页动画设
1.9 响应式
1.8 登陆页式
1.7 主题式
排行
热门
112 |
1.6 本书概要
112 |
1.5.5 软件
112 |
1.5.4 可扩展性
112 |
1.5.3 融合
112 |
1.5.2 虚拟化
112 |
1.5.1 以太网的使用
112 |
1.5 云网络的特征
112 |
1.4 什么是云网络
3.2.3 Bootstrap栅格系统
3.4.4 自适应显示/隐藏页面内容
3.3.1 固定式布局
2.1.1 下载Bootstrap
3.3.2 流式布局
3.4.6 响应式Bootstrap
3.4.2 设计响应式图片
3.2.4 响应式Bootstrap栅格系统
文章
下载
读书
·
Win2000下关闭无用端口
·
禁止非法用户登录综合设置 [win9x篇]
·
关上可恶的后门——消除NetBIOS隐患
·
网络入侵检测系统
·
潜伏在Windows默认设置中的陷井
·
调制解调器的不安全
·
构建Windows 2000服务器的安全防护林
·
SQL Server 2000的安全配置
·
Windows优化大师注册机源码
·
Aspcode动画教程
·
WIN 2000服务器防止ICMP数据包攻击教程
·
实现网络隐身的简单方法
·
手工进行克隆帐号
·
用W32DASM破解网页合并器的密码
·
注册表操作动画教程
·
冰河陷阱v1.2
·
黑客攻防技术宝典:Web实战篇(第2版)
·
超级网管员——网络安全
·
代码大全(第二版)
·
软件之道:软件开发争议问题剖析
·
CSS插件工具箱
·
CSS入门经典(第3版)
·
C#并行编程高级教程:精通.NET 4 Pa
·
CMMI+敏捷整合开发
关于我们
|
联系我们
|
广告服务
|
投资合作
|
版权申明
|
在线帮助
|
网站地图
|
作品发布
|
Vip技术培训
版权所有:
红黑联盟
--致力于做最好的IT技术学习网站