能力值:
( LV6,RANK:90 )
2 楼
仔仔细细看完了
不能辜负楼主的一片热忱,
,顶起来
能力值:
( LV3,RANK:20 )
3 楼
其实我一直在疑惑.
这个网上流传的验证地址有效的函数是如何流传起来了.
貌似某些人总讨厌MmIsAddressValid.
可是实际比较MmIsAddressValid和这个函数.做法不是很类似么.都是计算PTE..
能力值:
( 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; }
能力值:
(RANK:600 )
5 楼
如果只用MmIsAddressValid,他的返回值是boolean类型,无法判断该地址属于一般内存页还是大页,而这个函数可以,这样可以根据页类型,加快内存的搜索的速度。
能力值:
(RANK:600 )
6 楼
weolar 发的的确很牛,我这个IsValidAddr也是网上搜的,感觉够用了,就没有考虑那么多
总算是引导玉了,呵呵!学习了
能力值:
( LV9,RANK:610 )
7 楼
回帖是亮点~话说楼主的这个东西已经落后很久了,邪恶人士会把该抹的都抹掉,没有特征~
能力值:
(RANK:600 )
8 楼
我知道,文中也提到过:"暴搜驱动对象和PE镜像任然不能够检测到通过抹掉驱动对象和抹掉PE头,或者伪造驱动对象和PE头的rootkit "
发这个,当是给个思路参考吧,呵呵,很菜,大牛指教了。
能力值:
( LV13,RANK:220 )
9 楼
搜索完天都黑了,而且dll什么搜不到
能力值:
( LV2,RANK:10 )
10 楼
膜拜~~外国人就是牛
能力值:
( LV2,RANK:10 )
11 楼
名字出现乱码的原因一般都是很多人把UnicodeString的Buffer直接当PWCHAR处理了。
一定要记住,UnicodeString没有0结尾,而PWCHAR有。
能力值:
( LV2,RANK:10 )
12 楼
膜拜~~膜拜~~
能力值:
( LV2,RANK:10 )
13 楼
谢谢分享。。。
能力值:
( LV2,RANK:10 )
14 楼
mark,我正在研究 driverstart