├── .gitattributes ├── .gitignore ├── DummeVad.hpp ├── EPROCESS.cpp ├── EPROCESS.h ├── ETHREAD.cpp ├── ETHREAD.h ├── IRQL.hpp ├── Lock.hpp ├── MMVAD_SHORT.cpp ├── MMVAD_SHORT.h ├── MMVAD_SHORT.hpp ├── Singleton.hpp ├── USAGE.CPP ├── Undoc.hpp ├── UndocHolder.h ├── Vad.h ├── VadLock.h ├── VadNode.h └── VadScanner.hpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /DummeVad.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file DummeVad.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __DUMMEVAD_H__ 7 | #define __DUMMEVAD_H__ 8 | 9 | #include "MMVAD_SHORT.hpp" 10 | 11 | #include 12 | #include 13 | 14 | #include "EPROCESS.h" 15 | 16 | class CDummyVad : 17 | public boost::noncopyable 18 | { 19 | public: 20 | CDummyVad() 21 | { 22 | CMMVadShort* dummy_vad = reinterpret_cast(&m_dummyStack); 23 | MMVAD_SHORT* vs = *dummy_vad; 24 | vs->StartingVpn() = NULL; 25 | vs->EndingVpn() = NULL; 26 | //set our decoy 27 | m_vadTree.insert_unique(*reinterpret_cast(m_dummyStack)); 28 | } 29 | 30 | ~CDummyVad() 31 | { 32 | CMMVadShort* dummy_vad = reinterpret_cast(&m_dummyStack); 33 | dummy_vad->MMADDRESS_NODE.right_ = nullptr; 34 | dummy_vad->MMADDRESS_NODE.parent_ = nullptr; 35 | } 36 | 37 | VadTree* operator->() 38 | { 39 | return &m_vadTree; 40 | } 41 | 42 | __checkReturn 43 | void RelinkToVadRoot( 44 | __in const CMMVadShort& vad_root 45 | ) 46 | { 47 | CMMVadShort* dummy_vad = reinterpret_cast(&m_dummyStack); 48 | dummy_vad->MMADDRESS_NODE.right_ = vad_root.MMADDRESS_NODE.right_; 49 | dummy_vad->MMADDRESS_NODE.parent_ = vad_root.MMADDRESS_NODE.parent_; 50 | } 51 | 52 | __checkReturn 53 | bool RelinkToVadRoot() 54 | { 55 | EPROCESS* eprocess = reinterpret_cast(PsGetCurrentProcess()); 56 | CMMVadShort* vad_root = reinterpret_cast(eprocess->VadRoot()); 57 | 58 | if (!vad_root) 59 | return false; 60 | 61 | RelinkToVadRoot(*vad_root); 62 | return true; 63 | } 64 | 65 | private: 66 | void* m_dummyStack[0x10]; 67 | VadTree m_vadTree; 68 | }; 69 | 70 | 71 | #endif //__DUMMEVAD_H__ 72 | -------------------------------------------------------------------------------- /EPROCESS.cpp: -------------------------------------------------------------------------------- 1 | #include "Undoc.hpp" 2 | #include "EPROCESS.h" 3 | 4 | EX_PUSH_LOCK& EPROCESS::AddressCreationLock() 5 | { 6 | return *CUndoc::GetInstance().AddressCreationLock(this); 7 | } 8 | 9 | EX_PUSH_LOCK& EPROCESS::WorkingSetMutex() 10 | { 11 | return *CUndoc::GetInstance().WorkingSetMutex(this); 12 | } 13 | 14 | VM_FLAGS& EPROCESS::Flags() 15 | { 16 | return *CUndoc::GetInstance().Flags(this); 17 | } 18 | 19 | void*& EPROCESS::VadRoot() 20 | { 21 | return *CUndoc::GetInstance().VadRoot(this); 22 | } 23 | -------------------------------------------------------------------------------- /EPROCESS.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file EPROCESS.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __EPROCESS_H__ 7 | #define __EPROCESS_H__ 8 | 9 | #include "UndocHolder.h" 10 | #include "Undoc.hpp" 11 | #include "Vad.h" 12 | //#include "VadNode.h" 13 | //#include "MMVAD_SHORT.hpp" 14 | 15 | struct EPROCESS : 16 | private CUndocHolder 17 | { 18 | EX_PUSH_LOCK& AddressCreationLock(); 19 | EX_PUSH_LOCK& WorkingSetMutex(); 20 | VM_FLAGS& Flags(); 21 | void*& VadRoot(); 22 | }; 23 | 24 | #endif //__EPROCESS_H__ 25 | -------------------------------------------------------------------------------- /ETHREAD.cpp: -------------------------------------------------------------------------------- 1 | #include "Undoc.hpp" 2 | #include "ETHREAD.h" 3 | 4 | SAME_THREAD_APC_FLAGS& ETHREAD::SameThreadApcFlags() 5 | { 6 | return *CUndoc::GetInstance().SameThreadApcFlags(this); 7 | } 8 | -------------------------------------------------------------------------------- /ETHREAD.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file ETHREAD.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __ETHREAD_H__ 7 | #define __ETHREAD_H__ 8 | 9 | #include "UndocHolder.h" 10 | #include "Undoc.hpp" 11 | #include "Vad.h" 12 | 13 | struct ETHREAD : 14 | private CUndocHolder 15 | { 16 | SAME_THREAD_APC_FLAGS& SameThreadApcFlags(); 17 | }; 18 | 19 | #endif //__ETHREAD_H__ 20 | -------------------------------------------------------------------------------- /IRQL.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file IRQL.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __IRQL_H__ 7 | #define __IRQL_H__ 8 | 9 | #include "ntifs.h" 10 | 11 | class CIRQL 12 | { 13 | #define BAD_IRQL 0xFF 14 | 15 | protected: 16 | explicit CIRQL( 17 | KIRQL irqlLevel 18 | ) 19 | { 20 | if (NT_VERIFY(KeGetCurrentIrql() <= irqlLevel)) 21 | KeRaiseIrql(irqlLevel, &m_oldIRQL); 22 | else 23 | m_oldIRQL = BAD_IRQL; 24 | } 25 | public: 26 | ~CIRQL() 27 | { 28 | if (m_oldIRQL != BAD_IRQL) 29 | KeLowerIrql(m_oldIRQL); 30 | } 31 | 32 | __checkReturn 33 | bool IsIrqlRaised() 34 | { 35 | return (m_oldIRQL != BAD_IRQL); 36 | } 37 | 38 | static 39 | __checkReturn 40 | bool SufficienIrql( 41 | __in KIRQL irql 42 | ) 43 | { 44 | return (irql >= KeGetCurrentIrql()); 45 | } 46 | 47 | static 48 | __checkReturn 49 | bool RunsOnPassiveLvl() 50 | { 51 | return (PASSIVE_LEVEL == KeGetCurrentIrql()); 52 | } 53 | 54 | static 55 | __checkReturn 56 | bool RunsOnApcLvl() 57 | { 58 | return (APC_LEVEL == KeGetCurrentIrql()); 59 | } 60 | 61 | static 62 | __checkReturn 63 | bool RunsOnDispatchLvl() 64 | { 65 | return (DISPATCH_LEVEL == KeGetCurrentIrql()); 66 | } 67 | 68 | protected: 69 | KIRQL m_oldIRQL; 70 | }; 71 | 72 | class CDispatchLvl : public CIRQL 73 | { 74 | public: 75 | CDispatchLvl() : CIRQL(DISPATCH_LEVEL) 76 | { 77 | } 78 | }; 79 | 80 | class CApcLvl : public CIRQL 81 | { 82 | public: 83 | CApcLvl() : CIRQL(APC_LEVEL) 84 | { 85 | } 86 | }; 87 | 88 | #endif //__IRQL_H__ 89 | -------------------------------------------------------------------------------- /Lock.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Lock.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __LOCK_H__ 7 | #define __LOCK_H__ 8 | 9 | #include "IRQL.hpp" 10 | 11 | #include "fltKernel.h" 12 | 13 | //----------------------------------------------------------- 14 | // ****************** GENERIC LOCK CLASSES ****************** 15 | //----------------------------------------------------------- 16 | 17 | /* 18 | #CAutoLock usage : 19 | 20 | 1) CAutoLock 21 | 2) CAutoLock 22 | */ 23 | 24 | template 25 | class CAutoLock 26 | { 27 | public: 28 | //LOCK of type CLockHolder 29 | CAutoLock( 30 | __inout LOCK& lock 31 | ) : m_lock(lock) 32 | { 33 | m_lock.Lock(); 34 | } 35 | //LOCK of type TLOCK in CLockWorker's & CLockHolder's 36 | CAutoLock( 37 | __inout LOCK* lock 38 | ) : m_lock(lock) 39 | { 40 | m_lock.Lock(); 41 | } 42 | 43 | ~CAutoLock() 44 | { 45 | m_lock.Unlock(); 46 | } 47 | 48 | private: 49 | CAutoLock(const CAutoLock&); 50 | void operator=(const CAutoLock&); 51 | 52 | protected: 53 | WORKER m_lock; 54 | }; 55 | 56 | template 57 | class CLockWorker 58 | { 59 | protected: 60 | explicit CLockWorker( 61 | __inout TLOCK* lock 62 | ) : m_tLock(lock) 63 | { 64 | } 65 | 66 | private: 67 | CLockWorker(const CLockWorker&); 68 | void operator=(const CLockWorker&); 69 | 70 | protected: 71 | TLOCK* m_tLock; 72 | }; 73 | 74 | template 75 | class CLockHolder 76 | { 77 | protected: 78 | explicit CLockHolder() 79 | { 80 | } 81 | 82 | public: 83 | TLOCK* operator&() 84 | { 85 | return &m_tInitLock; 86 | } 87 | 88 | private: 89 | CLockHolder(const CLockHolder&); 90 | void operator=(const CLockHolder&); 91 | 92 | protected: 93 | TLOCK m_tInitLock; 94 | }; 95 | 96 | 97 | //----------------------------------------------------------------------- 98 | // ****************** FAST MUTEX;IRQL < DISPATCH_LEVEL ****************** 99 | //----------------------------------------------------------------------- 100 | 101 | class CFastLock : 102 | public CLockHolder 103 | { 104 | public: 105 | CFastLock() 106 | { 107 | ExInitializeFastMutex(&m_tInitLock); 108 | } 109 | }; 110 | 111 | class CFastLockWorker : 112 | protected CLockWorker 113 | { 114 | public: 115 | CFastLockWorker( 116 | __inout CFastLock& lock 117 | ) : CLockWorker(&lock) 118 | { 119 | } 120 | 121 | CFastLockWorker( 122 | __inout FAST_MUTEX* lock 123 | ) : CLockWorker(lock) 124 | { 125 | } 126 | 127 | _IRQL_requires_max_(APC_LEVEL) 128 | void Lock() 129 | { 130 | ExAcquireFastMutex(m_tLock); 131 | } 132 | 133 | _IRQL_requires_max_(APC_LEVEL) 134 | void Unlock() 135 | { 136 | ExReleaseFastMutex(m_tLock); 137 | } 138 | }; 139 | 140 | //------------------------------------------------------------------------------ 141 | // ****************** FAST RESOURCES LOCK; SHARED & EXCLUSIVE ****************** 142 | //------------------------------------------------------------------------------ 143 | 144 | class CRsrcFastLock : 145 | public CLockHolder 146 | { 147 | public: 148 | CRsrcFastLock() 149 | { 150 | FltInitializePushLock(&m_tInitLock); 151 | } 152 | }; 153 | 154 | class CResourceLockWorker : 155 | public CLockWorker 156 | { 157 | public: 158 | CResourceLockWorker( 159 | __inout EX_PUSH_LOCK* lock 160 | ) : CLockWorker(lock) 161 | { 162 | } 163 | 164 | _IRQL_requires_max_(APC_LEVEL) 165 | void Unlock() 166 | { 167 | FltReleasePushLock(m_tLock); 168 | } 169 | }; 170 | 171 | class CExclusiveLockWorker : 172 | public CResourceLockWorker 173 | { 174 | public: 175 | CExclusiveLockWorker( 176 | __inout CRsrcFastLock& lock 177 | ) : CResourceLockWorker(&lock) 178 | { 179 | } 180 | 181 | CExclusiveLockWorker( 182 | __inout EX_PUSH_LOCK* lock 183 | ) : CResourceLockWorker(lock) 184 | { 185 | } 186 | 187 | _IRQL_requires_max_(APC_LEVEL) 188 | void Lock() 189 | { 190 | FltAcquirePushLockExclusive(m_tLock); 191 | } 192 | }; 193 | 194 | class CSharedLockWorker : 195 | public CResourceLockWorker 196 | { 197 | public: 198 | CSharedLockWorker( 199 | __inout CRsrcFastLock& lock 200 | ) : CResourceLockWorker(&lock) 201 | { 202 | } 203 | 204 | CSharedLockWorker( 205 | __inout EX_PUSH_LOCK* lock 206 | ) : CResourceLockWorker(lock) 207 | { 208 | } 209 | 210 | _IRQL_requires_max_(APC_LEVEL) 211 | void Lock() 212 | { 213 | FltAcquirePushLockShared(m_tLock); 214 | } 215 | }; 216 | 217 | //------------------------------------------------ 218 | // ****************** SPIN LOCK ****************** 219 | //------------------------------------------------ 220 | 221 | class CSpinLock : 222 | public CLockHolder 223 | { 224 | public: 225 | CSpinLock() 226 | { 227 | KeInitializeSpinLock(&m_tInitLock); 228 | } 229 | }; 230 | 231 | class CSpinLockWorker : 232 | public CLockWorker 233 | { 234 | public: 235 | CSpinLockWorker( 236 | __inout CSpinLock& lock 237 | ) : CLockWorker(&lock) 238 | { 239 | } 240 | 241 | CSpinLockWorker( 242 | __inout KSPIN_LOCK* lock 243 | ) : CLockWorker(lock) 244 | { 245 | } 246 | 247 | _IRQL_requires_max_(DISPATCH_LEVEL) 248 | void Lock() 249 | { 250 | if (CIRQL::RunsOnDispatchLvl()) 251 | KeAcquireInStackQueuedSpinLockAtDpcLevel(m_tLock, &m_qhandle); 252 | else 253 | KeAcquireInStackQueuedSpinLock(m_tLock, &m_qhandle); 254 | } 255 | 256 | _IRQL_requires_max_(DISPATCH_LEVEL) 257 | void Unlock() 258 | { 259 | if (DISPATCH_LEVEL == m_qhandle.OldIrql) 260 | KeReleaseInStackQueuedSpinLockFromDpcLevel(&m_qhandle); 261 | else 262 | KeReleaseInStackQueuedSpinLock(&m_qhandle); 263 | } 264 | 265 | protected: 266 | KLOCK_QUEUE_HANDLE m_qhandle; 267 | }; 268 | 269 | #endif //__LOCK_H__ 270 | -------------------------------------------------------------------------------- /MMVAD_SHORT.cpp: -------------------------------------------------------------------------------- 1 | #include "MMVAD_SHORT.h" 2 | #include "Undoc.hpp" 3 | 4 | ULONG_PTR& MMVAD_SHORT::StartingVpn() 5 | { 6 | return *CUndoc::GetInstance().StartingVpn(this); 7 | } 8 | 9 | ULONG_PTR& MMVAD_SHORT::EndingVpn() 10 | { 11 | return *CUndoc::GetInstance().EndingVpn(this); 12 | } 13 | 14 | ULONG_PTR& MMVAD_SHORT::Flags() 15 | { 16 | return *CUndoc::GetInstance().Flags(this); 17 | } 18 | 19 | EX_PUSH_LOCK& MMVAD_SHORT::PushLock() 20 | { 21 | return *CUndoc::GetInstance().PushLock(this); 22 | } 23 | -------------------------------------------------------------------------------- /MMVAD_SHORT.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file MMVAD_SHORT.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __MMVAD_SHORT_H__ 7 | #define __MMVAD_SHORT_H__ 8 | 9 | #include "UndocHolder.h" 10 | 11 | struct MMVAD_SHORT : 12 | private CUndocHolder 13 | { 14 | ULONG_PTR& StartingVpn(); 15 | ULONG_PTR& EndingVpn(); 16 | ULONG_PTR& Flags(); 17 | EX_PUSH_LOCK& PushLock(); 18 | }; 19 | 20 | #endif //__MMVAD_SHORT_H__ 21 | -------------------------------------------------------------------------------- /MMVAD_SHORT.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file MMVAD_SHORT.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __MMVAD_SHORT_EXTENDED_H__ 7 | #define __MMVAD_SHORT_EXTENDED_H__ 8 | 9 | #include "MMVAD_SHORT.h" 10 | 11 | #include 12 | 13 | using namespace boost::intrusive; 14 | 15 | #define EXPAND(addr) reinterpret_cast(static_cast(addr) << PAGE_SHIFT) 16 | 17 | struct CMMVadShort : 18 | private MMVAD_SHORT 19 | { 20 | public: 21 | avl_set_member_hook< optimize_size > MMADDRESS_NODE; 22 | 23 | operator MMVAD_SHORT*() 24 | { 25 | return this; 26 | } // implicit conversion to MMVAD_SHORT* 27 | 28 | MMVAD_SHORT* operator->() 29 | { 30 | return this; 31 | } // implicit conversion to MMVAD_SHORT* 32 | 33 | friend bool operator<( 34 | __in const CMMVadShort& a, 35 | __in const CMMVadShort& b 36 | ) 37 | { 38 | CRange ar(((CMMVadShort&)a).StartingVpn(), ((CMMVadShort&)a).EndingVpn()); 39 | CRange br(((CMMVadShort&)b).StartingVpn(), ((CMMVadShort&)b).EndingVpn()); 40 | return (ar < br); 41 | } 42 | }; 43 | 44 | struct CMMVadShortCmp 45 | { 46 | bool operator()( 47 | __in const CRange &range, 48 | __in const CMMVadShort &vad 49 | ) const 50 | { 51 | MMVAD_SHORT* vs = ((CMMVadShort&)vad); 52 | CRange vad_range(EXPAND(vs->StartingVpn()), EXPAND(vs->EndingVpn())); 53 | return (range < vad_range); 54 | } 55 | 56 | bool operator()( 57 | __in const CMMVadShort &vad, 58 | __in const CRange &range 59 | ) const 60 | { 61 | MMVAD_SHORT* vs = ((CMMVadShort&)vad); 62 | CRange vad_range(EXPAND(vs->StartingVpn()), EXPAND(vs->EndingVpn())); 63 | return (vad_range < range); 64 | } 65 | }; 66 | 67 | typedef member_hook< CMMVadShort, avl_set_member_hook< optimize_size >, &CMMVadShort::MMADDRESS_NODE > VadMemberOption; 68 | typedef avltree< CMMVadShort, VadMemberOption > VadTree; 69 | 70 | #endif //__MMVAD_SHORT_EXTENDED_H__ 71 | -------------------------------------------------------------------------------- /Singleton.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Singleton.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __SINGLETON_H__ 7 | #define __SINGLETON_H__ 8 | 9 | /* 10 | # CSingleton usage : 11 | 12 | class CClass : 13 | public CSingleton 14 | { 15 | static CClass m_instance; 16 | CClass(...) : CSingleton(m_instance) 17 | { 18 | } 19 | public: 20 | } 21 | 22 | CClass CClass::m_instance; 23 | */ 24 | 25 | template 26 | class CSingleton 27 | { 28 | CSingleton(const CSingleton&);// = delete; 29 | void operator=(CSingleton const&);// = delete; 30 | static TYPE* m_instancePtr; 31 | public: 32 | static 33 | TYPE& GetInstance() 34 | { 35 | return *m_instancePtr; 36 | } 37 | 38 | protected: 39 | CSingleton( 40 | __in TYPE& staticInstance 41 | ) 42 | { 43 | m_instancePtr = &staticInstance; 44 | } 45 | }; 46 | 47 | template 48 | TYPE* CSingleton::m_instancePtr = NULL; 49 | 50 | #endif //__SINGLETON_H__ 51 | -------------------------------------------------------------------------------- /USAGE.CPP: -------------------------------------------------------------------------------- 1 | EPROCESS* eprocess = reinterpret_cast(PsGetCurrentProcess()); 2 | 3 | VadTree::iterator it; 4 | 5 | CMMVadShort* vad_root = reinterpret_cast(eprocess->VadRoot()); 6 | it->MMADDRESS_NODE.right_ = vad_root->MMADDRESS_NODE.right_; 7 | it->MMADDRESS_NODE.parent_ = vad_root->MMADDRESS_NODE.parent_; 8 | 9 | for (int i = 0; i < 0x10; i++) 10 | { 11 | MMVAD_SHORT* vad = *(++it); 12 | DbgPrint("\n%p %i %p %p %p %p\n", it, i, vad->StartingVpn(), vad->EndingVpn(), &vad->StartingVpn()); 13 | } 14 | 15 | 16 | 17 | //NEW USAGE!! 18 | CRange mem(nullptr); 19 | if (CVAdScanner::GetMemory((void*)0x77000000, &mem)) 20 | { 21 | DbgPrint("\nfound memory : %p %p\n", mem.Begin(), mem.End()); 22 | 23 | std::shared_ptr sp_vad_node; 24 | if (!CVAdScanner::Find(mem, &sp_vad_node)) 25 | return; 26 | 27 | for (int i = 0; i < 0x10; i++) 28 | { 29 | ++(*sp_vad_node.get()); 30 | DbgPrint("\na. %p ITERATE : %p %p\n", sp_vad_node.get(), sp_vad_node->Begin(), sp_vad_node->End()); 31 | } 32 | } -------------------------------------------------------------------------------- /Undoc.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Undoc.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __UNDOC_H__ 7 | #define __UNDOC_H__ 8 | 9 | #include "ntifs.h" 10 | #include "Singleton.hpp" 11 | 12 | #include "MMVAD_SHORT.h" 13 | #include "ETHREAD.h" 14 | #include "EPROCESS.h" 15 | 16 | struct OS_CONSTANTS 17 | { 18 | size_t MMVAD_SHORT_StartingVpn; 19 | size_t MMVAD_SHORT_EndingVpn; 20 | size_t MMVAD_SHORT_Flags;//MMVAD_SHORT.u1 21 | size_t MMVAD_SHORT_PushLock; 22 | 23 | size_t ETHREAD_SameThreadApcFlags; 24 | 25 | size_t EPROCESS_AddressCreationLock; 26 | size_t EPROCESS_WorkingSetMutex;//EPROCESS.Vm.WorkingSetMutex 27 | size_t EPROCESS_Flags;//EPROCESS.Flags, included VmDeleted, ... 28 | size_t EPROCESS_VadRoot; 29 | }; 30 | 31 | class CUndoc : 32 | public CSingleton 33 | { 34 | static CUndoc m_instance; 35 | CUndoc() : 36 | CSingleton(m_instance) 37 | { 38 | } 39 | #define UNDOC_MEMBER(addr, type, member_offset) reinterpret_cast(reinterpret_cast(addr) + (member_offset)) 40 | public: 41 | ULONG_PTR* StartingVpn( 42 | __in const MMVAD_SHORT* vad 43 | ) 44 | { 45 | return UNDOC_MEMBER(vad, ULONG_PTR, m_sConsts.MMVAD_SHORT_StartingVpn); 46 | } 47 | 48 | ULONG_PTR* EndingVpn( 49 | __in MMVAD_SHORT const* vad 50 | ) 51 | { 52 | return UNDOC_MEMBER(vad, ULONG_PTR, m_sConsts.MMVAD_SHORT_EndingVpn); 53 | } 54 | 55 | ULONG_PTR* Flags( 56 | __in MMVAD_SHORT const* vad 57 | ) 58 | { 59 | return UNDOC_MEMBER(vad, ULONG_PTR, m_sConsts.MMVAD_SHORT_Flags); 60 | } 61 | 62 | EX_PUSH_LOCK* PushLock( 63 | __in MMVAD_SHORT const* vad 64 | ) 65 | { 66 | return UNDOC_MEMBER(vad, EX_PUSH_LOCK, m_sConsts.MMVAD_SHORT_PushLock); 67 | } 68 | 69 | SAME_THREAD_APC_FLAGS* SameThreadApcFlags( 70 | __in ETHREAD const* ethread 71 | ) 72 | { 73 | return UNDOC_MEMBER(ethread, SAME_THREAD_APC_FLAGS, m_sConsts.ETHREAD_SameThreadApcFlags); 74 | } 75 | 76 | EX_PUSH_LOCK* AddressCreationLock( 77 | __in EPROCESS* eproc 78 | ) 79 | { 80 | return UNDOC_MEMBER(eproc, EX_PUSH_LOCK, m_sConsts.EPROCESS_AddressCreationLock); 81 | } 82 | 83 | EX_PUSH_LOCK* WorkingSetMutex( 84 | __in EPROCESS const* eproc 85 | ) 86 | { 87 | return UNDOC_MEMBER(eproc, EX_PUSH_LOCK, m_sConsts.EPROCESS_WorkingSetMutex); 88 | } 89 | 90 | VM_FLAGS* Flags( 91 | __in EPROCESS const* eproc 92 | ) 93 | { 94 | return UNDOC_MEMBER(eproc, VM_FLAGS, m_sConsts.EPROCESS_Flags); 95 | } 96 | 97 | /*CMMVadShort**/void** VadRoot( 98 | __in EPROCESS const* eproc 99 | ) 100 | { 101 | return UNDOC_MEMBER(eproc, /*CMMVadShort*/void*, m_sConsts.EPROCESS_VadRoot); 102 | } 103 | 104 | private: 105 | static OS_CONSTANTS m_sConsts; 106 | }; 107 | 108 | __declspec(selectany) CUndoc CUndoc::m_instance; 109 | __declspec(selectany) OS_CONSTANTS CUndoc::m_sConsts = { 0x018, 0x020, 0x028, 0x038, 0x450, 0x218, 0x390, 0x438, 0x448 }; //win7 x64, sp? 110 | 111 | #endif //__UNDOC_H__ 112 | -------------------------------------------------------------------------------- /UndocHolder.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file UndocHolder.h 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __UNDOCHOLDER_H__ 7 | #define __UNDOCHOLDER_H__ 8 | 9 | #include "ntifs.h" 10 | 11 | class CUndocHolder 12 | { 13 | CUndocHolder(); 14 | CUndocHolder(const CUndocHolder&); 15 | void operator=(const CUndocHolder&); 16 | }; 17 | 18 | #endif //__UNDOCHOLDER_H__ 19 | -------------------------------------------------------------------------------- /Vad.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Vad.h 3 | * @author created by: Peter Hlavaty 4 | * 5 | * Variables not likely to change, seems to be 'safe' to implement it 6 | * 7 | */ 8 | 9 | #ifndef __VAD_H__ 10 | #define __VAD_H__ 11 | 12 | #include "ntifs.h" 13 | 14 | typedef void* MM_AVL_TABLE; 15 | 16 | #pragma pack(push, 1) 17 | 18 | struct SAME_THREAD_APC_FLAGS 19 | { 20 | struct 21 | { 22 | UCHAR Spare : 1; 23 | UCHAR StartAddressInvalid : 1; 24 | UCHAR EtwCalloutActive : 1; 25 | UCHAR OwnsProcessWorkingSetExclusive : 1; 26 | UCHAR OwnsProcessWorkingSetShared : 1; 27 | UCHAR OwnsSystemCacheWorkingSetExclusive : 1; 28 | UCHAR OwnsSystemCacheWorkingSetShared : 1; 29 | UCHAR OwnsSessionWorkingSetExclusive : 1; 30 | }; 31 | struct 32 | { 33 | UCHAR OwnsSessionWorkingSetShared : 1; 34 | UCHAR OwnsProcessAddressSpaceExclusive : 1; 35 | UCHAR OwnsProcessAddressSpaceShared : 1; 36 | UCHAR SuppressSymbolLoad : 1; 37 | UCHAR Prefetching : 1; 38 | UCHAR OwnsVadExclusive : 1; 39 | UCHAR OwnsChangeControlAreaExclusive : 1; 40 | UCHAR OwnsChangeControlAreaShared : 1; 41 | }; 42 | }; 43 | 44 | struct VM_FLAGS 45 | { 46 | ULONG CreateReported : 1; 47 | ULONG NoDebugInherit : 1; 48 | ULONG ProcessExiting : 1; 49 | ULONG ProcessDelete : 1; 50 | ULONG Wow64SplitPages : 1; 51 | ULONG VmDeleted : 1; 52 | ULONG OutswapEnabled : 1; 53 | ULONG Outswapped : 1; 54 | ULONG ForkFailed : 1; 55 | ULONG Wow64VaSpace4Gb : 1; 56 | ULONG AddressSpaceInitialized : 1; 57 | ULONG SetTimerResolution : 1; 58 | ULONG BreakOnTermination : 1; 59 | ULONG DeprioritizeViews : 1; 60 | ULONG WriteWatch : 1; 61 | ULONG ProcessInSession : 1; 62 | ULONG OverrideAddressSpace : 1; 63 | ULONG HasAddressSpace : 1; 64 | ULONG LaunchPrefetched : 1; 65 | ULONG Background : 1; 66 | ULONG VmTopDown : 1; 67 | ULONG ImageNotifyDone : 1; 68 | ULONG PdeUpdateNeeded : 1; 69 | ULONG VdmAllowed : 1; 70 | ULONG CrossSessionCreate : 1; 71 | ULONG ProcessInserted : 1; 72 | ULONG DefaultIoPriority : 1; 73 | ULONG ProcessSelfDelete : 1; 74 | ULONG SetTimerResolutionLink : 1; 75 | }; 76 | 77 | struct MMVAD_FLAGS 78 | { 79 | union 80 | { 81 | ULONG UFlags; 82 | struct 83 | { 84 | ULONG VadType : 3; 85 | ULONG Protection : 5; 86 | ULONG PreferredNode : 6; 87 | ULONG NoChange : 1; 88 | ULONG PrivateMemory : 1; 89 | ULONG Teb : 1; 90 | ULONG PrivateFixup : 1; 91 | ULONG Spare : 13; 92 | ULONG DeleteInProgress : 1; 93 | }; 94 | }; 95 | }; 96 | 97 | #pragma pack(pop) 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /VadLock.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file VadHelper.h 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __VADHELPER_H__ 7 | #define __VADHELPER_H__ 8 | 9 | #include "ntifs.h" 10 | 11 | #include "Vad.h" 12 | #include "Lock.hpp" 13 | 14 | //------------------------------------------------------------------ 15 | // ****************** VAD_ROOT ADDRESS SPACE LOCK ****************** 16 | //------------------------------------------------------------------ 17 | 18 | template 19 | class CVADLock 20 | { 21 | public: 22 | CVADLock() : 23 | m_addressSpaceLock(&reinterpret_cast(PsGetCurrentProcess())->AddressCreationLock()), 24 | m_workingSetLock(&reinterpret_cast(PsGetCurrentProcess())->WorkingSetMutex()), 25 | m_locked(false) 26 | { 27 | ETHREAD* ethread = reinterpret_cast(PsGetCurrentThread()); 28 | ethread->SameThreadApcFlags().OwnsProcessAddressSpaceExclusive = TRUE; 29 | m_addressSpaceLock.Lock(); 30 | 31 | EPROCESS* eprocess = reinterpret_cast(PsGetCurrentProcess()); 32 | if (eprocess->Flags().VmDeleted) 33 | return; 34 | 35 | m_locked = true; 36 | ethread->SameThreadApcFlags().OwnsProcessWorkingSetExclusive = TRUE; 37 | m_workingSetLock.Lock(); 38 | } 39 | 40 | ~CVADLock() 41 | { 42 | ETHREAD* ethread = reinterpret_cast(PsGetCurrentThread()); 43 | if (m_locked) 44 | { 45 | m_workingSetLock.Unlock(); 46 | ethread->SameThreadApcFlags().OwnsProcessWorkingSetExclusive = FALSE; 47 | } 48 | 49 | m_addressSpaceLock.Unlock(); 50 | ethread->SameThreadApcFlags().OwnsProcessAddressSpaceExclusive = FALSE; 51 | } 52 | 53 | __checkReturn 54 | bool IsLocked() 55 | { 56 | return m_locked; 57 | } 58 | 59 | protected: 60 | bool m_locked; 61 | 62 | WORKER m_addressSpaceLock; 63 | CExclusiveLockWorker m_workingSetLock; 64 | }; 65 | 66 | class CVADScanLock : 67 | public CVADLock 68 | { 69 | public: 70 | CVADScanLock() : 71 | CVADLock() 72 | { 73 | } 74 | }; 75 | 76 | class CVADWriteLock : 77 | public CVADLock 78 | { 79 | public: 80 | CVADWriteLock() : 81 | CVADLock() 82 | { 83 | } 84 | }; 85 | 86 | #endif //__VADHELPER_H__ 87 | -------------------------------------------------------------------------------- /VadNode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file VADWalker.h 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __VADWALKER_H__ 7 | #define __VADWALKER_H__ 8 | 9 | #include "ntifs.h" 10 | #include "Range.h" 11 | #include "Lock.hpp" 12 | 13 | #include "MMVAD_SHORT.h" 14 | 15 | #include "VadLock.h" 16 | #include "DummeVad.hpp" 17 | #include "MMVAD_SHORT.hpp" 18 | #include 19 | 20 | //------------------------------------------------------------ 21 | // ****************** VAD_NODE MEMORY RANGE ****************** 22 | //------------------------------------------------------------ 23 | 24 | class CVadNode : 25 | public boost::noncopyable, 26 | private CSharedLockWorker 27 | { 28 | public: 29 | CVadNode( 30 | __in CMMVadShort& vadNode 31 | ) : m_vad(&vadNode), 32 | CSharedLockWorker(&(vadNode->PushLock())) 33 | { 34 | Lock(); 35 | } 36 | 37 | ~CVadNode() 38 | { 39 | Unlock(); 40 | } 41 | 42 | const MMVAD_SHORT* operator->() const 43 | { 44 | return *m_vad; 45 | } 46 | 47 | CVadNode* operator++() 48 | { 49 | //implement with locking 50 | return this; 51 | } 52 | 53 | void* Begin() 54 | { 55 | return EXPAND((*m_vad)->StartingVpn()); 56 | } 57 | void* End() 58 | { 59 | return EXPAND((*m_vad)->EndingVpn()) - 1; 60 | } 61 | 62 | private: 63 | CMMVadShort* m_vad; 64 | }; 65 | 66 | #endif //__VADWALKER_H__ 67 | -------------------------------------------------------------------------------- /VadScanner.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file VadScanner.hpp 3 | * @author created by: Peter Hlavaty 4 | */ 5 | 6 | #ifndef __VADSCANNER_H__ 7 | #define __VADSCANNER_H__ 8 | 9 | #include "Lock.hpp" 10 | #include "VadNode.h" 11 | #include "VadLock.h" 12 | #include "MMVAD_SHORT.hpp" 13 | #include "DummeVad.hpp" 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | class CVAdScanner : 21 | public boost::noncopyable 22 | { 23 | public: 24 | static 25 | __checkReturn 26 | bool Contains( 27 | __in const CRange& mem 28 | ) 29 | { 30 | CDummyVad dummy_vad; 31 | 32 | CVADLock lock; 33 | if (!lock.IsLocked()) 34 | return false; 35 | 36 | if (!dummy_vad.RelinkToVadRoot()) 37 | return false; 38 | 39 | VadTree::iterator it = dummy_vad->find(mem, CMMVadShortCmp()); 40 | return it != dummy_vad->end(); 41 | } 42 | 43 | static 44 | __checkReturn 45 | bool GetMemory( 46 | __in const CRange& mem, 47 | __inout CRange* out 48 | ) 49 | { 50 | CDummyVad dummy_vad; 51 | 52 | CVADLock lock; 53 | if (!lock.IsLocked()) 54 | return false; 55 | 56 | if (!dummy_vad.RelinkToVadRoot()) 57 | return false; 58 | 59 | VadTree::iterator it = dummy_vad->find(mem, CMMVadShortCmp()); 60 | if (dummy_vad->end() == it) 61 | return false; 62 | 63 | MMVAD_SHORT* vad = *it; 64 | out->Begin() = EXPAND(vad->StartingVpn()); 65 | out->End() = EXPAND(vad->EndingVpn()) - 1; 66 | return true; 67 | } 68 | 69 | static 70 | __checkReturn 71 | bool Find( 72 | __in const CRange& mem, 73 | __inout std::shared_ptr* out 74 | ) 75 | { 76 | CDummyVad dummy_vad; 77 | 78 | CVadNode* out_vadnode = nullptr; 79 | 80 | { 81 | CVADLock lock; 82 | if (!lock.IsLocked()) 83 | return false; 84 | 85 | if (!dummy_vad.RelinkToVadRoot()) 86 | return false; 87 | 88 | VadTree::iterator it = dummy_vad->find(mem, CMMVadShortCmp()); 89 | if (dummy_vad->end() == it) 90 | return false; 91 | MMVAD_SHORT* c_mmvad = *it; 92 | out_vadnode = new CVadNode(*it); 93 | } 94 | 95 | //outside of spinlock playing with std::shared_ptr 96 | if (!out_vadnode) 97 | return false; 98 | 99 | *out = std::shared_ptr(out_vadnode); 100 | return true; 101 | } 102 | }; 103 | 104 | #endif //__VADSCANNER_H__ 105 | --------------------------------------------------------------------------------