【旧文章搬运】更正一个枚举PspCidTable时的错误
原文发表于百度空间及看雪论坛,2009-02-27
看雪论坛地址:https://bbs.pediy.com/thread-82919.htm
==========================================================================
PspCidTable现在已经很科普了,关于其具体格式及如何枚举,网上相关文章一大堆,最多的两篇是gz1x和sudami写的。我这里只谈一个问题,就是枚举PspCidTable时cid的上限问题。很多人提到以一个Magic Number为上限,其值为0x4e1c,比如sudami的《PspCidTable杂谈》。虽然大多数时候这个上限已经大到足够用了,但事实上这个上限值是不可靠的,附张图,这个极BT的pid把我雷到了...

看到这张图后,我自己也写个了程序来验证了一下,更证实了0x4e1c这个值的不可靠。
程序如下:
///////////////////////代码开始////////////////////
#include "stdafx.h"
#include <windows.h>
#include <stdio.h> DWORD WINAPI ThreadProc(LPVOID lpParameter );
HANDLE hEvent=NULL;
int main(int argc, char* argv[])
{ int i=;
DWORD tid=;
hEvent=CreateEvent(NULL,FALSE,TRUE,"TEST");
for (i=;i<;i++)
{ CreateThread(NULL,,ThreadProc,NULL,NULL,&tid);
printf("Runing %d...TID=%d\n",i,tid);
Sleep();
}
while ()
{
Sleep();
}
return ;
} DWORD WINAPI ThreadProc(LPVOID lpParameter )
{
WaitForSingleObject(hEvent,INFINITE);
return ;
}
///////////////////////代码开始////////////////////
虽然ProcessId和ThreadId同样在PspCidTable占位,但是创建线程的开销明显要小于创建进程,因此这里创建2000个线程,而且这个线程里等待一个无信号的事件而进入挂起状态,运行开销也要小得多。(当然也可以直接在创建时就挂起)运行这个程序,可以直接从返回的ThreadId明显感觉到PspCidTable的膨胀。在我把这个程序运行了四次之后,就可以看到pid=25508=0x63A4(此时其线程的tid更大),再运行Windbg可看到其pid=33736=0x83C8,很BT~

很明显了,0x4e1c这个不知道哪儿来的数(貌似是BlackLight提出的)并不可靠,正确的方法呢?
正确方法就是以PspCidTable的NextHandleNeedingPool为上限。
来看一下当前的PspCidTable:
lkd> dd pspcidtable L1
805695e0 e1001a00
lkd> dt _HANDLE_TABLE e1001a00
nt!_HANDLE_TABLE
+0x000 TableCode : 0xe12e4001
+0x004 QuotaProcess : (null)
+0x008 UniqueProcessId : (null)
+0x00c HandleTableLock : [] _EX_PUSH_LOCK
+0x01c HandleTableList : _LIST_ENTRY [ 0xe1001a1c - 0xe1001a1c ]
+0x024 HandleContentionEvent : _EX_PUSH_LOCK
+0x028 DebugInfo : (null)
+0x02c ExtraInfoPages :
+0x030 FirstFree : 0x86d0
+0x034 LastFree : 0x86bc
+0x038 NextHandleNeedingPool : 0x8800
+0x03c HandleCount :
+0x040 Flags :
+0x040 StrictFIFO : 0y1
可以看到NextHandleNeedingPool值为0x8800=34816,这对当前情况来说是个很合理的值。其实由Windows分配句柄表的原理可知,0x8800才是当前句柄表(PspCidTable)的句柄上限,仅当当前Pool已满,不能放下更多对象时,才会再次分配一个一级表,而NextHandleNeedingPool也将增大到0x9000,步长为一个一级表的句柄大小0x800.
在枚举PspCidTable时就不再用0x4e1c的另一个理由是(当然,前面那张图已经很有说服力了,哈哈):系统自己在枚举句柄表时使用的ExEnumHandleTable函数仍然是调用了ExpLookupHandleTableEntry来实现的。而ExpLookupHandleTableEntry的开头是这样写的:
////////////省略无关代码//////////
MaxHandle = *(volatile ULONG *) &HandleTable->NextHandleNeedingPool; //
// See if this can be a valid handle given the table levels.
//
if (Handle.Value >= MaxHandle) {
return NULL;
}
////////////省略无关代码//////////
看到了吗?系统也是以NextHandleNeedingPool的值作为当前句柄表中的句柄上限,即使你用0x4e1c来暴力枚举,在超出NextHandleNeedingPool之后也得不到哪怕一个有效的进线程对象。不用多说什么了,以后我们要忘掉0x4e1c,使用NextHandleNeedingPool作为枚举时正确的句柄上限值。
【旧文章搬运】更正一个枚举PspCidTable时的错误的更多相关文章
- 【旧文章搬运】ZwQuerySystemInformation枚举内核模块及简单应用
原文发表于百度空间,2008-10-24========================================================================== 简单说,即 ...
- 【旧文章搬运】ZwQuerySystemInformation枚举进线程信息
原文发表于百度空间,2008-10-15========================================================================== 很古老的东 ...
- 【旧文章搬运】炉子给的SYSTEM_HANDLE_TYPE有点错误
原文发表于百度空间,2008-12-03========================================================================== 今天写程序 ...
- 【旧文章搬运】关于windbg搜索符号文件的一点说明
原文发表于百度空间,2010-09-07========================================================================== 本来只是打 ...
- 【旧文章搬运】分析了一下360安全卫士的HOOK(二)——架构与实现
原文发表于百度空间及看雪论坛,2009-10-14 看雪论坛地址:https://bbs.pediy.com/thread-99460.htm 刚发这篇文章的时候,因为内容涉及360的核心产品,文章被 ...
- 【旧文章搬运】PspCidTable概述
原文发表于百度空间,2009-03-28========================================================================== PspCi ...
- 【旧文章搬运】PspCidTable攻与防
原文发表于百度空间,2009-03-29========================================================================== PspCi ...
- 【旧文章搬运】加载PE文件时IAT的填充时机
原文发表于百度空间,2011-06-20========================================================================== 大致过程如 ...
- 【旧文章搬运】如何从EPROCESS辨别一个进程是否已退出
原文发表于百度空间,2008-7-31========================================================================== 前面已经通过 ...
随机推荐
- [转] 一句shell命令搞定代码行数统计
今天面试时,突然被面试官问到怎样用shell命令搞定某个文件夹下java代码行数的统计. 想了一下,基本思路就是找到这个文件夹下面的所有java文件,然后每个文件统计一下代码,外层套个for循环,叠加 ...
- spring-quartz定时任务使用小结
在实际项目中,通常须要用到定时任务(定时作业).spring框架提供了非常好的实现. 1. 下载spring-quartz插件包 这里默认当前系统中是集成了spring框架的基本功能的.去网上下载s ...
- 几种自己主动运行js代码的方式
近期在看jquery,发现他竟然能自己主动运行js代码,于是就查了下.收集了几种经常使用的实现方法 jquery的方法 使用场景:不论什么须要运行的js特效 $(document).ready(fun ...
- Effective C++ 条款13/14 以对象管理资源 || 在资源管理类中小心拷贝行为
三.资源管理 资源就是一旦你使用了它,将来不用的时候必须归还系统.C++中最常用的资源就是动态内存分配.其实,资源还有 文件描述符.互斥器.图形界面中的字形.画刷.数据库连接.socket ...
- 【转载】.NET Remoting学习笔记(一)概念
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...
- 不能选择sublime作为默认打开方式的解决办法
Sublime Text 绿色版删除后无法设置为默认打开方式…而且网上也没有给出明确的解决办法 注册表的解决办法: 删除 HKEY_CURRENT_USER\Software\Classes\Appl ...
- HDU 3065 病毒侵袭持续中(AC自己主动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3065 Problem Description 小t非常感谢大家帮忙攻克了他的上一个问题.然而病毒侵袭 ...
- 移动Web开发实践
移动设备的高速发展给用户带来了非常大的便利.用户使用Android.iPhone和其他移动设备非常easy接入互联网. 移动设备对网页的性能要求比較高.以下就说说Mobile Web开发的一些心得. ...
- jquery 深入学习笔记之中的一个 (事件绑定)
[jquery 事件绑定] 1.加入元素事件绑定 (1) 加入事件为当前元素 $('p').on('click',function(){ //code here ... }); (2) 加入事件为未来 ...
- python第三方库系列之十八--python/django test库
django是属于python语音的web框架,要说django測试.也能够先说说python的測试.django能够用python的方式測试,当然,django也基于python封装了一个自己的測试 ...