本文借助windbg来理解程序中的函数如何使用handle对句柄表进行查询的。所以先要开启Win7下Windbg的内和调试功能。

  • 解决win7下内核调试的问题
win7下debug默认无法进行内核调试(!process等命令无法使用),除非是双机调试。或改用livekd进行调试。
尝试http://blog.csdn.net/hutao1101175783/article/details/50522767中提出的方法,开启windbg的内和调试功能:

重启之后开启Local Kernel Debugging:

开启成功:

加载符号表之后,就可以使用!process命令了:

  • 解决windbg源码调试的问题:

添加源文件路径:

开启源码级别的调试:

给TestHandle.exe的main函数下断点:
运行后自动弹出源码调试:

  • 研究句柄

再开一个windbg用内核调试。!process 0 0 命令找到TestHandle.exe的信息:

查看这个进程的所有句柄信息(同时也显示出了OBJECT的信息,来给我们提供验证):

下面,借助对TestHandle.exe的调试我们知道38号句柄是hEvent:

查看0x38号句柄的信息(这个信息被我当做“结果”来验证我的“推理”过程):

  • 推理步骤

查看TestHandle的EProcess结构:

得到TableCode,这个值指向一级、二级或三级句柄表(具体是几级句柄表由末尾数决定):

根据低两位判断句柄表的层级。TableCode低位是1,说明是一个二级句柄表(可以参考这个文章的分析:https://www.cnblogs.com/lsh123/p/7296423.html):

 

这里显示了两个一级句柄表
不同级别的句柄表可以参考文章:https://www.2cto.com/kf/201609/543902.html
和图:

那么句柄值乘以4再加上fffff8a0`19ca8000就是指向对应的handle_table_entry://为什么这里要乘以4?句柄是0x38,索引就是0x38/4,又由于每个handle_table_entry的大小是16字节。那么为什么索引是0x38/4?后面会回答

找到对应的handle_table_entry:

其中fffffa80`11399951 就是Object指针,偏移0x30-1就可以定位到OBJECT:

因为是在64位系统下,所以偏移是0x30-1,偏移发生了变化(32位系统下就是0x17):

这样就通过句柄取到了内核对象,整个流程思路参考了:http://www.cppblog.com/sleepwom/archive/2011/10/19/72591.html
并参考了图片:

  • handle的类型
在WinNT.h中定义的handle是这样的:
typedef void* handle;

而DECLARE_HANDLE(HWND);就是:
  struct HWND__ { int unused;};
  typedef struct HWND__ *HWND;
所以DECLARE_HANDLE的作用就是将name定义为一个指向结构体的指针。
handle是一个无类型指针,而HWND是一个指向结构体的指针。
Handle是一个void存储着一个整形数据类型作为“伪索引”。
这里的handle就是我们本例中传入的0x38。ExMapHandleToPointer 中又会调用ExpLookupHandleTableEntry。
在使用句柄去查找进程的句柄表时会调用函数ExpLookupHandleTableEntry,其原型如下:

参数 HandleTable 是查找目标所在的 Handle table 地址,而 tHandle 是结构化的 Handle 值。参考:http://www.mamicode.com/info-detail-1539980.html
handle与exhandle的关系如下:
这个 tHandle 结构将 Handle 值分为几个部分,如下图所示:

这个 TagBit 值占两位(bit 0 到 bit 1),被清为 0 值。因此:tHandle.Value 值就是对齐在 4 bytes 边界上。(出于某种原因)使用高30位作为索引来查找句柄表,低两位的存在没有意义。参考:https://www.cnblogs.com/ck1020/p/5897460.html

现在低两位没有意义不代表将来低两位没有意义,handle的含义和使用可能在未来发生变化。

《Windows核心编程》第3章——深入理解handle的更多相关文章

  1. windows核心编程 第8章201页旋转锁的代码在新版Visual Studio运行问题

    // 全局变量,用于指示共享的资源是否在使用 BOOL g_fResourceInUse = FALSE; void Func1() { //等待访问资源 while(InterlockedExcha ...

  2. windows核心编程 第5章job lab示例程序 解决小技巧

    看到windows核心编程 第5章的最后一节,发现job lab例子程序不能在我的系统(win8下)正常运行,总是提示“进程在一个作业里”         用process explorer程序查看 ...

  3. windows核心编程---第七章 用户模式下的线程同步

    用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ...

  4. Windows核心编程 第十七章 -内存映射文件(上)

    第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...

  5. Windows核心编程 第六章 线程基础知识 (上)

    第6章 线程的基础知识 理解线程是非常关键的,因为每个进程至少需要一个线程.本章将更加详细地介绍线程的知识.尤其是要讲述进程与线程之间存在多大的差别,它们各自具有什么作用.还要介绍系统如何使用线程内核 ...

  6. Windows核心编程 第四章 进程(上)

    第4章 进 程     本章介绍系统如何管理所有正在运行的应用程序.首先讲述什么是进程,以及系统如何创建进程内核对象,以便管理每个进程.然后将说明如何使用相关的内核对象来对进程进行操作.接着,要介绍进 ...

  7. Windows核心编程 第三章 内核对象

    第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...

  8. windows核心编程---第四章 进程

    上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了.首先要给大家介绍的是进程内核对象.进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象就是与进程相关联的一个数据结构.操作系统内核通过 ...

  9. Windows核心编程 第27章 硬件输入模型和局部输入状态

    第27章 硬件输入模型和局部输入状态 这章说的是按键和鼠标事件是如何进入系统并发送给适当的窗口过程的.微软设计输入模型的一个主要目标就是为了保证一个线程的动作不要对其他线程的动作产生不好的影响. 27 ...

  10. Windows核心编程 第十七章 -内存映射文件(下)

    17.3 使用内存映射文件 若要使用内存映射文件,必须执行下列操作步骤: 1) 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件. 2) 创建一个文件映射内核对象,告诉系统该 ...

随机推荐

  1. kbmMW 5.08.01压力测试报告

    上图为客户端测试结果,运行14小时,无异常报告.基于洞主封装的HttpsysTransport,基于ClientQuery完成25万多次数据库访问操作,含查询并对查询结果进行修改及增加新记录,然后提交 ...

  2. mysql常见查询练习题

    #建学生信息表student create table student ( sno varchar(20) not null primary key, sname varchar(20) not nu ...

  3. 2019-04-03-day025-异常与日志

    内容回顾 考试 6个小时 120分 (100+20) 15:00-18:00 笔试 60分 19:00-22:00 上机考试 40分 + 20分 60分及格不算附加题 简答题 读程序 简单编程 编程题 ...

  4. Spring MVC — @RequestMapping原理讲解-1

    转载地址 :http://blog.csdn.net/j080624/article/details/56278461 为了降低文章篇幅,使得文章更目标化,简洁化,我们就不例举各种@RequestMa ...

  5. Python 笔试 —— 效率与优雅

    1. 效率 字符串拼接: 加号拼接字符串将造成对象的创建和垃圾的回收: 使用字符串的 join 方法对尤其是循环中的字符串进行拼接(先将不断出现的字符串 append 到 一个 list 中,再进行 ...

  6. Samsung_tiny4412(驱动笔记05)----Makefile,open,read,write,lseek,poll,ioctl,fasync

    /*********************************************************************************** * * Makefile,op ...

  7. JAVA基础部分复习(一、8中基础类型,以及String相关内容)

    以下是关于java中8种基本类型的介绍说明: package cn.review.day01; /** * java基础复习,8种数据类型 * (byte,short,long,int,double, ...

  8. [LeetCode&Python] Problem 706. Design HashMap

    Design a HashMap without using any built-in hash table libraries. To be specific, your design should ...

  9. day04之流程控制

    if语句: if 条件1: pass elif 条件2: pass elif 条件3: pass else: pass if 条件语句中,先判断条件1,如果满足条件1,则执行第二行代码,第二行执行完后 ...

  10. HDU 1069:Monkey and Banana(DP)

    Monkey and Banana Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...