内核之旅-概述篇 上

Download PDF:
http://www.cisrg.cn/doc/krnl-way-win-11.rar

文章难免存在不足,如果有任何错误,请指正:)建议下载PDF查看本文章,内容比WEB版多些。
7all7@163.com

Author:7all
WebSite:http://www.cisrg.cn
推荐的图书:
《深入解析Windows操作系统》(中文版)
《Microsoft.Windows.Internals.Fourth.Edition》(英文版,前者的英文原版)
《深入理解计算机系统》(中文版)
《80x86汇编语言与计算机体系结构》(英文版)
好的资料可以给大家带来技术上面更多的想法,《深入解析Windows操作系统》为候捷翻译,刚刚发行,刚买来后,我花了3个小时在这本书中遨游,发现了很多看英文版本时搞错的概念,对于象我这样英语差的同胞,这本书绝对可以称得上经典的资料。
《深入理解计算机系统》是一本以Linux系统为基础讲解OS架构与硬件关系的图书,对于喜欢Linux的朋友可以考虑阅读该书,在《Unix操作系统设计》中由于以Unix V为版本讲解的Unix系统,多少有些许看得不尽人意的地方;而目前针对FreeBSD的资料比较少,所以如果大家想从整个系统的角度来分析一个类Unix系统的话,这本书将是一个好资料,而且还会帮你纠正很多写代码的弊病。
如果说Intel出了汇编语言,那么《80x86汇编语言与计算机体系结构》则是告诉你汇编程序是怎么编写的,每个指令在何种情况下占用了几个字节,一个程序在编译、连接后的opcode(机器码)是如何产生的,作者会很细心的告诉你一个mov指令占用一个时钟周期,在数据传值上经常使用mov、xchg,还会告诉你mov指令占用的opcode字节。如果有人说《深入理解计算机系统》这本书不好,那我只能说每个人的想法不同,如果有人说这本书不好的话,我就没有啥言语了,这本书是我所见到的汇编教程中比较NB的一本了。


(一)需要理解的几个概念
在开始针对Windows的机制分析前,需要注意一些基础概念,有了这些概念,然后结合工具的使用,会有利于对Windows机制的分析。
API:Application Program Interface,有几千个API函数。
Plat software Development Kit:平台开发套间,在开发VC程序时,最好的习惯是安装最新的SDK包,里面的内容绝对比你安装的过时的MSDN多很多,同时还有很多例子代码告诉你Windows程序的规范是怎么写的。
DDK:设备驱动开发包。
进程的概念:
进程只是一个容器而已,因为这个容器用来存放主线程,在Windows程序中,无论是main、WinMain函数创建的都不是进程,而是主线程,主线程才为一个进程内的主体。理解线程的概念,对于开发Windows程序有很大的帮助。进程创建后,根据其各种环境条件创建了主线程,主线程也分为两个部分,User Mode Thread(用户模式线程)和Kernel Mode Thread(内核模式线程)。对于主线程而言,我们可做的坏事情(从线程角度考虑,抛弃进程的各种环境条件)不是很多,当我们调用CreateThread函数创建一个线程,或者创建一个线程池时,我们可以做的坏事情就会相对较多,因为MS提供了一部分管理线程的函数,同时也公布了一组管理线程的内核数据结构,该数据结构为CONTEXT;从CONTEXT数据结构是依靠CPU类型来看,该结构的确是有些底层了;对于该结构的描述,在《Windows核心编程》有所阐述。通过初始化一个CONTEXT结构,通过GetThreadContext函数可以获取当前线程的CPU寄存器状态,通过SetThreadContext函数我们可以设置当前线程的CPU寄存器状态。不过这里有些麻烦的是,当我们使用GetThreadContext和SetThreadContext函数时,线程必须是不活动的,因为一个用户态可见的活动线程是异步执行的,可能你使用上述函数时得到的值与实际值有出入。前段时间在搞线程池时问过同事关于异步的问题,同事给我了很好的答案,通过一段时间的编写测试代码,对该处有了更深的认识。
线程的概念:
有必要把下面的内容单独出来,上面只是通过主线程的一些看法,以及CONTEXT结构的特殊性。既然谈及到CONTEXT结构,有个比较有意思的事情,我昨天早上起床背了几个单词后突然想起了这个结构,于是我把ntoskrnl.exe进行了逆向,在ntoskrnl.exe内也存在一个CONTEXT结构,而且与用户态的结构值完全相同,但这并不说明内核态会引用用户态的该结构,前面提及的该结构底层的说法只是说明该结构保存获得的内容比较底层而已。如果大家认真看过《Windows核心编程》中关于对该结构描述时,作者夸张的做法后,其实作者有些地方也不是很对的,当然每个人理解技术的情况不同,如果这里解释有误,还是需要大家的指点。
提及CONTEXT结构,而且上面也提及可以通过Get(Set)ThreadContext函数实现对该结构的修改,那么我们是否可以实现通过对该结构的操作来实现用户态下线程的暂停和恢复运行?答案是可以,但是需要进行特殊的处理,因为线程是异步执行的,其堆栈环境也不象进程那样稳定,换句话说进程只要主线程在运行,那么其堆栈环境会稳定的存在;但是线程(指使用CreateThread创建的线程)与之不同,一旦线程返回结束,或者调用线程结束函数,则在线程创建时的堆栈会自动被内核清理掉。但是使用CONTEXT结构来管理线程的话,就需要对线程的运行机理非常的熟悉,否则很难实现对其管理。
要想在用户态下实现对多个线程的控制(这里的控制不是指线程同步,线程同步是比较容易实现的,很多资料都有详细的讲解),最好的也是唯一的办法(用户态)就是ResumeThread和SuspendThread,因为Windows是一个多任务强占式操作系统,所以在线程调度时你很难控制内核模式下线程的情况,所以在用户态下只能使用上面的这两个函数恢复和暂停线程。上面说到线程有用户态和内核态的区分,所以当使用SuspendThread函数暂停线程时,仅仅暂停了用户态线程;也即用户态线程暂停了,在内核态它还是活跃的;但这足够了,最起码我们可以保证我们在用户态下的程序能够按照我们的想法运行了,至于内核态如何,那就是OS的事情了。
线程包括:
一组代码CPU状态的寄存器值
两个栈,用户态栈和内核态栈
TLS(Thread Local Storage),私有存储区域
线程唯一标识符,线程ID
线程自己的运行环境

虚拟内存:
这个概念等同于Unix下的swap(交换分区),针对该问题的描述,我们先以通用的说法来理解。在OS内一个程序的执行,并没有使用实际的物理地址,程序的执行通过OS与CPU来结合执行,在OS中存在一种分页机制,用于映射32位程序的地址到物理地址;若程序运行时占很大空间,可以使用swap(*nix)、PageFile.sys(Win)来进行虚拟内存映射,这些都通过分页机制来实现。
在Windows中,使用内存管理器(Memory Manager)来实现内存映射,同时也起到保护的作用。这种保护、映射机制使得一个进程不会闯入另一个进程,也不会修改内核的数据。
要通俗的理解的话,可以把虚拟内存机制考虑为用户态调试时可见的内存地址,但并非真实物理内存地址,然后通过Memory Manager进行内存映射。





摘自wrk/base/ntos/mm/i386/mi386.h (DownLoad:http://www.cisrg.cn/viewtopic.php?id=1656)
/*++

    Virtual Memory Layout on x86 is:

                 +------------------------------------+
        00000000 |                                    |
                 |                                    |
                 |                                    |
                 | User Mode Addresses                |
                 |                                    |
                 |   All pages within this range      |
                 |   are potentially accessible while |
                 |   the CPU is in USER mode.         |
                 |                                    |
                 |                                    |
                 +------------------------------------+
        7ffff000 | 64k No Access Area                 |
                 +------------------------------------+
        80000000 |                                    |
                 | NTLDR loads the kernel, HAL and    |
                 | boot drivers here.  The kernel     |
                 | then relocates the drivers to the  |
                 | system PTE area.                   |
                 |                                    |
                 | Kernel mode access only.           |
                 |                                    |
                 | When possible, the PFN database &  |
                 | initial non paged pool is built    |
                 | here using large page mappings.    |
                 |                                    |
                 +------------------------------------+
                 |                                    |
                 | Additional system PTEs, system     |
                 | cache or special pooling           |
                 |                                    |
                 +------------------------------------+
                 |                                    |
                 | System mapped views.               |
                 |                                    |
                 +------------------------------------+
                 |                                    |
                 | Session space.                     |
                 |                                    |
                 +------------------------------------+
        C0000000 | Page Table Pages mapped through    |
                 |          this 4mb region           |
                 |   Kernel mode access only.         |
                 |                                    |
                 +------------------------------------+
        C0400000 | HyperSpace - working set lists     |
                 |  and per process memory management |
                 |  structures mapped in this 8mb     |
                 |  region.                           |
                 |  Kernel mode access only.          |
                 +------------------------------------+
        C0C00000 | System Cache Structures            |
                 |   reside in this 4mb region        |
                 |   Kernel mode access only.         |
                 +------------------------------------+
        C1000000 | System cache resides here.         |
                 |   Kernel mode access only.         |
                 |                                    |
                 |                                    |
                 +------------------------------------+
        E1000000 | Start of paged system area         |
                 |   Kernel mode access only.         |
                 |                                    |
                 |                                    |
                 +------------------------------------+
                 |                                    |
                 | System PTE area - for mapping      |
                 |   kernel thread stacks and MDLs    |
                 |   that require system VAs.         |
                 |   Kernel mode access only.         |
                 |                                    |
                 +------------------------------------+
                 |                                    |
                 | NonPaged System area               |
                 |   Kernel mode access only.         |
                 |                                    |
                 +------------------------------------+
        FFBE0000 | Crash Dump Driver area             |
                 |   Kernel mode access only.         |
                 +------------------------------------+
        FFC00000 | Last 4mb reserved for HAL usage    |
                 +------------------------------------+
--*/

(二)Windows体系结构
内核部分:
Ntoskrnl.exe:执行体和内核,上层为执行体,主要提供导出函数(API、设备驱动)、只能在内核运行的函数等;下层为内核,由一些函数组成,同时负责对底层硬件结构的支持。
Hal.dll:硬件抽象层,在该层实现了对各种硬件的支持;实际上Hal.dll与Ntoskrnl.exe是相互依赖的关系,通过他们的结合,实现了Windows的平台移植。
Win32k.sys:包括内部支持函数,内核设备驱动程序;包括,GUI实现部分,收集鼠标键盘事件并处理,屏幕输出等。
核心DLL:Kernel32.dll、Advapi32.dll、User32.dll、Gdi32.dll。
用户态部分:
系统支持进程,Winlogon.exe(登陆)、System Process(空闲进程)、Interrupts(中断,空闲进程)、DPCs(延迟过程调用,空闲进程)、System(内核模式系统线程)、smss.exe(会话管理器)。
服务进程,services.exe。
环境子系统,csrss.exe(环境子系统,在win中很重要的一部分)。
用户态应用程序。
可使用 Process Explore查看,下载地址:www. sysinternals.com。


重点理解:
Ntdll.dll,用户态需要与内核交互的API函数都通过Ntdll.dll进行,首先用户态API函数接口都通过Ntdll.dll交付给内核态,然后内核态返回信息给Ntdll.dll,再由Ntdll.dll把信息传递给用户态程序。可见该dll的重要性。
下面引用了候捷老师在MS讲座上的PPT图片,当然这些图片也可以在MS的站点上找到,鉴于直接引用候捷老师的PPT,这里特地指出。
下载地址:http://www.cisrg.cn/viewtopic.php?id=1823

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值