如果要使用未导出的函数,只要自己定义一个函数指针,并且为函数指针提供正确的函数地址就可以使用了。有两种办法都可以获取为导出的函数地址:
<1> 特征码搜索(模块里搜索) <2> 解析内核PDB文件(windbg u指令)
当你调用的内核函数,如果返回的结果不是STATUS_SUCCESS,就说明函数执行中遇到了问题,具体是什么问题,可以在ntstatus.h文件中查看。
在内核中,一个小小的错误就可能导致蓝屏,比如:读写一个无效的内存地址。为了让自己的内核程序更加健壮,强烈建议大家在编写内核程序时,使用异常处。 Windows提供了结构化异常处理机制,一般的编译器都是支持的,如下:
__try{ //可能出错的代码 } __except(filter_value) { //出错时要执行的代码 }出现异常时,可根据filter_value的值来决定程序该如果执行,当filter_value的值为:
EXCEPTION_EXECUTE_HANDLER(1),代码进入except块 EXCEPTION_CONTINUE_SEARCH(0),不处理异常,由上一层调用函数处理 EXCEPTION_CONTINUE_EXECUTION(-1),回去继续执行错误处的代码ANSI_STRING字符串:
typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; }STRING;UNICODE_STRING字符串:
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaxmumLength; PWSTR Buffer; } UNICODE_STRING; ANSI_STRING字符串UNICODE_STRING字符串RtlInitAnsiStringRtlInitUnicodeStringRtlCopyStringRtlCopyUnicodeStringRtlCompareStringRtlCompareUnicoodeStringRtlAnsiStringToUnicodeStringRtlUnicodeStringToAnsiString由于这是纯c代码,所以必须在上面先声明变量
#include <ntddk.h> //卸载函数 VOID DriverUnload(PDRIVER_OBJECT driver) { DbgPrint("驱动程序停止运行了.\r\n"); } //入口函数,相当于main NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) { //驱动程序入口 //DbgPrint("int3的第一个驱动程序\n"); //内核开辟空间 PULONG AddrTemp = 0; ULONG StartAddr = 0x8003F000; ULONG i= 0; PULONG Addr = (PULONG)ExAllocatePool(NonPagedPool,0x10000); //初始化 RtlFillMemory(Addr,0x10000,0); //从GDT和IDT拷贝数据 //GDT 0x8003F000 0x3FF 0x8003F000 0x7FF RtlMoveMemory(Addr,(CONST VOID UNALIGNED*)StartAddr,0xBFE); AddrTemp = (PULONG)Addr; for (i=0;i<0x40;i++) { DbgPrint("%08X %08X %08X %08X %08X",StartAddr,*(AddrTemp+1),*AddrTemp,*(AddrTemp+3),*(AddrTemp+2)); AddrTemp+=4; //为什么1和3在前面? 为了和windbg显示一样,换了一下次序 StartAddr+=0x10; } DbgPrint("GDT表打印完毕"); for (i=0;i<0x80;i++) { DbgPrint("%08X %08X %08X %08X %08X",StartAddr,*(AddrTemp+1),*AddrTemp,*(AddrTemp+3),*(AddrTemp+2)); AddrTemp+=4; StartAddr+=0x10; } DbgPrint("IDT表打印完毕"); //free释放 ExFreePool(Addr); //设置一个卸载函数,便于退出 driver->DriverUnload = DriverUnload; return STATUS_SUCCESS; }2.编写代码,实现如下功能: <1> 初始化一个字符串 <2>拷贝一个字符串 <3>比较两个字符串是否相等 <4> ANSI_STRING与UNICODE_STRING字符串相互转换
#include <ntddk.h> //卸载函数 VOID DriverUnload(PDRIVER_OBJECT driver) { DbgPrint("驱动程序停止运行了.\r\n"); } //入口函数,相当于main NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path) { //创建字符串 ANSI_STRING ANString1; ANSI_STRING ANString2; UNICODE_STRING StrUnicode; //初始化 RtlInitAnsiString(&ANString1,"My Name Is ANSISTR@NG1"); RtlInitAnsiString(&ANString2,"My Name Is ANSISTRING2"); RtlInitUnicodeString(&StrUnicode,L"My Name Is UNICODESTR"); //比较 if (RtlCompareString(&ANString1,&ANString2,TRUE) == 0) { DbgPrint("第一次:ANString1 equal to ANString2"); } else { DbgPrint("字符串不相等.\r\n"); } //拷贝 RtlCopyString(&ANString2,&ANString1); if (RtlCompareString(&ANString1,&ANString2,TRUE) == 0) { DbgPrint("第二次:ANString1 equal to ANString2"); } else { DbgPrint("字符串不相等.\r\n"); } //转换 if (RtlAnsiStringToUnicodeString(&StrUnicode,&ANString1,TRUE) == STATUS_SUCCESS) { DbgPrint("RtlAnsiStringToUnicodeString转换成功"); } //设置一个卸载函数,便于退出 driver->DriverUnload = DriverUnload; return STATUS_SUCCESS; }