内核编程基础

内核编程基础

1.内核API的使用

  • 在应用层编程 我们可以使用WINDWOS提供的各种API函数,只要导入头文件<windows.h>就可以了,但是在内核编程的时候,我们不能像Ring3那样直接使用。微软为内核程序提供了专门的API,只要在程序中包含相应的头文件就可以使用了,如:#include <ntddk.h>(假设你已经正确安装了WDK)
  • 在应用层编程的时候,我们通过MSDN来了解函数的详细信息,在内核编程的时候,要使用WDK自己的帮助文档

2.未导出函数的使用

WDK说明文档中只包含了内核模块的函数,对于未导出的函数,则不能直接使用。
如果要使用未导出的函数,只有自己定义一个函数指针,并且为函数指针提供正确的函数地址就可以使用了。有两种办法都可以获取未导出的函数地址

<1>特征码搜索

<2>解析内核PDB文件

3.基本数据类型

<1> 在内核编程的时候,强烈建议大家遵守WDK的编码习惯,不要这样写:
unsigned long length;

<2>习惯使用WDK自己的类型:

ULONG(unsigned long)   PULONG(unsigned long *)
UCHAR(unsigned char)   PUCHAR(unsigned char*)
UINT(unsigned int)     PUINT(unsigned int*)
VOID(void)          PVOID(void*)

4.返回值

大部分内核函数的返回值都是NTSTATUS类型,如:

NTSTATUS PsCreateSystemThread();
NTSTATUS ZwOpenProcess();
NTSTATUS ZwOpenEvent();

在这里插入图片描述

也就是说,这个值能说明函数的执行结果,比如:

STATUS_SUCCESS            0X00000000   成功  

STATUS_INBALID_PARAMETER  0xC000000D   参数无效  

STATUS_BUFFER_OVERFLOW    0x80000005   缓冲区长度不够

当你调用的内核函数,如果返回的结果不是STATUS_SUCCESS,就说明函数执行中遇到了问题,具体是什么问题,可以在ntstatus.h文件中查看

5.内核中的异常处理

在内核中,一个小小的错误就可能导致蓝屏,比如:读写一个无效的内存地址.为了让自己的内核程序更加健壮,强烈建议大家在编写内核程序时,使用异常处理.

Windows提供了结构化异常处理机制,一般的编译器都是支持的,如下:

__try{

        //可能出错的代码
    }
    
__except(filter_value)
{
    //出错时要执行的代码
}

出现异常时,可根据filter-value的值来决定程序该如何执行,当filter_value的值为:

EXCEPTION_EXECUTE_HANDLER(filter_value = 1),代码进入except块  
EXCEPTION_CONTINUE_SEARCH(filter_value = 0),不处理异常,由上一层调用函数处理
EXCEPTION_CONTINUE_EXECUTION(filter_value = -1),回去继续执行错误处的代码  

6.常用的内核内存函数

对内存的使用,主要就是:申请,设置,拷贝以及释放.

C语言内核中
mallocExAllocatePool
memsetRtlFillMemory
memcpyRtlMoveMemory
freeExFreePool

7.内核字符串种类

CHAR(char)        //ASCII  
WCHAR(wchar_t)    //UNICODE
ANSI_STRING       //升级版ASCII
 UNICODE_STRING   //升级版UniCode

在应用层时,无论是ASCII还是UNICODE都是以0结尾,表示字符结束,区别时ascii是一个字节(0),而unicode是两个字节的(00)

ANSI_STRING字符串:

typedef struct _STRING
{
    USHORT Length;//长度
    USHOST MaximumLength;//最大长度
    PCHAR Buffer;//字符串开始地址
}STRING;

UNICODE_STRING字符串:

typedef struct 
{
    USHORT Length;//长度
    USHOST MaximumLength;//最大长度
    PWSTR Buffer;//字符开始地址
}UNICODE_STRING;

//区别在于它的是PWSTR,两个字节为单位

在驱动开发中,尽量使用升级版的字符类型

内核字符串常用函数

字符串常用的功能无非就是:
创建,复制,比较以及转换等等

功能ANSI_STRING字符串UNICODE_字符串
创建RtlInitAnsiStringRtlInitUncodeString
复制RtlInitAnsiStringRtlCopyUnicodeString
比较RtlCompareStringRtlCompareUnicodeString
转换RtlAnsiStringToUnicodeStringRtlUnicodeStringToAnsiString
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值