API使用规则
- 在Windows中API分为用户层API和内核层API,在用户层中,无法直接调用内核层API,实际上,绝大部分的用户层API在最底层都会通过
ntdll.dll
切换到内核层,间接调用内核层的API。 - 在内核层编程中,不能调用用户层的API,也就是说,像是创建文件就不能使用
CreateFile
,创建进程不能使用CreateProcess
,在内核层中会提供内核版本的创建文件、创建进程等的API。
内核API命名规则
- Windows操作系统的内核使用C编写,但是使用了面对对象的思想,在系统内核中,它将不同的API分成了不同的组件,每个API名称前都会带有一个组件的名称前缀,如下所示:
函数前缀 | 所属组件或函数的说明 |
---|---|
Cc | 缓存管理器 |
Cm | 配置管理器(注册表) |
Dbg/Kd | 调试支持函数 |
Ex | 执行体函数 |
FsRtl | 文件系统驱动程序 |
Fstub | 文件系统引导接口函数 |
Hal | HAL提供的接口函数 |
Io | I/O管理器 |
ke | 内核函数 |
Lpc | 本地过程调用(LPC)函数 |
Mm | 内存管理器 |
Nt | windows系统服务 |
Ob | 对象管理器 |
Perf | 日志记录函数 |
Po | 电源管理器 |
Pp | 即插即用管理器 |
Ps | 进程/线程 |
Raw | RAW文件系统函数 |
Rtl | 内存运行时库函数 |
Se | 安全函数 |
Vf | 驱动程序检验器哈桑农户 |
Wmi | Windows管理器规范 |
Zw | 和Nt前缀同名的一套函数,省去了参数验证的步骤,其它逻辑相同,可以认为以Nt前缀为名称的函数针对用户模式的调用者,以zW前缀为名称的函数针对内核模式的调用者 |
一些字符串操作API
- 这些API用于操作内核特有的字符串UNICODE_STRING结构
函数名 | 功能 |
---|---|
RtlInitUnicodeString | 初始化字符串,此函数不会分配空间 |
RtlFreeUnicodeString | 销毁字符串 |
RtlCopyUnicodeString | 拷贝字符串 |
RtlAppendUnicodeStringToString | 追加字符串 |
RtlCmpareUnicodeString | 比较字符串 |
RtlUnicodeStringToInteger | 字符串转数字 |
RtlIntegerToUnicodeString | 数字转字符串 |
Kdprintf | 输出 |
部分Ex-系列函数
Ex-系列函数名 | 功能 |
---|---|
ExAllocatePoolWithTag | 内存分配,相当于malloc |
ExFreePool | 内存释放,相当于free |
ExAcquireFaseMutex | 获取一个快速互斥体,互斥体用于多线程同步 |
ExReleaseFaseMutex | 释放一个快速互斥体 |
ExRaiseStatus | 抛出一个异常,带有一个错误的status值,这个函数用于从代码很深的地方直接报错 |
部分Zw-及Nt-系列函数
Zw-系列函数名 | 对应的Nt-函数 | 功能 |
---|---|---|
ZwCreateFile | NtCreateFile | 打开文件(实际上也可以用于打开一个设备) |
ZwWriteFile | NtWriteFile | 写文件(实际上也可以用于发送请求给设备) |
ZwReadFile | NtReadFile | 读文件,同上 |
ZwQueryDirectoryFile | NtQueryDirectoryFile | 目录查询 |
ZwDeviceIoControlFile | NtDeviceIoControlFile | 发出设备控制请求 |
ZwCreateKey | NtCreateKey | 打开一个注册表键 |
ZwQueryValueKey | NtQueryValueKey | 读取一个注册表中的值 |
部分Rtl-系列函数
Rtl-系列函数名 | 功能 |
---|---|
RtlInitUnicodeString | 初始化一个字符串 |
RtlCopyUnicodeString | 拷贝字符串 |
RtlAppendUnicodeToString | 将一个字符串追加到另一个字符串后 |
RtlStringCbPrintf | 将字符串打印到另一个字符串中,相当于sprintf |
RtlCopyMemory | 内存数据块拷贝 |
RtlMoveMemory | 内存数据块移动 |
RtlZeroMemory | 内存数据清零 |
RtlCompareMemory | 比较内存 |
RtlGetVersion | 获得当前windows的版本 |
部分Io-系列函数
- 以Io-开头的系列函数非常重要,因为它们涉及到了IO管理器,IO管理器的作用就是将用户调用的API翻译成IRP,或者将等价请求发送到内核各个不同的设备的关键组件,这个类别的函数是我们在处理请求是最常调用的。
Io-系列函数 | 功能 |
---|---|
IoCreateFile | 打开文件,这个函数比ZwCreateFile更加底层 |
IoCreateDevice | 生成一个设备对象 |
IoCallDriver | 发送请求,实际上这个函数可能是IofCallDriver的以个别名。WindowsIo管理器调用这个函数把不同的IRP发送到不同的设备 |
IoCompleteRequest | 完成请求,实际上是通知IO管理器这个IRP已经完成了 |
IoCopyCurrentIrpStackLocationToNext | 将当前的IRP栈空间内容拷贝到下一个栈空间 |
IoSkipCurrentIrpStackLocationToNext | 跳过当前IRP栈空间 |
IoGetCurrentIrpStackLocation | 获得IRP的当前栈空间指针 |
- 注:参考《Windows内核安全与驱动开发》