`
wodamazi
  • 浏览: 1416625 次
文章分类
社区版块
存档分类
最新评论

读书笔记_windows内核编程基础_part 1

 
阅读更多

1. 数据类型的定义,一般使用重定义的方式,例如ULONG,UCHAR等,x86到x64平台,指针从4字节转变成8字节。

2. 大多数的内核API都返回一个状态,这个状态的类型为NTSTATUS。一般用宏NT_SUCCESS()来判断返回值是否成功

3. DbgPrint()输出的字符串可以在debugview下观察到

UNICODE_STRING str = RTL_CONSTANT_STRING(L”first-ddddd”);,如此定义Unicode字符串

打印unicode字符串,利用%wZ, 因为这是一个结构指针。DbgPrint(“%wZ”,&str);

4. 驱动对象

Windows内核是面向对象,但是的是C语言

驱动对象的结构

typedef struct _DRIVER_OBJECT {

// 结构的类型和大小。

CSHORT Type;

CSHORT Size;

// 设备对象,这里实际上是一个设备对象的链表的开始。因为DeviceObject

// 中有相关链表信息。读下一小节“设备对象”会得到更多的信息。

PDEVICE_OBJECT DeviceObject;

……

// 驱动的名字

UNICODE_STRING DriverName;

……

// 快速IO 分发函数

PFAST_IO_DISPATCH FastIoDispatch;

……

// 驱动的卸载函数

PDRIVER_UNLOAD DriverUnload;

// 普通分发函数

PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];

} DRIVER_OBJECT;

内核模块不是一个进程,只是一组回调函数让windows来调用

有两个概念,“普通分发函数”和“快速IO分发函数”,引申的一个概念就是分发函数的Hook技术

5. IRP和设备对象DEVICE_OBJECT

DO用来接收IRP, IRP 都是发送给设备对象的,以下是wdm.h中定义的DEVICE_OBJECT的结构

Typedef struct DECLSPEC_ALLGN(MEMORY_ALLOCATION_ALIGNMENT)

_DEVICE_OBJECT{

CSHORT Type;

USHORT Size;

// 引用计数

ULONG ReferenceCount;

// 这个设备所属的驱动对象

Struct _DRIVER_OBJECT *DriverObject;

// 指向下一个设备对象,如果驱动对象中存在n个设备时,这些设备会组成一个单向链表。

Struct _DEVICE_OBJECT *NextDevice;

// 设备类型

DEVICE_TYPE DeviceType;

// IRP栈大小

HAR StackSize

}DEVICE_OBJECT

当Windows向设备对象发送请求时,驱动对象的分发函数中的某一个会被调用。分发函数的原型如下:

第一参数是请求目标的device,第二参数irp是请求的指针

NTSTATUS MyDispatch(PDEVICE_OBJECT deivce, PIRP irp);

IRP也是一个结构,这个结构很复杂,注意IRP栈空间。一个IRP往往需要传递n个设备才能完成,在传递过程中,有可能会一些“中间变换”,导致请求参数的变化,我们给每次“中转”都保留一个“栈空间”,用来保存中间参数,所以每个函数调用IRP都会分配一个空间。

6. WDK的函数

WDK的函数根据不同的分类,有着不同的前缀名,Ndis-开头都是网络启动开发相关的函数。

相对于windows API 比较常用的函数,WDK的函数对应为

ExAllocatePool 内存分配函数,相对于CRumTime库里的malloc

ExFreePool 内存释放,相对与CRunTime库里的free

ExAcquireFastMutex,获取一个快速互斥体,用于在多线程环境下的同步。

ExReleaseFastMutex,释放一个快速互斥体

ExRasieStatus,抛出一个异常,类似try exception。

Zw-和同名的Nt-函数有着同样的功能,中间实际上是从Zw-函数到Nt-函数的简单跳转关系。

常用的函数还包括Rtl-系列函数

RtlInitUnicodeString 初始化一个unicode字符串

RtlCopyUnicodeString 拷贝字符串

RtlAppendUnicodeToString 一个字符串追加到到另一个字符串后

RtlStringCbPrintf 打印字符串到另一个字符串中,相当与sprintf

RtlCopyMemory 内存数据块拷贝

RtlMoveMemory 内存数据移动

RtlZeroMemory 内存数据清零

RtlCompareMemory 比较内存

RtlGetVersion 获得当前windows的版本

Io-系列函数涉及IO管理器,所以它一般处于更低层,

IoCreateDevice,生成一个设备对象

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics