首页
社区
课程
招聘
[原创]通过暴搜DRIVER_OBJECT枚举驱动
发表于: 2010-3-30 00:12 19411

[原创]通过暴搜DRIVER_OBJECT枚举驱动

gjden 活跃值
14
2010-3-30 00:12
19411
收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 75
活跃值: (723)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
仔仔细细看完了
不能辜负楼主的一片热忱,,顶起来
2010-3-30 01:30
0
雪    币: 8196
活跃值: (2791)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
其实我一直在疑惑.

这个网上流传的验证地址有效的函数是如何流传起来了.

貌似某些人总讨厌MmIsAddressValid.

可是实际比较MmIsAddressValid和这个函数.做法不是很类似么.都是计算PTE..
2010-3-30 08:52
0
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
4
你那个IsValidAddr太狭隘了,很多情况没考虑到,比如pae啥的。MmIsValidAddr也只能判断非分页情况。
MmIsValidAddr也只能判断非分页情况。
贴个V大给的俄罗斯人写的:

PCHAR MiProtectionToString[] = {
"MM_ZERO_ACCESS", // 0 // this value is not used.
"MM_READONLY", // 1
"MM_EXECUTE", // 2
"MM_EXECUTE_READ", // 3
"MM_READWRITE", // 4 // bit 2 is set if this is writable.
"MM_WRITECOPY", // 5
"MM_EXECUTE_READWRITE", // 6
"MM_EXECUTE_WRITECOPY", // 7
"MM_NOCACHE" // 8
};

#if 1
#undef MmPrint
#define MmPrint(x)
#endif

VALIDITY_CHECK_STATUS
MmIsAddressValidExNotPae(
IN PVOID Pointer
)
{
VALIDITY_CHECK_STATUS Return = VCS_INVALID;


MMPTE* Pde = MiGetPdeAddress(Pointer);

MmPrint(("PDE is 0x%08x\n", Pde));
if( Pde->u.Hard.Valid )
{
MmPrint(("PDE entry is valid, PTE PFN=%08x\n", Pde->u.Hard.PageFrameNumber));

MMPTE* Pte = MiGetPteAddress(Pointer);

MmPrint(("PTE is 0x%08x\n", Pte));
if( Pte->u.Hard.Valid )
{
MmPrint(("PTE entry is valid, PFN=%08x\n", Pte->u.Hard.PageFrameNumber));
Return = VCS_VALID;
}
else
{
//
// PTE is not valid
//

MMPTE pte = *Pte;

MmPrint(("Got invalid PTE [%08x]: Proto=%d,Transition=%d,Protection=0x%x,PageFilePFN=0x%x\n",
pte.u.Long,
pte.u.Soft.Prototype,
pte.u.Soft.Transition,
pte.u.Soft.Protection,
pte.u.Soft.PageFileHigh));

if( pte.u.Long )
{
if( pte.u.Soft.Prototype == 1 )
{
MmPrint(("PTE entry is not valid, points to prototype PTE.\n"));

// more accurate check should be performed here for pointed prototype PTE!

Return = VCS_PROTOTYPE;
}
else // not a prototype PTE
{
if( pte.u.Soft.Transition != 0 )
{
//
// This is a transition page. Consider it invalid.
//

MmPrint(("PTE entry is not valid, points to transition page.\n"));

Return = VCS_TRANSITION;
}
else if (pte.u.Soft.PageFileHigh == 0)
{
//
// Demand zero page
//

MmPrint(("PTE entry is not valid, points to demand-zero page.\n"));

Return = VCS_DEMANDZERO;
}
else
{
//
// Pagefile PTE
//

if( pte.u.Soft.Transition == 0 )
{
MmPrint(("PTE entry is not valid, VA is paged out (PageFile offset=%08x)\n",
pte.u.Soft.PageFileHigh));

Return = VCS_PAGEDOUT;
}
else
{
MmPrint(("PTE entry is not valid, Refault\n"));
}
}
}
}
else
{
MmPrint(("PTE entry is completely invalid\n"));
}
}
}
else
{
MmPrint(("PDE entry is not valid\n"));
}

return Return;
}


VALIDITY_CHECK_STATUS
MmIsAddressValidExPae(
IN PVOID Pointer
)
{
VALIDITY_CHECK_STATUS Return = VCS_INVALID;

MMPTE_PAE* Pde = MiGetPdeAddressPae(Pointer);

MmPrint(("PDE is at 0x%08x\n", Pde));
if( Pde->u.Hard.Valid )
{
MmPrint(("PDE entry is valid, PTE PFN=%08x\n", Pde->u.Hard.PageFrameNumber));

MMPTE_PAE* Pte;

if( Pde->u.Hard.LargePage != 0 )
{
//
// This is a large 2M page
//

MmPrint(("! PDE points to large 2M page\n"));

Pte = Pde;
}
else
{
//
// Small 4K page
//

// Get its PTE
Pte = MiGetPteAddressPae(Pointer);
}

MmPrint(("PTE is at 0x%08x\n", Pte));
if( Pte->u.Hard.Valid )
{
MmPrint(("PTE entry is valid, PFN=%08x\n", Pte->u.Hard.PageFrameNumber));

Return = VCS_VALID;
}
else
{
//
// PTE is not valid
//

MMPTE_PAE pte = *Pte;

MmPrint(("Got invalid PTE [%08x%08x]\n", pte.u.Long.HighPart, pte.u.Long.LowPart));

if( pte.u.Long.LowPart == 0 )
{
MmPrint(("PTE entry is completely invalid (page is not committed or is within VAD tree)\n"));
}
else
{
if( pte.u.Soft.Prototype == 1 )
{
MmPrint(("PTE entry is not valid, points to prototype PTE. Protection=%x[%s], ProtoAddress=%x\n",
(ULONG)pte.u.Proto.Protection,
MiPageProtectionString((UCHAR)pte.u.Proto.Protection),
(ULONG)pte.u.Proto.ProtoAddress));

// more accurate check should be performed here for pointed prototype PTE!

Return = VCS_PROTOTYPE;
}
else // not a prototype PTE
{
if( pte.u.Soft.Transition != 0 )
{
//
// This is a transition page.
//

MmPrint(("PTE entry is not valid, points to transition page. PFN=%x, Protection=%x[%s]\n",
(ULONG)pte.u.Trans.PageFrameNumber,
(ULONG)pte.u.Trans.Protection,
MiPageProtectionString((UCHAR)pte.u.Trans.Protection)));

Return = VCS_TRANSITION;
}
else if (pte.u.Soft.PageFileHigh == 0)
{
//
// Demand zero page
//

MmPrint(("PTE entry is not valid, points to demand-zero page. Protection=%x[%s]\n",
(ULONG)pte.u.Soft.Protection,
MiPageProtectionString((UCHAR)pte.u.Soft.Protection)));

Return = VCS_DEMANDZERO;
}
else
{
//
// Pagefile PTE
//

if( pte.u.Soft.Transition == 0 )
{
MmPrint(("PTE entry is not valid, VA is paged out. PageFile Offset=%08x, Protection=%x[%s]\n",
(ULONG)pte.u.Soft.PageFileHigh,
(ULONG)pte.u.Soft.Protection,
MiPageProtectionString((UCHAR)pte.u.Soft.Protection)));

Return = VCS_PAGEDOUT;
}
else
{
MmPrint(("PTE entry is not valid, Refault\n"));
}
}
}
}
}
}
else
{
MmPrint(("PDE entry is not valid\n"));
}

return Return;
}

VALIDITY_CHECK_STATUS
MmIsAddressValidEx(
IN PVOID Pointer
)
{
if( CR4() & PAE_ON ) {
return MmIsAddressValidExPae(Pointer);
}
else {
return MmIsAddressValidExNotPae(Pointer);
}
}


BOOLEAN
MmIsAddressRangeValid(
IN PVOID Address,
IN ULONG Size
)
{
Address = ALIGN_DOWN_POINTER(Address, PAGE_SIZE);
Size = ALIGN_UP(Size, PAGE_SIZE);

for( PVOID Ptr = Address; (ULONG)Ptr < (ULONG)Address + Size; *(ULONG*)&Ptr += PAGE_SIZE )
{
if( MmIsAddressValidEx(Ptr) == VCS_INVALID ) {
return FALSE;
}
}

return TRUE;
}
2010-3-30 09:22
0
雪    币: 6790
活跃值: (4441)
能力值: (RANK:600 )
在线值:
发帖
回帖
粉丝
5
如果只用MmIsAddressValid,他的返回值是boolean类型,无法判断该地址属于一般内存页还是大页,而这个函数可以,这样可以根据页类型,加快内存的搜索的速度。
2010-3-30 09:29
0
雪    币: 6790
活跃值: (4441)
能力值: (RANK:600 )
在线值:
发帖
回帖
粉丝
6
weolar  发的的确很牛,我这个IsValidAddr也是网上搜的,感觉够用了,就没有考虑那么多
总算是引导玉了,呵呵!学习了
2010-3-30 09:35
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
7
回帖是亮点~话说楼主的这个东西已经落后很久了,邪恶人士会把该抹的都抹掉,没有特征~
2010-3-30 12:07
0
雪    币: 6790
活跃值: (4441)
能力值: (RANK:600 )
在线值:
发帖
回帖
粉丝
8
我知道,文中也提到过:"暴搜驱动对象和PE镜像任然不能够检测到通过抹掉驱动对象和抹掉PE头,或者伪造驱动对象和PE头的rootkit"

发这个,当是给个思路参考吧,呵呵,很菜,大牛指教了。
2010-3-30 15:34
0
雪    币: 146
活跃值: (182)
能力值: ( LV13,RANK:220 )
在线值:
发帖
回帖
粉丝
9
搜索完天都黑了,而且dll什么搜不到
2010-6-14 10:28
0
雪    币: 80
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
膜拜~~外国人就是牛
2010-6-14 18:49
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
名字出现乱码的原因一般都是很多人把UnicodeString的Buffer直接当PWCHAR处理了。
一定要记住,UnicodeString没有0结尾,而PWCHAR有。
2010-6-19 12:10
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
膜拜~~膜拜~~
2010-6-19 22:31
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
谢谢分享。。。
2010-6-21 13:19
0
雪    币: 27
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
mark,我正在研究 driverstart
2010-6-22 08:22
0
游客
登录 | 注册 方可回帖
返回
//