百度空间 | 百度首页 
               
 
查看文章
 
[note]句柄啊,3层表啊,ExpLookupHandleTableEntry啊...
2008年01月08日 星期二 21:06

到此已经彻底明白了。哈哈,感谢kanxue和Debugman里面的2位大牛的热心帮助:

www.debugman.com/read.php

bbs.pediy.com/showthread.php

---------------------------------------------------------------------------------------

一天前的疑惑:

句柄这东西到了底层还真烦琐。HANDLE本来就是个void类型的4字节,保存指向object的指针.于是就有了

HANDLE_TABLE、HANDLE_TABLE_ENTRY、OBJECT_HEADER、 EXHANDLE

琢磨着这个EXHANDLE,它里面的Index保存着3层表索引。通过它,也就是EXHANDLE。Value 的后30位可以找到进程ID指向的object

关于这个3层表,“JIURL玩玩Win2k进程线程篇 HANDLE_TABLE”一文中也有比较详细的介绍,可惜是W2K滴, HANDLE_TABLE在XP中发生了变化,不过其中的第一个参数保存的内容仍然是指向HANDLE_TABLE_ENTRY,不过是要经过索引偏移后才能得到.

开始还准备用Windbg探索下这个3层表,发现困难重重 ---

准备搞下QQ进程中的HANDLE_TABLE,一张图接着一张图后,到 TableCode这里卡住了。不晓得具体怎么偏移才能继续搜索到下一层的表了。。。

就是这点破东西害的偶看WRK看了2天多。还是木有完全理解。哎,等以后脑子清醒了再看吧。标记之:

这个破函数偶现在是看不明白了。糊涂的很,关键还是对这个3层表没有理解正确。里面一会儿求余、一会儿整除的,搞糊涂了。要是哪位牛牛能给偶解释下就好了。


PHANDLE_TABLE_ENTRY
ExpLookupHandleTableEntry (
    IN PHANDLE_TABLE HandleTable,
    IN EXHANDLE tHandle
    )
{
// 一大堆局部变量
    ULONG_PTR i,j,k;
    ULONG_PTR CapturedTable;
    ULONG TableLevel;
    PHANDLE_TABLE_ENTRY Entry = NULL;
    EXHANDLE Handle;

    PUCHAR TableLevel1;
    PUCHAR TableLevel2;
    PUCHAR TableLevel3;

    ULONG_PTR MaxHandle;

    PAGED_CODE();

    Handle = tHandle;
    Handle.TagBits = 0;
    MaxHandle = *(volatile ULONG *) &HandleTable->NextHandleNeedingPool;

// 判断当前句柄是否有效
    if (Handle.Value >= MaxHandle) {
        return NULL;       
    }

//
// 得到当前的索引等级 -- 即 CapturedTable 的最后2位
// 而 (CapturedTable - TableLevel) 便是这个3层表的起始地址。
// 通过Handle.Value中的后30位保存的索引号,找到进程ID对应的HANDLE_TABLE_ENTRY
//
    CapturedTable = *(volatile ULONG_PTR *) &HandleTable->TableCode;
    TableLevel = (ULONG)(CapturedTable & 3);
    CapturedTable -= TableLevel;

// 有3种情况: 0、1、2
    switch (TableLevel) {
       
        case 0:        

            TableLevel1 = (PUCHAR) CapturedTable;

            // 就一层表。这层表中保存的就是一堆HANDLE_TABLE_ENTRY
            // 索引号*2 得到在其中的偏移量
            Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[Handle.Value * 2];

            break;
       
        case 1:
          
            TableLevel2 = (PUCHAR) CapturedTable;

            // 有2层表:上层 和 下层 [中层为空]
            // 和2KB求余后,i保存的是在下层表中的索引
            i = Handle.Value % (2 * 1024);

            // 上层开始处偏移j后指向的是下层的开始处
            Handle.Value -= i;
            j = Handle.Value / ((2 * 1024) / 8);

            TableLevel1 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2[j];
            Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[i * 2];

            break;
       
        case 2:

            TableLevel3 = (PUCHAR) CapturedTable;

            i = Handle.Value % (2 * 1024);

            Handle.Value -= i;

            k = Handle.Value / ((2 * 1024) / 8);

            j = k % (4 * 1024);

            k -= j;

            k = k / (1024 / 2);


            TableLevel2 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel3[k];
            TableLevel1 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2[j];
            Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[i * 2];

            break;

        default :
            _assume (0);
    }

    return Entry;
}

附件

ExpLookupHandleTableEntry.rar (400.5 KB)

类别:Note | 浏览() | 评论 (1)
 
最近读者:
 
网友评论:
1
2008年01月15日 星期二 13:07
真是云雾缭绕!~想学可又不知道什么用!~
 
本篇日志被作者设置为禁止发表新评论

     

©2009 Baidu