能力值:
( LV5,RANK:60 )
|
-
-
26 楼
占位,观帖~~~
|
能力值:
( LV2,RANK:10 )
|
-
-
27 楼
学习哦。。楼主好人
|
能力值:
( LV2,RANK:10 )
|
-
-
28 楼
观摩了,但是不是很懂,继续学习。。。
|
能力值:
( LV12,RANK:400 )
|
-
-
29 楼
tp中创建了一个IO TIMER,所以我们来看一下如何遍历系统中的所有IO TIMER
至于基本概念,大家有不明白的就去参考一下WDK文档吧
PT中提供了这个功能:
最终我山寨的效果:
多了一个,应该是PT没有显示无效的IO TIMER
我们最终的目的是遍历IO TIMER链然后取消指定模块中的IO TIMER,
所以理想中我会最终封装出来一个这样的函数:
BOOLEAN DeleteIoTimerInSpecialModule(PWCHAR pModuleName);
关于遍历IO TIMER,网上我搜了下貌似没什么具体的介绍,那么我们就看一下WRK中有没有相关线索,
还是从已导出的函数入手,相关函数:
IoInitializeTimer初始化IO TIMER
IoStartTimer启动IO TIMER
IoStopTimer停止IO TIMER
先看一下IoInitializeTimer:
代码很简单,如果传入的设备对象没有关联IO TIMER就分配一个IO TIMER,并与设备对象相关联,
也就是保存到设备对象的Timer域,
最后将IO TIMER的TimerList域追加到了IopTimerQueueHead的尾部,来看一下 IO TIMER 结构:
这个结构在xp,2k3,win7中是相同的
TimerList是一个ListEntry,这样我们只要找到了IopTimerQueueHead就能遍历系统中的所有IO TIMER了
搜索IopTimerQueueHead过程就不列出了,无非就是定位
接下来将IO TIMER中对我们有用的信息保存出来,这里我自定义了一个结构用来保存信息:
typedef struct _MyIoTimer{
ULONG TimerObjectAddress;
ULONG TimerState;
ULONG TimerRoutine;
ULONG DeviceObject;
}MyIoTimer,*PMyIoTimer;
#define MAX_IOTIMER_COUNT 150
//遍历IopTimerQueueHead取得IO TIMER信息
//执行成功返回MyIoTimer结构的数量,否则为0
ULONG GetIoTimerInformationByIopTimerQueueHead(PVOID* pvBuf)
{
ULONG IopTimerQueueHeadAddress;
ULONG ulBufSize;
ULONG ulTemp;
ULONG ulCount = 0;
PLIST_ENTRY pIopTimerQueueHead = NULL;
PLIST_ENTRY pNextTimer = NULL;
PIoTimer pTimer = NULL;
MyIoTimer myTimer;
IopTimerQueueHeadAddress = GetIopTimerQueueHeadAddress();
if ( MmIsAddressValidEx((PVOID)IopTimerQueueHeadAddress) == VCS_INVALID ) return 0;
pIopTimerQueueHead = (PLIST_ENTRY)IopTimerQueueHeadAddress;
pNextTimer = pIopTimerQueueHead->Blink;
//分配足够大的空间
ulBufSize = MAX_IOTIMER_COUNT * sizeof(MyIoTimer);
*pvBuf = ExAllocatePoolWithTag(PagedPool,ulBufSize,123);
if (*pvBuf == NULL) return 0;
while ( TRUE )
{
if ( MmIsAddressValidEx(pNextTimer) == VCS_INVALID )
{
KdPrint(("检测到IopTimerQueueHead中存在非法地址"));
ExFreePool(*pvBuf);
*pvBuf = NULL;
return 0;
}
if ( pNextTimer == pIopTimerQueueHead ) break;
pTimer = CONTAINING_RECORD(pNextTimer,IoTimer,TimerList);
RtlZeroMemory(&myTimer,sizeof(MyIoTimer));
myTimer.TimerObjectAddress = (ULONG)pTimer; //IO TIMER对象地址
myTimer.TimerState = (ULONG)pTimer->TimerFlag;
myTimer.TimerRoutine = (ULONG)pTimer->TimerRoutine; //TIMER例程地址
myTimer.DeviceObject = (ULONG)pTimer->DeviceObject; //设备对象
RtlMoveMemory( (PVOID)((ULONG)*pvBuf+ulCount*sizeof(MyIoTimer)),&myTimer,sizeof(MyIoTimer) );
pNextTimer = pNextTimer->Blink;
ulCount++;
if ( ulCount > MAX_IOTIMER_COUNT )
{
KdPrint(("Io Timer 数量超过了150")); //这里简单退出了,可以更改为分配更大的缓冲
ExFreePool(*pvBuf);
*pvBuf = NULL;
return 0;
}
}
return (ulCount*sizeof(MyIoTimer));
}
通过封装的这个函数就能得到系统中的所有IO TIMER了
最后判断一下 TimerRoutine 是否在指定的模块地址范围之内,如果检测到了的话,
调用IoStopTimer取消定时器
BOOLEAN DeleteIoTimerInSpecialModule(PWCHAR pModuleName)
{
PVOID pvTimerBuf = NULL;
ULONG ulTimerReturn;
ULONG ulModuleBase;
ULONG ulModuleSize;
ULONG i;
ULONG ulCount = 0;
PMyIoTimer pMyTimer = NULL;
BOOLEAN Result = FALSE;
if (pModuleName == NULL) goto __exit1;
ulTimerReturn = GetDriverObjectByIopTimerQueueHead(&pvTimerBuf);
if (ulTimerReturn == 0) goto __exit1;
ulModuleBase = GetSpecialModuleBase(pModuleName,&ulModuleSize);
if ( (ulModuleBase < (ULONG)MmSystemRangeStart)||(ulModuleSize == 0) ) goto __exit1;
pMyTimer = (PMyIoTimer)pvTimerBuf;
//遍历所有IO TIMER
while (TRUE)
{
if ( (pMyTimer->TimerObjectAddress == 0)||(ulCount == MAX_IOTIMER_COUNT - 1) ) break;
if ( (pMyTimer->TimerRoutine > ulModuleBase)&&(pMyTimer->TimerRoutine < ulModuleBase + ulModuleSize) )
IoStopTimer((PDEVICE_OBJECT)pMyTimer->DeviceObject);
pMyTimer++;
ulCount++;
}
Result = TRUE;
__exit1:
if ( pvTimerBuf != NULL ) ExFreePool(pvTimerBuf);
pvTimerBuf = NULL;
return Result;
}
|
能力值:
( LV3,RANK:20 )
|
-
-
30 楼
看雪好久没有看到好贴了,你的分享精神很可贵。
对了,能推荐下你认为好的驱动学习书籍吗?
|
能力值:
( LV3,RANK:20 )
|
-
-
31 楼
写的很好,我不懂驱动可是能看得懂你写的。我感觉你表达能力很强,有点大师的风格啊。
能把你写的工具分享给大家吗?
|
能力值:
( LV2,RANK:10 )
|
-
-
32 楼
写的非常详细啊,楼主兄弟!可惜菜鸟我连io timer是何物都不知道呢,真正个暴殄天物啊(恸哭。。)
wdk文档哪里有?是中文的吗?
偷笑一下楼上的兄弟(申明:不是恶意的):我不懂驱动可是能看得懂你写的!!!不懂驱动也看得懂??这也叫懂?有过度拍马屁之嫌,呵呵
|
能力值:
( LV2,RANK:10 )
|
-
-
33 楼
与5楼同问,加上一问:能分享下楼主学习驱动的经验或历程否?
好文章啊,为什么我就写不出呢?这一篇前面看得懂,后面就不知所云了,apc是何物哦?
|
能力值:
( LV2,RANK:10 )
|
-
-
34 楼
路过学习,保存下来慢慢看
|
能力值:
( LV12,RANK:760 )
|
-
-
35 楼
硬碰硬非常不良好啊~
|
能力值:
( LV3,RANK:20 )
|
-
-
36 楼
嗯嗯 像楼主学习!!有一天我也会的
|
能力值:
( LV2,RANK:10 )
|
-
-
37 楼
markkkkkkkkkkkkk
|
能力值:
( LV2,RANK:10 )
|
-
-
38 楼
markkkkkkkkkkk
|
能力值:
( LV2,RANK:10 )
|
-
-
39 楼
小菜路过,好久没玩了。。看下。
|
能力值:
( LV2,RANK:10 )
|
-
-
40 楼
呵呵,支持一个。。。。
|
能力值:
( LV2,RANK:10 )
|
-
-
41 楼
呵呵 共享精神值得共勉
|
能力值:
( LV2,RANK:10 )
|
-
-
42 楼
这个太厉害了。。
|
能力值:
( LV2,RANK:10 )
|
-
-
43 楼
不错,学习了~~
|
能力值:
( LV2,RANK:10 )
|
-
-
44 楼
国际惯例,强势插入,深入了解!
|
能力值:
( LV2,RANK:10 )
|
-
-
45 楼
属于喜欢的类型
|
能力值:
( LV2,RANK:10 )
|
-
-
46 楼
很明显不行……线程回调没处理……
|
能力值:
( LV11,RANK:190 )
|
-
-
47 楼
图文并茂,灰常谢谢楼主
|
能力值:
( LV2,RANK:10 )
|
-
-
48 楼
呵呵,看到了看到了
|
能力值:
( LV2,RANK:10 )
|
-
-
49 楼
牛贴,学习下
|
能力值:
( LV4,RANK:50 )
|
-
-
50 楼
不错,支持楼主分享精神。。。
|
|
|