zoukankan      html  css  js  c++  java
  • 内核编程基础

    一、未导出函数的使用

    WDK说明文档中只包含了内核模块导出的函数,对于未导出的函数,则不能直接使用。

    如果要使用未导出的函数,只要自己定义一个函数指针,并且为函数指针提供正确的函数地址就可以使用了。有两种办法都可以获取为导出的函数地址:

    1. 特征码搜索
    2. 解析内核PDB文件

    二、返回值

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

    NTSTATUS PsCreateSystemThread();

    NTSTATUS ZwOpenProcess();

    NTSTATUS ZwOpenEvent();

    这个值能说明函数执行的结果,例如

    1. STATUS_SUCCESS 0x00000000  成功
    2. STATUS_INVALID_PARAMETER 0xC000000D 参数无效
    3. STATUS_BUFFER_OVERFLOW 0X80000005 缓冲区长度不够

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

    三、内核中的异常处理

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

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

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

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

    四、常用的内核内存函数

    五、内核字符串种类

    CHAR(char)/WCHAR(wchar_t)/ANSI_STRING/UNICODE_STRING

    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;

    六、内核字符串常用函数、

    字符串常用的功能无非就是:

    创建、复制、比较以及转换等等

     七、课后作业

     申请一块内存,并在内存中存储GDT、IDT的所有数据。然后在DebugView中显示出来,最后释放内存

    #include<ntddk.h>
    #include<ntstatus.h>

    VOID DriverUnload(PDRIVER_OBJECT driver)
    {
    DbgPrint("驱动停止运行. ");
    }

    extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path)
    {
    UCHAR GDT[6];
    UCHAR IDT[6];
    ULONG GdtAddr, GdtLen, IdtAddr, IdtLen;
    PUCHAR pBuffer = NULL;
    ULONG i;
    // 设置一个卸载函数,便于退出
    pDriver->DriverUnload = DriverUnload;
    // 读取GDT, IDT
    __asm
    {
    sgdt fword ptr GDT
    sidt fword ptr IDT
    }
    GdtAddr = *(PULONG)(GDT + 2);
    GdtLen = *(PUSHORT)GDT;
    IdtAddr = *(PULONG)(IDT + 2);
    IdtLen = *(PUSHORT)IDT;
    pDriver->DriverUnload = DriverUnload;

    //申请内存
    //参数pagepool代表是系统可用内存
    PUCHAR SMemory = (PUCHAR)ExAllocatePool(PagedPool,IdtLen+GdtLen);

    if (SMemory == NULL)
    {
    DbgPrint("申请内存失败. ");
    return STATUS_SUCCESS;
    }
    //将gdt与idt的数据赋值到自己申请的内存中
    RtlMoveMemory(SMemory, (PUCHAR)GdtAddr, GdtLen);
    RtlMoveMemory(SMemory + GdtLen, (PUCHAR)IdtAddr, IdtLen);
    //打印表
    DbgPrint("Print GDT Table: ");
    for (ULONG i = 0; i < GdtLen; i+=16)
    {
    DbgPrint("%08x %08x`%08x %08x`%08x ", (ULONG)(SMemory + i), ((PULONG)(SMemory + i))[0], ((PULONG)(SMemory + i))[1], ((PULONG)(SMemory + i))[2], ((PULONG)(SMemory + i)[3]));
    }
    DbgPrint("Print IDT TABLE: ");
    for (ULONG i = 0; i < IdtLen; i += 16)
    {
    DbgPrint("%08x %08x`%08x %08x`%08x ", (ULONG)(SMemory + GdtLen+ i), ((PULONG)(SMemory + GdtLen + i))[0], ((PULONG)(SMemory + GdtLen + i))[1], ((PULONG)(SMemory + GdtLen + i))[2], ((PULONG)(SMemory + GdtLen + i)[3]));
    }
    //释放内存
    ExFreePool(SMemory);

    return STATUS_SUCCESS;
    }

    运行结果截图

     

  • 相关阅读:
    C++ 引用做左值
    C++ 引用本质的详解
    C++ 引用基础
    C语言错误 指针的类型错误
    C++ c++与C语言的区别(三目运算符,const修饰符)
    C++ c++与C语言的区别(struct类型的加强,函数-变量类型加强,bool类型)
    C++ c++与C语言的区别(实用性增强,register关键字增强,全局变量检测增强)
    C++ c++初识
    C语言 Linux内核链表(企业级链表)
    C语言 结构体中属性的偏移量计算
  • 原文地址:https://www.cnblogs.com/pppyyyzzz/p/13897247.html
Copyright © 2011-2022 走看看