精华内容
下载资源
问答
  • 2018-11-09 02:54:38

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

    也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                   
    什么是Windows内核编程?

    上述文字由《天书夜读:从汇编语言到Windows内核编程》作者  谭文  提供

        Linux的内核编程大家都是比较熟悉的。而Windows内核编程则不大为一般读者所熟悉。常常有这样的问题:

        “你又没有Windows的代码,你如何搞内核编程?”

        “除了微软的人,难道还有人做Windows内核吗?”

        “Windows内核编程有用吗?”

        其实Windows内核编程不但有用,而且常用。很多我们每天都使用的软件,就毫无疑问的使用了Windows内核编程的技术。最典型的就是实时监控的杀毒软件。此外还有防火墙、虚拟光驱、以及90%的驱动程序。这些程序的有一个共同的特点,他们的一部分组件,是作为Windows的一部分,能对Windows上运行的所有的应用程序起作用。

        因此内核编程的应用,往往给传统软件带来更强的功能,实现技术上的飞跃。

        举个例子。我们常常听说,对文件进行加密,可以使文档更加安全。对文件加密并不需要任何内核组件。我们可以写一个应用程序,读入文件,加密数据,然后重写为一个加密文件。解密也可以同样如此。

        但是实际上这并不满足一般的用户需求。对一个公司的员工来说,那些“重要的文档”很可能就是每天工作所用的文件。想象一下,他必须要每天从服务器上下载加密的文件,然后用解密工具解密。然后用Office开始工作。工作完毕后,用加密工具加密,再上传,然后删除工作文档。且不说大部分时间文档是以解密的方式保存在硬盘上的不安全性,这个工作流程是可以接受的吗?没有人会接受的。

        比较“人性化”的方式就是让Office可以直接打开已经加密的文档。保存的时候,直接就保存成加密的文档。硬盘上,这个文档始终是加密的。而且对合法的用户透明。对非法的用户,则只能看见密文,从而无法编辑也无法阅读。而且也不仅仅Office,还有AutoCAD、Visual Studio、Photoshop等等用户可能用于编辑机密文件的所有的工具。这是可以实现的吗?如果我们不能去修改Office和其他的工作软件。

        这当然是可以实现的。既然我们编写Windows内核程序,当然可以让Windows的文件系统从硬盘读取文件的时候,对特定的进程进行特别的解密。等这些软件读取到数据的时候,它们读到的已经是正常的数据了。这个过程和实时扫描病毒的原理是一样的,使用一个文件过滤驱动程序。这就是读者可能已经听到过的文件透明加密技术。

        在和《天书夜读:从汇编语言到Windows内核编程》一书同一系列的《寒江独钓——Windows内核编程与信息安全》(预计明年出版)中,对键盘过滤、硬盘过滤、文件过滤、网络过滤等安全相关的内核编程,都有详尽的讲解和例子。

        内核编程的另一个特点是:这些代码运行在R0级。R0级别是最高特权级别。对CPU有完全控制的能力。这非常的适合一些安全软件,当然也适合做破坏的工作。因为内核程序有最高(也就是根)权限,这样的技术在安全领域(或者破坏领域)被称为rootkit技术。rootkit技术是当前安全领域最热门的技术之一。

        许多病毒使用了rootkit技术。用来隐藏病毒文件,窃取密码、发送攻击包等等。rootkit病毒感染后极难清除,在感染前提前防范是最有效的办法。

        Windows内核确实没有公开源代码。但是MS提供Windows内核程序的开发包:WDK。WDK实际上主要用于开发驱动程序。而驱动程序基本上都是内核程序。WDK提供的头文件以及部分源代码,实际上就是Windows内核的代码的一部分。有部分驱动程序(比如FAT32文件系统)的代码是完全公开的。我们也可以在这里看到Windows内核开发者的代码风格。同时,微软也提供了所有Windows版本的符号表在网上供研究者下载。并提供了功能无比强大的调试器WinDbg。有了它们,你就可以轻松的调试Windows内核了。无论是你自己写的代码的部分,还是Windows内核开发者们编写的部分。虽然看到的是汇编语言,但是函数名和全局变量名都是存在的。而且,所有的这些(WDK、WinDBG,符号表)都是免费的。

        那您还在等什么呢?欢迎进入Windows内核编程的世界!

    13164110_200810161135191.jpg本书购买地址:http://www.china-pub.com/209258


    【书 名】天书夜读:从汇编语言到Windows内核编程
    【作 者】 谭文,邵坚磊 著
    【ISBN】 978-7-121-07339-7
    【出版社】 电子工业出版社
    【出版日期】2008年12月
    【宣传语】
    从貌似天书的汇编代码中,一探Windows底层的核心实现。
    在开发中出现的问题,能从Windows自身找到答案!
                

    给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

    这里写图片描述
    更多相关内容
  • 资源名称:[天书夜读-从汇编语言到Windows内核编程]资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
  • 从汇编语言到Windows内核编程 驱网核心技术丛书 天书夜读
  • 《从汇编语言到Windows内核编程》这是一本关于Windows内核编程的书籍
  • 如果读者从未接触过Windows内核编程,本部分将指导读者开始Windows内核编程,学会使用WDK,并熟悉内核编程的习惯与方法。  第4章 内核字符串与内存 38  4.1 字符串的处理 39  4.1.1 使用字符串结构 39  4.1.2 ...
  • windows内核编程

    2016-09-19 10:46:02
    windows内核下操作字符串
  • 基本Windows内核编程+++教程 Visual Studio配置 1- General ==> Windows SDK Version ===> 10.0.10586.0 2- VC++ Directories ==> Include Directories = $(VC_IncludePath);$(WindowsSDK_IncludePath); 3- C/C++ ==...
  • 达内2013Windows内核编程的PDF文档
  • 从汇编语言到Windows内核编程.pdf 【完整书签】【高清版】(共282页) ============================================ 入手篇 熟悉汇编 第1章 汇编指令与c语言 1.1 上机建立第一个工程 1.1.1用visual studio创建工程...
  • 天书夜读-从汇编语言到Windows内核编程 高清完整-附件资源
  • 天书夜读-从汇编语言到Windows内核编程].谭文.邵坚磊.扫描版.pdf
  • 本书从基本的windows程序与汇编指令出发,深入浅出地讲解了windows内核编程、调试、阅读,以及自行探索的方法。读者在使用c/c++开发windows程序的基础上,将熟练掌握汇编和c语言的应用,深入了解windows底层,并...
  • 然后开始讲解Windows内核的C语言编程的基础。让读者能熟悉使用C语言开发Windows内核程序。接着指导读者进行内核的开发和调试环境的配置,并进行了一系列的尝试:阅读Windows内核的部分实现代码,并尝试自己去实现它...
  • Delphi监视串口的Windows内核编程-截取串口..rar
  • [天书夜读-从汇编语言到Windows内核编程].谭文.邵坚磊.扫描版.
  • 很不错的电子书,经典书籍,值得一读
  • 介绍了使用VMWare或者Hyper-V虚拟机搭建传统的Windows内核编程开发调试环境的方法,并利用VS2015新建了一个极其简单的NT式驱动程序HelloWorld,通过介绍HelloWorld的安装、调试和设置DbgPrint过滤等知识,概要展现一...
  • [天书夜读-从汇编语言到Windows内核编程].谭文.邵坚磊.扫描版.pdf
  • 大部分widnows驱动程序都是内核驱动(Kernel Driver),所以本笔记不分"驱动程序"与"内核编程",也不区分"内核模块"(Kernel Module)、“驱动程序”(Driver)与"内核程序",这些词汇统一指编译出的扩展名为".sys"的可...

    第一个内核程序

    通过 Visual Studio新建工程

    注意事项:
    大部分widnows驱动程序都是内核驱动(Kernel Driver),所以本笔记不分"驱动程序"与"内核编程",也不区分"内核模块"(Kernel Module)、“驱动程序”(Driver)与"内核程序",这些词汇统一指编译出的扩展名为".sys"的可执行文件(并非强制扩展名为.sys),也不区分"应用层"与"用户态"。

    驱动分类:

    1. NT驱动 最简单的驱动模型,不支持硬件特性
    2. WDM驱动 在NT驱动的基础上引入的一套驱动模型,支持即插即用、电源事件等特性。
    3. WDF驱动 对WDM驱动的封装与升级,屏蔽了部分细节,简化了大量接口。

    笔记中如不是特殊说明,一般都为NT驱动。

    打开 Visual Studio 2019 选择"创建新项目",选择 “Empty WDM Driver
    在这里插入图片描述
    键入工程名字"MyDriver"
    在这里插入图片描述
    点击"创建"
    在这里插入图片描述
    创建成功。

    然后在菜单中找到“项目§”→“添加新项”,在弹出的对话框中选择“C++文件(.cpp)”,在下方的名称(N)中输入“First.c”,最后点击“添加”。
    在这里插入图片描述
    现在已经可以看到工程内存在一个空白的First.c文件,开发者可以往这个空白文件中添加内核代码,但在添加代码前,需要包含驱动开发的头文件ntddk.h。

    内核入口函数详解

    内核驱动入口函数 DriverEntry 原型如下

    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
    

    参数介绍:
    DriverObject,表示一个驱动对象的指针,指向操作系统在内存中为该驱动分配的一个类型为PDRIVER_OBJECT数据结构,用于记录该驱动的详细信息。
    RegistryPath,表示当前驱动所对应的驱动对象指针。是一个类型为UNCODE_STRING的指针,表示当前驱动所对应的注册表位置。UNICODE_STRING是内核中表示字符串的结构体,定义如下:

    typedef struct _UNICODE_STRING {
    USHORT Length; //表示Buffer所指向缓冲区中字符串的长度,单位为字节。
    USHORT MaximumLength;//表示Buffer所执行的缓冲区的总空间大小,单位为字节。
    _Field_size_bytes_part_opt_(MaximumLength, Length) PWCH   Buffer;//指向一个UNICODE类型的字符串缓冲区
    } UNICODE_STRING;
    typedef UNICODE_STRING* PUNICODE_STRING;
    

    注意:Buffer指向的字符串,并不要求以 ‘\0’ 作为结束,在大多数情况下,Buffer指向的字符串没有以 ‘\0’ 结尾。

    RegistryPath 为 PUNICODE_STRING 类型的参数,表示的是这个驱动所对应注册表的位置,这是因为内核驱动时作为 Windows 系统服务 (Service) 存在的,Widnows系统又众多服务,如果从服务运行的环境来区分,服务分为用户态服务、内核态服务,统称为 “服务(Service)”,不同服务通过服务的名字来识别,服务的名称简称 “服务名”。
    在安装操作系统后,系统会内置一系列服务,这些服务统称为系统服务,称为第三幅服务。开发者可以开发属于自己的服务,称为第三方服务。一个驱动SYS文件需要运行(加载到内核中),首先需要把这个驱动文件注册(创建)成一个服务(第三方服务),注册成功后,系统会把该服务信息写入到注册表HKEY_LOCAL_MACHINE\ SYSTEM\CurrentControlSet\Services 下,以服务的名字作为一个注册表的键名。

    入口函数DriverEntry的返回值类型为NTSTATUS,定义如下
    typedef _Return_type_success_(return >= 0) LONG NTSTATUS;,由此可见返回值实际上是一个LONG类型。
    Windows操作系统规定DriverEntry返回STATUS_SUCCESS表示成功,返回其他值表示失败。
    内核驱动作为Windows服务运行,在执行具体代码前,驱动SYS文件首先会被映射到内核地址空间,作为内核的一个驱动模块(MODULE),接着系统对这个驱动模块执行导入表初始化、修正重定位表中对应的数据偏移等操作,最后系统会调用该驱动模块的DriverEntry入口函数,如果这个入口函数返回STATUS_SUCCESS,系统认为这个驱动初始化成功;如果这个入口函数返回除STATUS_SUCCESS以外的其他值,系统认为驱动初始化失败,系统执行一系列的清理工作,并把驱动模块从内核空间中移除,从用户态角度看,就是服务启动失败。

    编写入口函数体

    实例:

    #include "ntddk.h"
    
    VOID DriverUnload(PDRIVER_OBJECT DriverObject)
    {
    	if (DriverObject != NULL)
    	{
    		DbgPrint("[%ws]Driver Upload,Driver Object Address:%p", __FUNCTIONW__, DriverObject);
    	}
    
    	return;
    }
    
    /// @brief 入口函数
    /// @param DriverObject 一个驱动对象的指针
    /// @param RegistryPath 当前驱动对应的注册表位置
    /// @code 
    /// typedef struct _UNICODE_STRING {
    ///		USHORT Length;
    ///		USHORT MaximumLength;
    ///		#ifdef MIDL_PASS
    ///		[size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT* Buffer;
    ///		#else // MIDL_PASS
    ///		_Field_size_bytes_part_opt_(MaximumLength, Length) PWCH   Buffer;
    ///		#endif // MIDL_PASS
    ///	} UNICODE_STRING;
    /// typedef UNICODE_STRING* PUNICODE_STRING;
    /// @encode
    /// @return 返回一个NTSTATUS值,即 STATUS_SUCCESS 或适当的错误状态
    
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    {
    	// DbgPring函数是WDK提供的API,类似c语言的printf函数
    	// %ws表示打印一个以'\0'结尾的UNICODE字符串
    	// __FUNCTIONW__是以'\0' 结束的UNICODE字符串,表示当前函数的名字,对应格式化字符串中的%ws
    	DbgPrint("[%ws]Hello Kernel World\n", __FUNCTIONW__);
    
    	// 判断两个参数是否为空,不为空打印两个参数值
    	if (RegistryPath != NULL)
    	{
    		// RegistryPath类型为UNICODE_STRING类型,打印该类字符串需要使用%wZ格式化参数
    		DbgPrint("[%ws]Driver RegistryPath:%wZ\n", __FUNCTIONW__, RegistryPath);
    	}
    	if (DriverObject != NULL)
    	{
    		DbgPrint("[%ws]Driver Object Address:%p\n", __FUNCTIONW__, DriverObject);
    		// 服务停止回调
    		DriverObject->DriverUnload = DriverUnload;
    	}
    	return STATUS_SUCCESS;
    }
    

    注意:不能使用一下方式打印UNICODE_STRING类型的变量,例如不能使用下面的方式打印上面实例中的RegistryPath参数:
    DbgPring("[%ws] Driver RegistryPath: %ws\n",__FUNCTIONW__,RegistryPath->Buffer);
    因为UNICODE_STRING结构体内Buffer指向的字符串结尾不一定有’\0’,而对于 %ws 类型来说,会一直寻找Buffer字符串的’\0’,在这种情况下,行为是不可预料的。

    DriverEntry函数除了打印一系列信息,还有一个重要的操作:
    DriverObject->DriverUnload = Unload;
    DriverUnload是DriverObject结构体中的一个成员,DriverObject表示当前的驱动对象,记录了当前驱动的详细信息,DriverUnload为驱动对象结构体内的一个函数指针。
    驱动是作为服务方式运行的,服务可以被启动,也可以被停止,停止的实质就是系统把该驱动模块对应在内核地址空间中的代码以及数据移除。当一个内核驱动被要求停止时,DriverObject→DriverUnload指向的函数就会被系统调用,开发者可以在这个函数中执行一些清理相关的工作。
    DriverUnload函数非常重要,但重要并不等于必须,DriverUnload函数是可选的,开发者可以不提供DriverUnload函数,这样做的结果是该驱动不支持停止,也就是说,只要开发者不提供DriverUnload函数,这个驱动对应的服务一旦启动后,再也无法停止。该特性被很多安全软件利用,刻意不提供DriverUnload函数,避免驱动被恶意停止。
    DriverEntry函数执行一系列操作后,最后返回STATUS_SUCCESS,表示驱动初始化成功。DriverEntry函数返回除STATUS_SUCCESS以外的其他值时,表示驱动初始化失败,系统发现驱动初始化失败会移除内核地址空间的驱动代码与数据,这个操作看起来与驱动服务的停止非常类似,但是请读者注意:驱动初始化失败不会触发DriverUnload函数的调用,DriverUnload只有在驱动服务成功启动(初始化)后,被要求停止时才会触发。

    编译第一个驱动

    通过Visual Studio 编译

    点击生成,如果出现以下错误,则删除MyDriver.inf文件即可,Ctrl/Command + ; 输入MyDriver.inf查找文件,右键点中该文件,选择 “删除”。

    在这里插入图片描述

    编译成功后,读者可以在工程的文件夹目录中找到一个x64的文件夹,在x64目录下找到Debug文件夹,该文件夹下的FirstDriver.sys文件就是编译好的驱动文件,对应的还有FirstDriver.pdb文件,FirstDriver.pdb文件包含了驱动相应的调试信息,如结构体定义、函数名等,在驱动调试中非常重要。该文件夹下还有其他文件,如FirstDriver.cer,可以暂时忽略。

    通过WDK直接编译

    通过WDK自带的编译程序来进行编译。在编译前,还需要准备一个Sources文件,Sources文件实际上是一个文本文件,文件名字为Sources,该文件主要描述了需要编译的C文件列表,以及需要链接的LIB库等信息,针对本例,Sources文件的内容编写如下:

    TARGETNAME=FirstDriver
    TARGETTYPE=DRIVER
    SOURCES=First.c
    

    TARGETNAME表示编译出来的目标名字;TARGETTYPE表示编译出来的二进制类型是DRIVER,而不是LIB或其他;SOURCES后面是需要编译的C文件,本例中只有一个First.c,如果有多个C文件需要编译,可以写成:

    SOURCES=First.c \
    	Second.c
    

    在开始菜单中找到Windows Driver Kit→选择Windows 7的x64 Checked Build Environment。在WDK编译工具的命令行中,使用cd命令进入First.c文件所在的目录,然后在命令行中输入“build”命令开始编译。注意,输入的build命令不带引号。
    在这里插入图片描述
    在编译过程中会报以下错误:
    在这里插入图片描述
    这是因为老版本的WDK不支持__FUNCTIONW__标识。这里给读者一个建议,如果编写的驱动代码需要支持不同版本的WDK编译,请不要使用新版本WDK独有的特性。针对上面的问题,请读者修改代码,去掉__FUNCTIONW__以及配套的%ws,或者简单地把DbgPrint注释掉,当然,更好的做法是根据不同WDK版本进行条件编译。修改后重新编译。成功生成驱动文件。
    在这里插入图片描述

    成功编译后,在First.c的文件夹内会生成一个objfre_wxp_x86\i386文件夹,成功编译后,在First.c的文件夹内会生成一个objchk_win7_amd64文件夹,这个文件夹的命名包含了驱动编译的版本信息,其中chk表示Debug版本,Win7表示使用的是Windows 7版本WDK编译环境,amd64表示64位驱动程序,在objchk_win7_amd64\amd64\文件夹下,生成了FirstDriver.sys文件以及FirstDriver.pdb文件。

    展开全文
  • Windows内核安全编程,这个资源不错,非常适合windows内核程序的入门,全面系统地介绍了串口、键盘、磁盘、文件系统、网络、等内核模块的编程技术
  • 天书夜读_从汇编语言到WINDOWS内核编程
  • 寒江独钓-Windows内核安全编程(完整版)--源码 寒江独钓-Windows内核安全编程(完整版)--源码
  • 如果读者从未接触过Windows内核编程,本部分将指导读者开始Windows内核编程,学会使用WDK,并熟悉内核编程的习惯与方法。  第4章 内核字符串与内存 38  4.1 字符串的处理 39  4.1.1 使用字符串结构 39  4.1.2 ...
  • 寒江独钓-Windows内核安全编程(完整版)
  • Windows内核编程

    2010-06-28 15:11:18
    Windows内核安全编程个人笔记(未完待续)
  • Windows内核编程》---基本汇编指令
  • 从汇编语言到Windows内核编程pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,077
精华内容 39,230
关键字:

windows内核编程