FindDllByVad遍歷dll文件

vadRoot結構好像中有在sp2系統下有效,在sp3系統下調試時,會在遍歷avl樹的操作時藍屏...


驅動層:

.h

/*

  FindDllByVad.H

  Author: <your name>
  Last Updated: 2007-07-06

  This framework is generated by EasySYS 0.3.0
  This template file is copying from QuickSYS 0.3.0 written by Chunhua Liu
  
 //=============================================
  Modify by PLK_XiaoWei[0GiNr]
  http://www.0GiNr.com
  //=============================================
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif 

//#include "ioctls.h"


//#include <ntifs.h>

#ifndef _FINDDLLBYVAD_H
#define _FINDDLLBYVAD_H 1
//============================================
#define DEVICE_NAME L"\\Device\\devFindDllByVad1" //Driver Name
#define LINK_NAME L"\\DosDevices\\FindDllByVad1"  //Link Name
//============================================
#define IOCTL_BASE	0x800

#define MY_CTL_CODE(i) \
	CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_HELLO	MY_CTL_CODE(1)
//============================================

#define dprintf if (DBG) DbgPrint
#define nprintf DbgPrint

#define kmalloc(_s)	ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSQ')
//#define kfree(_p)	ExFreePoolWithTag(_p, 'SYSQ')
#define kfree(_p)	ExFreePool(_p)



typedef struct _EX_PUSH_LOCK {
	
	//
	// LOCK bit is set for both exclusive and shared acquires
	//
#define EX_PUSH_LOCK_LOCK_V          ((ULONG_PTR)0x0)
#define EX_PUSH_LOCK_LOCK            ((ULONG_PTR)0x1)
	
	//
	// Waiting bit designates that the pointer has chained waiters
	//
	
#define EX_PUSH_LOCK_WAITING         ((ULONG_PTR)0x2)
	
	//
	// Waking bit designates that we are either traversing the list
	// to wake threads or optimizing the list
	//
	
#define EX_PUSH_LOCK_WAKING          ((ULONG_PTR)0x4)
	
	//
	// Set if the lock is held shared by multiple owners and there are waiters
	//
	
#define EX_PUSH_LOCK_MULTIPLE_SHARED ((ULONG_PTR)0x8)
	
	//
	// Total shared Acquires are incremented using this
	//
#define EX_PUSH_LOCK_SHARE_INC       ((ULONG_PTR)0x10)
#define EX_PUSH_LOCK_PTR_BITS        ((ULONG_PTR)0xf)
	
    union {
        struct {
            ULONG_PTR Locked         : 1;
            ULONG_PTR Waiting        : 1;
            ULONG_PTR Waking         : 1;
            ULONG_PTR MultipleShared : 1;
            ULONG_PTR Shared         : sizeof (ULONG_PTR) * 8 - 4;
        };
        ULONG_PTR Value;
        PVOID Ptr;
    };
} EX_PUSH_LOCK, *PEX_PUSH_LOCK;

//
// Rundown protection structure
//
// typedef struct _EX_RUNDOWN_REF {
// 	
// #define EX_RUNDOWN_ACTIVE      0x1
// #define EX_RUNDOWN_COUNT_SHIFT 0x1
// #define EX_RUNDOWN_COUNT_INC   (1<<EX_RUNDOWN_COUNT_SHIFT)
//     union {
//         ULONG_PTR Count;
//         PVOID Ptr;
//     };
// } EX_RUNDOWN_REF, *PEX_RUNDOWN_REF;

//
// Fast reference routines. See ntos\ob\fastref.c for algorithm description.
//
#if defined (_WIN64)
#define MAX_FAST_REFS 15
#else
#define MAX_FAST_REFS 7
#endif

typedef struct _EX_FAST_REF {
    union {
        PVOID Object;
#if defined (_WIN64)
        ULONG_PTR RefCnt : 4;
#else
        ULONG_PTR RefCnt : 3;
#endif
        ULONG_PTR Value;
    };
} EX_FAST_REF, *PEX_FAST_REF;

//
//  One handle table exists per process.  Unless otherwise specified, via a
//  call to RemoveHandleTable, all handle tables are linked together in a
//  global list.  This list is used by the snapshot handle tables call.
//


typedef struct _HANDLE_TABLE {

    //
    //  A pointer to the top level handle table tree node.
    //

    ULONG_PTR TableCode;

    //
    //  The process who is being charged quota for this handle table and a
    //  unique process id to use in our callbacks
    //

    struct _EPROCESS *QuotaProcess;
    HANDLE UniqueProcessId;


    //
    // These locks are used for table expansion and preventing the A-B-A problem
    // on handle allocate.
    //

#define HANDLE_TABLE_LOCKS 4

    EX_PUSH_LOCK HandleTableLock[HANDLE_TABLE_LOCKS];

    //
    //  The list of global handle tables.  This field is protected by a global
    //  lock.
    //

    LIST_ENTRY HandleTableList;

    //
    // Define a field to block on if a handle is found locked.
    //
    EX_PUSH_LOCK HandleContentionEvent;

    //
    // Debug info. Only allocated if we are debugging handles
    //
    PVOID DebugInfo;

    //
    //  The number of pages for additional info.
    //  This counter is used to improve the performance
    //  in ExGetHandleInfo
    //
    LONG ExtraInfoPages;

    //
    //  This is a singly linked list of free table entries.  We don't actually
    //  use pointers, but have each store the index of the next free entry
    //  in the list.  The list is managed as a lifo list.  We also keep track
    //  of the next index that we have to allocate pool to hold.
    //

    ULONG FirstFree;

    //
    // We free handles to this list when handle debugging is on or if we see
    // that a thread has this handles bucket lock held. The allows us to delay reuse
    // of handles to get a better chance of catching offenders
    //

    ULONG LastFree;

    //
    // This is the next handle index needing a pool allocation. Its also used as a bound
    // for good handles.
    //

    ULONG NextHandleNeedingPool;

    //
    //  The number of handle table entries in use.
    //

    LONG HandleCount;

    //
    // Define a flags field
    //
    union {
        ULONG Flags;

        //
        // For optimization we reuse handle values quickly. This can be a problem for
        // some usages of handles and makes debugging a little harder. If this
        // bit is set then we always use FIFO handle allocation.
        //
        BOOLEAN StrictFIFO : 1;
    };

} HANDLE_TABLE, *PHANDLE_TABLE;

typedef struct _HANDLE_TABLE_ENTRY {
	
    //
    //  The pointer to the object overloaded with three ob attributes bits in
    //  the lower order and the high bit to denote locked or unlocked entries
    //
	
    union {
		
        PVOID Object;
		
        ULONG ObAttributes;
		
        PVOID InfoTable;
		
        ULONG_PTR Value;
    };
	
    //
    //  This field either contains the granted access mask for the handle or an
    //  ob variation that also stores the same information.  Or in the case of
    //  a free entry the field stores the index for the next free entry in the
    //  free list.  This is like a FAT chain, and is used instead of pointers
    //  to make table duplication easier, because the entries can just be
    //  copied without needing to modify pointers.
    //
	
    union {
		
        union {
			
            ACCESS_MASK GrantedAccess;
			
            struct {
				
                USHORT GrantedAccessIndex;
                USHORT CreatorBackTraceIndex;
            };
        };
		
        LONG NextFreeTableEntry;
    };
	
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;

typedef struct _MMADDRESS_NODE {
    union {
        LONG_PTR Balance : 2;
        struct _MMADDRESS_NODE *Parent;
    } u1;
    struct _MMADDRESS_NODE *LeftChild;
    struct _MMADDRESS_NODE *RightChild;
    ULONG_PTR StartingVpn;
    ULONG_PTR EndingVpn;
} MMADDRESS_NODE, *PMMADDRESS_NODE;

typedef struct _MMSECTION_FLAGS {
    unsigned BeingDeleted : 1;
    unsigned BeingCreated : 1;
    unsigned BeingPurged : 1;
    unsigned NoModifiedWriting : 1;
	
    unsigned FailAllIo : 1;
    unsigned Image : 1;
    unsigned Based : 1;
    unsigned File : 1;
	
    unsigned Networked : 1;
    unsigned NoCache : 1;
    unsigned PhysicalMemory : 1;
    unsigned CopyOnWrite : 1;
	
    unsigned Reserve : 1;  // not a spare bit!
    unsigned Commit : 1;
    unsigned FloppyMedia : 1;
    unsigned WasPurged : 1;
	
    unsigned UserReference : 1;
    unsigned GlobalMemory : 1;
    unsigned DeleteOnClose : 1;
    unsigned FilePointerNull : 1;
	
    unsigned DebugSymbolsLoaded : 1;
    unsigned SetMappedFileIoComplete : 1;
    unsigned CollidedFlush : 1;
    unsigned NoChange : 1;
	
    unsigned filler0 : 1;
    unsigned ImageMappedInSystemSpace : 1;
    unsigned UserWritable : 1;
    unsigned Accessed : 1;
	
    unsigned GlobalOnlyPerSession : 1;
    unsigned Rom : 1;
    unsigned WriteCombined : 1;
    unsigned filler : 1;
} MMSECTION_FLAGS;


typedef struct _MMEXTEND_INFO {
    UINT64 CommittedSize;
    ULONG ReferenceCount;
} MMEXTEND_INFO, *PMMEXTEND_INFO;

typedef struct _SEGMENT_FLAGS {
    ULONG_PTR TotalNumberOfPtes4132 : 10;
    ULONG_PTR ExtraSharedWowSubsections : 1;
    ULONG_PTR LargePages : 1;
#if defined (_WIN64)
    ULONG_PTR Spare : 52;
#else
    ULONG_PTR Spare : 20;
#endif
} SEGMENT_FLAGS, *PSEGMENT_FLAGS;

typedef struct _SECTION_IMAGE_INFORMATION {
    PVOID TransferAddress;
    ULONG ZeroBits;
    SIZE_T MaximumStackSize;
    SIZE_T CommittedStackSize;
    ULONG SubSystemType;
    union {
        struct {
            USHORT SubSystemMinorVersion;
            USHORT SubSystemMajorVersion;
        };
        ULONG SubSystemVersion;
    };
    ULONG GpValue;
    USHORT ImageCharacteristics;
    USHORT DllCharacteristics;
    USHORT Machine;
    BOOLEAN ImageContainsCode;
    BOOLEAN Spare1;
    ULONG LoaderFlags;
    ULONG ImageFileSize;
    ULONG Reserved[ 1 ];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;

typedef struct _SEGMENT {
    struct _CONTROL_AREA *ControlArea;
    ULONG TotalNumberOfPtes;
    ULONG NonExtendedPtes;
    ULONG Spare0;
	
    UINT64 SizeOfSegment;
    ULONG SegmentPteTemplate[1];
	
    SIZE_T NumberOfCommittedPages;
    PMMEXTEND_INFO ExtendInfo;
	
    SEGMENT_FLAGS SegmentFlags;
    PVOID BasedAddress;
	
    //
    // The fields below are for image & pagefile-backed sections only.
    // Common fields are above and new common entries must be added to
    // both the SEGMENT and MAPPED_FILE_SEGMENT declarations.
    //
	
    union {
        SIZE_T ImageCommitment;     // for image-backed sections only
        PEPROCESS CreatingProcess;  // for pagefile-backed sections only
    } u1;
	
    union {
        PSECTION_IMAGE_INFORMATION ImageInformation;    // for images only
        PVOID FirstMappedVa;        // for pagefile-backed sections only
    } u2;
	
    PVOID PrototypePte;
    //MMPTE ThePtes[MM_PROTO_PTE_ALIGNMENT / PAGE_SIZE];
	
} SEGMENT, *PSEGMENT;

typedef struct _CONTROL_AREA {
    PSEGMENT Segment;
    LIST_ENTRY DereferenceList;
    ULONG NumberOfSectionReferences;    // All section refs & image flushes
    ULONG NumberOfPfnReferences;        // valid + transition prototype PTEs
    ULONG NumberOfMappedViews;          // total # mapped views, including
	// system cache & system space views
    ULONG NumberOfSystemCacheViews;     // system cache views only
    ULONG NumberOfUserReferences;       // user section & view references
    union {
        ULONG LongFlags;
        MMSECTION_FLAGS Flags;
    } u;
    PFILE_OBJECT FilePointer;
    PVOID WaitingForDeletion;
    USHORT ModifiedWriteCount;
    USHORT FlushInProgressCount;
    ULONG WritableUserReferences;
#if !defined (_WIN64)
    ULONG QuadwordPad;
#endif
} CONTROL_AREA, *PCONTROL_AREA;

#if defined (_WIN64)

#define COMMIT_SIZE 51

#if ((COMMIT_SIZE + PAGE_SHIFT) < 63)
#error COMMIT_SIZE too small
#endif

#else
#define COMMIT_SIZE 19

#if ((COMMIT_SIZE + PAGE_SHIFT) < 31)
#error COMMIT_SIZE too small
#endif
#endif

typedef enum _MI_VAD_TYPE {
    VadNone,
		VadDevicePhysicalMemory,
		VadImageMap,
		VadAwe,
		VadWriteWatch,
		VadLargePages,
		VadRotatePhysical,
		VadLargePageSection
} MI_VAD_TYPE, *PMI_VAD_TYPE;

typedef struct _MMVAD_FLAGS {
    ULONG_PTR CommitCharge : COMMIT_SIZE; // limits system to 4k pages or bigger!
    ULONG_PTR NoChange : 1;
    ULONG_PTR VadType : 3;
    ULONG_PTR MemCommit: 1;
    ULONG_PTR Protection : 5;
    ULONG_PTR Spare : 2;
    ULONG_PTR PrivateMemory : 1;    // used to tell VAD from VAD_SHORT
} MMVAD_FLAGS;

typedef struct _MMVAD_FLAGS2 {
    unsigned FileOffset : 24;       // number of 64k units into file
    unsigned SecNoChange : 1;       // set if SEC_NOCHANGE specified
    unsigned OneSecured : 1;        // set if u3 field is a range
    unsigned MultipleSecured : 1;   // set if u3 field is a list head
    unsigned ReadOnly : 1;          // protected as ReadOnly
    unsigned LongVad : 1;           // set if VAD is a long VAD
    unsigned ExtendableFile : 1;
    unsigned Inherit : 1;           //1 = ViewShare, 0 = ViewUnmap
    unsigned CopyOnWrite : 1;
} MMVAD_FLAGS2;

typedef struct _MMVAD {
    union {
        LONG_PTR Balance : 2;
        struct _MMVAD *Parent;
    } u1;
    struct _MMVAD *LeftChild;
    struct _MMVAD *RightChild;
    ULONG_PTR StartingVpn;
    ULONG_PTR EndingVpn;
	
    union {
        ULONG_PTR LongFlags;
        MMVAD_FLAGS VadFlags;
    } u;
    PCONTROL_AREA ControlArea;
    PVOID FirstPrototypePte;
    PVOID LastContiguousPte;
    union {
        ULONG LongFlags2;
        MMVAD_FLAGS2 VadFlags2;
    } u2;
} MMVAD, *PMMVAD;

typedef struct _MM_AVL_TABLE {
    MMADDRESS_NODE  BalancedRoot;
    ULONG_PTR DepthOfTree: 5;
    ULONG_PTR Unused: 3;
#if defined (_WIN64)
    ULONG_PTR NumberGenericTableElements: 56;
#else
    ULONG_PTR NumberGenericTableElements: 24;
#endif
    PVOID NodeHint;
    PVOID NodeFreeHint;
} MM_AVL_TABLE, *PMM_AVL_TABLE;

typedef struct _KGDTENTRY {
    USHORT  LimitLow;
    USHORT  BaseLow;
    union {
        struct {
            UCHAR   BaseMid;
            UCHAR   Flags1;     // Declare as bytes to avoid alignment
            UCHAR   Flags2;     // Problems.
            UCHAR   BaseHi;
        } Bytes;
        struct {
            ULONG   BaseMid : 8;
            ULONG   Type : 5;
            ULONG   Dpl : 2;
            ULONG   Pres : 1;
            ULONG   LimitHi : 4;
            ULONG   Sys : 1;
            ULONG   Reserved_0 : 1;
            ULONG   Default_Big : 1;
            ULONG   Granularity : 1;
            ULONG   BaseHi : 8;
        } Bits;
    } HighWord;
} KGDTENTRY, *PKGDTENTRY;

typedef struct _KIDTENTRY {
	USHORT Offset;
	USHORT Selector;
	USHORT Access;
	USHORT ExtendedOffset;
} KIDTENTRY;

typedef struct _KEXECUTE_OPTIONS {
    UCHAR ExecuteDisable : 1;
    UCHAR ExecuteEnable : 1;
    UCHAR DisableThunkEmulation : 1;
    UCHAR Permanent : 1;
    UCHAR ExecuteDispatchEnable : 1;
    UCHAR ImageDispatchEnable : 1;
    UCHAR Spare : 2;
} KEXECUTE_OPTIONS, PKEXECUTE_OPTIONS;

typedef struct _KPROCESS {

    //
    // The dispatch header and profile listhead are fairly infrequently
    // referenced.
    //

    DISPATCHER_HEADER Header;
    LIST_ENTRY ProfileListHead;

    //
    // The following fields are referenced during context switches.
    //

    ULONG_PTR DirectoryTableBase[2];

#if defined(_X86_)

    KGDTENTRY LdtDescriptor;
    KIDTENTRY Int21Descriptor;
    USHORT IopmOffset;
    UCHAR Iopl;
    BOOLEAN Unused;

#endif

#if defined(_AMD64_)

    USHORT IopmOffset;

#endif

    volatile KAFFINITY ActiveProcessors;

    //
    // The following fields are referenced during clock interrupts.
    //

    ULONG KernelTime;
    ULONG UserTime;

    //
    // The following fields are referenced infrequently.
    //

    LIST_ENTRY ReadyListHead;
    SINGLE_LIST_ENTRY SwapListEntry;

#if defined(_X86_)

    PVOID VdmTrapcHandler;

#else

    PVOID Reserved1;

#endif

    LIST_ENTRY ThreadListHead;
    KSPIN_LOCK ProcessLock;
    KAFFINITY Affinity;

    //
    // N.B. The following bit number definitions must match the following
    //      bit field.
    //
    // N.B. These bits can only be written with interlocked operations.
    //

#define KPROCESS_AUTO_ALIGNMENT_BIT 0
#define KPROCESS_DISABLE_BOOST_BIT 1
#define KPROCESS_DISABLE_QUANTUM_BIT 2

    union {
        struct {
            LONG AutoAlignment : 1;
            LONG DisableBoost : 1;
            LONG DisableQuantum : 1;
            LONG ReservedFlags : 29;
        };
   
        LONG ProcessFlags;
    };

    SCHAR BasePriority;
    SCHAR QuantumReset;
    UCHAR State;
    UCHAR ThreadSeed;
    UCHAR PowerState;
    UCHAR IdealNode;
    BOOLEAN Visited;
    union {
        KEXECUTE_OPTIONS Flags;
        UCHAR ExecuteOptions;
    };

#if !defined(_X86_) && !defined(_AMD64_)

    PALIGNMENT_EXCEPTION_TABLE AlignmentExceptionTable;

#endif

    ULONG_PTR StackCount;
    LIST_ENTRY ProcessListEntry;
} KPROCESS, *PKPROCESS, *PRKPROCESS;

typedef enum _PS_QUOTA_TYPE {
    PsNonPagedPool = 0,
		PsPagedPool    = 1,
		PsPageFile     = 2,
		PsQuotaTypes   = 3
} PS_QUOTA_TYPE, *PPS_QUOTA_TYPE;

typedef struct _EPROCESS_QUOTA_ENTRY {
    SIZE_T Usage;  // Current usage count
    SIZE_T Limit;  // Unhindered progress may be made to this point
    SIZE_T Peak;   // Peak quota usage
    SIZE_T Return; // Quota value to return to the pool once its big enough
} EPROCESS_QUOTA_ENTRY, *PEPROCESS_QUOTA_ENTRY;

//#define PS_TRACK_QUOTA 1

#define EPROCESS_QUOTA_TRACK_MAX 10000

typedef struct _EPROCESS_QUOTA_TRACK {
    SIZE_T Charge;
    PVOID Caller;
    PVOID FreeCaller;
    PVOID Process;
} EPROCESS_QUOTA_TRACK, *PEPROCESS_QUOTA_TRACK;

typedef struct _EPROCESS_QUOTA_BLOCK {
    EPROCESS_QUOTA_ENTRY QuotaEntry[PsQuotaTypes];
    LIST_ENTRY QuotaList; // All additional quota blocks are chained through here
    ULONG ReferenceCount;
    ULONG ProcessCount; // Total number of processes still referencing this block
#if defined (PS_TRACK_QUOTA)
    EPROCESS_QUOTA_TRACK Tracker[2][EPROCESS_QUOTA_TRACK_MAX];
#endif
} EPROCESS_QUOTA_BLOCK, *PEPROCESS_QUOTA_BLOCK;

// typedef struct _KGATE {
//     DISPATCHER_HEADER Header;
// } KGATE, *PKGATE;

//
// Define guarded mutex structure.
//

// begin_ntifs begin_ntddk begin_wdm begin_nthal begin_ntosp

#define GM_LOCK_BIT          0x1 // Actual lock bit, 0 = Unlocked, 1 = Locked
#define GM_LOCK_BIT_V        0x0 // Lock bit as a bit number
#define GM_LOCK_WAITER_WOKEN 0x2 // A single waiter has been woken to acquire this lock
#define GM_LOCK_WAITER_INC   0x4 // Increment value to change the waiters count

// typedef struct _KGUARDED_MUTEX {
//     LONG Count;
//     PKTHREAD Owner;
//     ULONG Contention;
//     KGATE Gate;
//     union {
//         struct {
//             SHORT KernelApcDisable;
//             SHORT SpecialApcDisable;
//         };
// 		
//         ULONG CombinedApcDisable;
//     };
// 	
// } KGUARDED_MUTEX, *PKGUARDED_MUTEX;

// end_wdm


typedef struct _EPROCESS {
    KPROCESS Pcb;

    //
    // Lock used to protect:
    // The list of threads in the process.
    // Process token.
    // Win32 process field.
    // Process and thread affinity setting.
    //

    EX_PUSH_LOCK ProcessLock;

    LARGE_INTEGER CreateTime;
    LARGE_INTEGER ExitTime;

    //
    // Structure to allow lock free cross process access to the process
    // handle table, process section and address space. Acquire rundown
    // protection with this if you do cross process handle table, process
    // section or address space references.
    //

    EX_RUNDOWN_REF RundownProtect;

    HANDLE UniqueProcessId;

    //
    // Global list of all processes in the system. Processes are removed
    // from this list in the object deletion routine.  References to
    // processes in this list must be done with ObReferenceObjectSafe
    // because of this.
    //

    LIST_ENTRY ActiveProcessLinks;

    //
    // Quota Fields.
    //

    SIZE_T QuotaUsage[PsQuotaTypes];
    SIZE_T QuotaPeak[PsQuotaTypes];
    SIZE_T CommitCharge;

    //
    // VmCounters.
    //

    SIZE_T PeakVirtualSize;
    SIZE_T VirtualSize;

    LIST_ENTRY SessionProcessLinks;

    PVOID DebugPort;
    PVOID ExceptionPort;
    PHANDLE_TABLE ObjectTable;

    //
    // Security.
    //

    EX_FAST_REF Token;

    PFN_NUMBER WorkingSetPage;
    KGUARDED_MUTEX AddressCreationLock;
    KSPIN_LOCK HyperSpaceLock;

    struct _ETHREAD *ForkInProgress;
    ULONG_PTR HardwareTrigger;

    PMM_AVL_TABLE PhysicalVadRoot;
    PVOID CloneRoot;
    PFN_NUMBER NumberOfPrivatePages;
    PFN_NUMBER NumberOfLockedPages;
    PVOID Win32Process;
    PVOID *Job;
    PVOID SectionObject;

    PVOID SectionBaseAddress;

    PEPROCESS_QUOTA_BLOCK QuotaBlock;

    PVOID  WorkingSetWatch;
    HANDLE Win32WindowStation;
    HANDLE InheritedFromUniqueProcessId;

    PVOID LdtInformation;
    PVOID VadFreeHint;
    PVOID VdmObjects;
    PVOID DeviceMap;

    PVOID Spare0[3];
    union {
        ULONG PageDirectoryPte[1];
        ULONGLONG Filler;
    };
    PVOID Session;
    UCHAR ImageFileName[ 16 ];

    LIST_ENTRY JobLinks;
    PVOID LockedPagesList;

    LIST_ENTRY ThreadListHead;

    //
    // Used by rdr/security for authentication.
    //

    PVOID SecurityPort;

#ifdef _WIN64
    PWOW64_PROCESS Wow64Process;
#else
    PVOID PaeTop;
#endif

    ULONG ActiveThreads;

    ACCESS_MASK GrantedAccess;

    ULONG DefaultHardErrorProcessing;

    NTSTATUS LastThreadExitStatus;

    //
    // Peb
    //

    PPEB Peb;

    //
    // Pointer to the prefetches trace block.
    //
    EX_FAST_REF PrefetchTrace;

    LARGE_INTEGER ReadOperationCount;
    LARGE_INTEGER WriteOperationCount;
    LARGE_INTEGER OtherOperationCount;
    LARGE_INTEGER ReadTransferCount;
    LARGE_INTEGER WriteTransferCount;
    LARGE_INTEGER OtherTransferCount;

    SIZE_T CommitChargeLimit;
    SIZE_T CommitChargePeak;

    PVOID AweInfo;

    //
    // This is used for SeAuditProcessCreation.
    // It contains the full path to the image file.
    //

    ULONG SeAuditProcessCreationInfo;

    ULONG Vm[18];

#if !defined(_WIN64)
    LIST_ENTRY MmProcessLinks;
#else
    ULONG Spares[2];
#endif

    ULONG ModifiedPageCount;

    #define PS_JOB_STATUS_NOT_REALLY_ACTIVE      0x00000001UL
    #define PS_JOB_STATUS_ACCOUNTING_FOLDED      0x00000002UL
    #define PS_JOB_STATUS_NEW_PROCESS_REPORTED   0x00000004UL
    #define PS_JOB_STATUS_EXIT_PROCESS_REPORTED  0x00000008UL
    #define PS_JOB_STATUS_REPORT_COMMIT_CHANGES  0x00000010UL
    #define PS_JOB_STATUS_LAST_REPORT_MEMORY     0x00000020UL
    #define PS_JOB_STATUS_REPORT_PHYSICAL_PAGE_CHANGES  0x00000040UL

    ULONG JobStatus;


    //
    // Process flags. Use interlocked operations with PS_SET_BITS, etc
    // to modify these.
    //

    #define PS_PROCESS_FLAGS_CREATE_REPORTED        0x00000001UL // Create process debug call has occurred
    #define PS_PROCESS_FLAGS_NO_DEBUG_INHERIT       0x00000002UL // Don't inherit debug port
    #define PS_PROCESS_FLAGS_PROCESS_EXITING        0x00000004UL // PspExitProcess entered
    #define PS_PROCESS_FLAGS_PROCESS_DELETE         0x00000008UL // Delete process has been issued
    #define PS_PROCESS_FLAGS_WOW64_SPLIT_PAGES      0x00000010UL // Wow64 split pages
    #define PS_PROCESS_FLAGS_VM_DELETED             0x00000020UL // VM is deleted
    #define PS_PROCESS_FLAGS_OUTSWAP_ENABLED        0x00000040UL // Outswap enabled
    #define PS_PROCESS_FLAGS_OUTSWAPPED             0x00000080UL // Outswapped
    #define PS_PROCESS_FLAGS_FORK_FAILED            0x00000100UL // Fork status
    #define PS_PROCESS_FLAGS_WOW64_4GB_VA_SPACE     0x00000200UL // Wow64 process with 4gb virtual address space
    #define PS_PROCESS_FLAGS_ADDRESS_SPACE1         0x00000400UL // Addr space state1
    #define PS_PROCESS_FLAGS_ADDRESS_SPACE2         0x00000800UL // Addr space state2
    #define PS_PROCESS_FLAGS_SET_TIMER_RESOLUTION   0x00001000UL // SetTimerResolution has been called
    #define PS_PROCESS_FLAGS_BREAK_ON_TERMINATION   0x00002000UL // Break on process termination
    #define PS_PROCESS_FLAGS_CREATING_SESSION       0x00004000UL // Process is creating a session
    #define PS_PROCESS_FLAGS_USING_WRITE_WATCH      0x00008000UL // Process is using the write watch APIs
    #define PS_PROCESS_FLAGS_IN_SESSION             0x00010000UL // Process is in a session
    #define PS_PROCESS_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00020000UL // Process must use native address space (Win64 only)
    #define PS_PROCESS_FLAGS_HAS_ADDRESS_SPACE      0x00040000UL // This process has an address space
    #define PS_PROCESS_FLAGS_LAUNCH_PREFETCHED      0x00080000UL // Process launch was prefetched
    #define PS_PROCESS_INJECT_INPAGE_ERRORS         0x00100000UL // Process should be given inpage errors - hardcoded in trap.asm too
    #define PS_PROCESS_FLAGS_VM_TOP_DOWN            0x00200000UL // Process memory allocations default to top-down
    #define PS_PROCESS_FLAGS_IMAGE_NOTIFY_DONE      0x00400000UL // We have sent a message for this image
    #define PS_PROCESS_FLAGS_PDE_UPDATE_NEEDED      0x00800000UL // The system PDEs need updating for this process (NT32 only)
    #define PS_PROCESS_FLAGS_VDM_ALLOWED            0x01000000UL // Process allowed to invoke NTVDM support
    #define PS_PROCESS_FLAGS_SMAP_ALLOWED           0x02000000UL // Process allowed to invoke SMAP support
    #define PS_PROCESS_FLAGS_CREATE_FAILED          0x04000000UL // Process create failed

    #define PS_PROCESS_FLAGS_DEFAULT_IO_PRIORITY    0x38000000UL // The default I/O priority for created threads. (3 bits)

    #define PS_PROCESS_FLAGS_PRIORITY_SHIFT         27
    
    #define PS_PROCESS_FLAGS_EXECUTE_SPARE1         0x40000000UL //
    #define PS_PROCESS_FLAGS_EXECUTE_SPARE2         0x80000000UL //


    union {

        ULONG Flags;

        //
        // Fields can only be set by the PS_SET_BITS and other interlocked
        // macros.  Reading fields is best done via the bit definitions so
        // references are easy to locate.
        //

        struct {
            ULONG CreateReported            : 1;
            ULONG NoDebugInherit            : 1;
            ULONG ProcessExiting            : 1;
            ULONG ProcessDelete             : 1;
            ULONG Wow64SplitPages           : 1;
            ULONG VmDeleted                 : 1;
            ULONG OutswapEnabled            : 1;
            ULONG Outswapped                : 1;
            ULONG ForkFailed                : 1;
            ULONG Wow64VaSpace4Gb           : 1;
            ULONG AddressSpaceInitialized   : 2;
            ULONG SetTimerResolution        : 1;
            ULONG BreakOnTermination        : 1;
            ULONG SessionCreationUnderway   : 1;
            ULONG WriteWatch                : 1;
            ULONG ProcessInSession          : 1;
            ULONG OverrideAddressSpace      : 1;
            ULONG HasAddressSpace           : 1;
            ULONG LaunchPrefetched          : 1;
            ULONG InjectInpageErrors        : 1;
            ULONG VmTopDown                 : 1;
            ULONG ImageNotifyDone           : 1;
            ULONG PdeUpdateNeeded           : 1;    // NT32 only
            ULONG VdmAllowed                : 1;
            ULONG SmapAllowed               : 1;
            ULONG CreateFailed              : 1;
            ULONG DefaultIoPriority         : 3;
            ULONG Spare1                    : 1;
            ULONG Spare2                    : 1;
        };
    };

    NTSTATUS ExitStatus;

    USHORT NextPageColor;
    union {
        struct {
            UCHAR SubSystemMinorVersion;
            UCHAR SubSystemMajorVersion;
        };
        USHORT SubSystemVersion;
    };
    UCHAR PriorityClass;

    MM_AVL_TABLE VadRoot;

    ULONG Cookie;

} EPROCESS; 

#endif

.c文件

/*
	FindDllByVad.C
	Author: BieDaLian
	Last Updated: 2007-07-06

	This framework is generated by EasySYS 0.3.0 Modify
	This template file is copying from QuickSYS 0.3.0 written by Chunhua Liu
	//=============================================
	Modified by PLK_XiaoWei[0GiNr]
	http://www.0GiNr.com
	//=============================================
*/

/////////////////////////////////////////////////////////////////////////////////
/////////////
/////////            Just  For  WIN2003 SP2....
//////////  If you need the src,please DIY it by yourself.....
///////
////
///////////////////////////////////////////////////////////////////////////////

#include "FindDllByVad.h"    

#define NOTHING
#define SANITIZE_PARENT_NODE(Parent) ((PMMADDRESS_NODE)(((ULONG_PTR)(Parent)) & ~0x3))
#define Parent(Links) (               \
    (PRTL_SPLAY_LINKS)(SANITIZE_PARENT_NODE((Links)->u1.Parent)) \
)
#define IsRightChild(Links) ( (RtlRightChild(Parent(Links)) == (PRTL_SPLAY_LINKS)(Links)) )
#define IsLeftChild(Links) ( (RtlLeftChild(Parent(Links)) == (PRTL_SPLAY_LINKS)(Links)) )

//===========================================
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString);
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
VOID DriverUnload(PDRIVER_OBJECT pDriverObj);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);

void __fastcall DumpVadInfo(MMVAD *VadNode);
typedef void (_stdcall *PROCESS_CALLBCK)(EPROCESS *Eprocess);
void _stdcall ProcessCallBack(EPROCESS *Eprocess);
void EnumProcess(PROCESS_CALLBCK ProcessCallBack);

/************************************************************************
* 函數名稱:DriverEntry
* 功能描述:
* 參數列表:

* 返回值:
*************************************************************************/
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{

	NTSTATUS status = STATUS_SUCCESS;
	UNICODE_STRING ustrLinkName;
	UNICODE_STRING ustrDevName;    
	PDEVICE_OBJECT pDevObj;

	//DbgBreakPoint();
	_asm int 3
	dprintf("[FindDllByVad] DriverEntry: %S\n",pRegistryString->Buffer);

    // Create dispatch points for device control, create, close.
	pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
	pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
	pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
	pDriverObj->DriverUnload = DriverUnload;
	//

	RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
	
	status = IoCreateDevice(pDriverObj, 
				0,
				&ustrDevName, 
				FILE_DEVICE_UNKNOWN,
				0,
				FALSE,
				&pDevObj);

	dprintf("[FindDllByVad] Device Name %S",ustrDevName.Buffer);

	if(!NT_SUCCESS(status))
	{
		dprintf("[FindDllByVad] IoCreateDevice = 0x%x\n", status);
		return status;
	}

	
	RtlInitUnicodeString(&ustrLinkName, LINK_NAME);

	status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);  
	if(!NT_SUCCESS(status))
	{
		dprintf("[FindDllByVad] IoCreateSymbolicLink = 0x%x\n", status);
		IoDeleteDevice(pDevObj);  
		return status;
	}
	
	dprintf("[FindDllByVad] SymbolicLink:%S",ustrLinkName.Buffer);

	EnumProcess((PROCESS_CALLBCK)ProcessCallBack);

	return STATUS_SUCCESS;
}



/************************************************************************
* 函數名稱:DriverUnload
* 功能描述:
* 參數列表:

  * 返回值:
*************************************************************************/
VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{	
	UNICODE_STRING strLink;
	RtlInitUnicodeString(&strLink, LINK_NAME);
	//
    // Delete the symbolic link
    //
	IoDeleteSymbolicLink(&strLink);
	//
    // Delete the device object
    //
	IoDeleteDevice(pDriverObj->DeviceObject);
	dprintf("[FindDllByVad] Unloaded\n");
}

NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	dprintf("[FindDllByVad] IRP_MJ_CREATE\n");
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	dprintf("[FindDllByVad] IRP_MJ_CLOSE\n");
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
	PIO_STACK_LOCATION pIrpStack;
	ULONG uIoControlCode;
	PVOID pIoBuffer;
	ULONG uInSize;
	ULONG uOutSize;

	pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
	uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
	pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
	uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

	switch(uIoControlCode)
	{
	case IOCTL_HELLO:
		{
			//Say Hello #^_^#
			dprintf("[FindDllByVad] Hello,I have benn called..");
			status = STATUS_SUCCESS;
		}
		break;
	}

	if(status == STATUS_SUCCESS)
		pIrp->IoStatus.Information = uOutSize;
	else
		pIrp->IoStatus.Information = 0;

	pIrp->IoStatus.Status = status;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return status;
}



/************************************************************************
* 函數名稱:RealSuccessor
* 功能描述:從avl樹中得到當前結點的後繼結點
* 參數列表:PMMADDRESS_NODE 輸入結點

* 返回值:PMMADDRESS_NODE 輸入結點的後繼結點
*************************************************************************/
PMMADDRESS_NODE RealSuccessor (PMMADDRESS_NODE Links)
{
    PMMADDRESS_NODE Ptr;
	//如果有右孩子,就找右孩子最左下的結點
   if ((Ptr = Links->RightChild) != NULL) {
		
        while (Ptr->LeftChild != NULL) {
            Ptr = Ptr->LeftChild;
        }
		
        return Ptr;
    }
	
   //如果沒有右孩子
    Ptr = Links;
    while (IsRightChild(Ptr)) {	//是右孩子就找到父母
        Ptr = SANITIZE_PARENT_NODE (Ptr->u1.Parent);
    }
	
    if (IsLeftChild(Ptr)) {
        return SANITIZE_PARENT_NODE (Ptr->u1.Parent);
    }
	
    return NULL;
}


/************************************************************************
* 函數名稱:EnumerateGenericTableWithoutSplayingAvl
* 功能描述:從avl樹中,得到最新的結點
* 參數列表:PMM_AVL_TABLE 樹的根結點
		   RestartKey 是否進行AVL樹的旋轉
* 返回值:PVOID 樹中最近變化的結點
*************************************************************************/
PVOID
EnumerateGenericTableWithoutSplayingAvl (PMM_AVL_TABLE Table,PVOID *RestartKey)									   
{
    PMMADDRESS_NODE NodeToReturn;
	
    if (Table->NumberGenericTableElements == 0) {
		
        //
        // Nothing to do if the table is empty.
        //
		
        return NULL;
		
    }
	
    //
    // If the restart flag is true then go to the least element
    // in the tree.
    //
	
    if (*RestartKey == NULL) {
		
        //
        // Loop until we find the leftmost child of the root.
        //
		
        for (NodeToReturn = Table->BalancedRoot.RightChild;
		NodeToReturn->LeftChild;
		NodeToReturn = NodeToReturn->LeftChild) {
			NOTHING;

        }
		
        *RestartKey = NodeToReturn;
		
    }
    else {
		
        //
        // The caller has passed in the previous entry found
        // in the table to enable us to continue the search.  We call
        // RealSuccessor to step to the next element in the tree.
        //
		
        NodeToReturn = RealSuccessor (*RestartKey);
		
        if (NodeToReturn) {
            *RestartKey = NodeToReturn;
        }
    }
	
    //
    // Return the found element.
    //
	
    return NodeToReturn;
}



/************************************************************************
* 函數名稱:NodeTreeWalk
* 功能描述:遍歷AVL樹,對每個結點調用DumpVadInfo
* 參數列表:Table 樹的根結點
		   
* 返回值:NONE
*************************************************************************/
VOID NodeTreeWalk (PMM_AVL_TABLE Table)
{
    PVOID RestartKey;
    PMMADDRESS_NODE NewNode;
    PMMADDRESS_NODE PrevNode;
    PMMADDRESS_NODE NextNode;
	
    RestartKey = NULL;
	
    do {
		
        NewNode = EnumerateGenericTableWithoutSplayingAvl (Table,
			&RestartKey);
		
        if (NewNode == NULL) {
            break;
        }

		DumpVadInfo((MMVAD *)NewNode);
		
    } while (TRUE);
	
    return;
}


/************************************************************************
* 函數名稱:IsFileObjectSafe
* 功能描述:判定FileObject對象是否安全
* 參數列表:FileObject FileObject對象
		   
* 返回值:BOOLEAN
*************************************************************************/
BOOLEAN IsFileObjectSafe(FILE_OBJECT *FileObject)
{
	if (!MmIsAddressValid(FileObject))
	{
		return FALSE;
	}

	if(!MmIsAddressValid(FileObject->DeviceObject))
	{
		return FALSE;
	}

	if (FileObject->FileName.Length==0 ||
		!MmIsAddressValid(FileObject->Vpb)||
		!MmIsAddressValid(FileObject->FsContext)||
		!MmIsAddressValid(FileObject->FsContext2))
	{
		return FALSE;
	}

	return TRUE;
}


/************************************************************************
* 函數名稱:DumpVadInfo
* 功能描述:打印出查找到dll文件的路徑
* 參數列表:VadNode  從VadNodek中得到文件路徑
		   
* 返回值:
*************************************************************************/
void __fastcall DumpVadInfo(MMVAD *VadNode)
{
	PCONTROL_AREA ControlArea;
	PFILE_OBJECT FileObject;
	OBJECT_NAME_INFORMATION *FileObjectNameInfo;
	ANSI_STRING FileName;
	UNICODE_STRING DosDeviceName;
	UNICODE_STRING DosPath;
	NTSTATUS Status;

	FileObjectNameInfo=NULL;
	FileObject=NULL;

	if (!MmIsAddressValid(VadNode))
	{
		return;
	}

	if(!MmIsAddressValid(VadNode->ControlArea))
	{
		return;
	}
	ControlArea=VadNode->ControlArea;
	if (ControlArea->u.Flags.Image)
	{
		FileObject=VadNode->ControlArea->FilePointer;		
	}

	if (IsFileObjectSafe(FileObject))
	{	
		Status=IoVolumeDeviceToDosName(FileObject->DeviceObject,&DosDeviceName);

		if (NT_SUCCESS(Status))
		{
			DosPath.Length=0;
			DosPath.MaximumLength=DosDeviceName.Length+FileObject->FileName.Length+sizeof(WCHAR);
			DosPath.Buffer=kmalloc(DosPath.MaximumLength);
			if (DosPath.Buffer)
			{
				RtlZeroMemory(DosPath.Buffer,DosPath.Length);
				RtlAppendUnicodeStringToString(&DosPath,&DosDeviceName);
				RtlAppendUnicodeStringToString(&DosPath,&FileObject->FileName);
				Status=RtlUnicodeStringToAnsiString(&FileName,&DosPath,TRUE);
				if (NT_SUCCESS(Status))
				{
					DbgPrint("File %s\n",FileName.Buffer);
					RtlFreeAnsiString(&FileName);
				}

				kfree(DosPath.Buffer);
			}

			kfree(DosDeviceName.Buffer);
		}
		
	}
	return;
}


/************************************************************************
* 函數名稱:ProcessCallBack
* 功能描述:進程回調函數
* 參數列表:Eprocess  從Eprocess得到MM_AVL_TABLE開始遍歷得到dll列表
		   
* 返回值:
*************************************************************************/
void ProcessCallBack(EPROCESS *Eprocess)
{
	EPROCESS *process;
	MMADDRESS_NODE *AddressNode;
	MMVAD *VadTreeNode;

	process=(EPROCESS *)Eprocess;
	if (!MmIsAddressValid(process))
	{
		return;
	}
		
	AddressNode=(MMADDRESS_NODE *)(&process->VadRoot);
	dprintf("Pid %d PROCESS NAME %s\nAddress Node %x\n",process->UniqueProcessId,
														process->ImageFileName,
														AddressNode);

	NodeTreeWalk((MM_AVL_TABLE *)AddressNode);

	//WalkTree((MMVAD *)AddressNode);

	return ;
}


/************************************************************************
* 函數名稱:EnumProcess
* 功能描述:DriverEntry中調用,進行遍歷
* 參數列表:ProcessCallBack  回調函數
		   
* 返回值:
*************************************************************************/
void EnumProcess(PROCESS_CALLBCK ProcessCallBack)
{
	//
	//MmProcessLinks Just For WIN2003 or Later....
	//
	EPROCESS *CurrentProcess;
	EPROCESS *NextProcess;
	LIST_ENTRY *Next;

	//DbgBreakPoint();	

	NextProcess=CurrentProcess=(EPROCESS *)IoGetCurrentProcess();
	Next=&CurrentProcess->MmProcessLinks;
	do 
	{
		ProcessCallBack(NextProcess);
		Next=Next->Flink;
		NextProcess=CONTAINING_RECORD(Next,EPROCESS,MmProcessLinks);

	} while(Next!=&CurrentProcess->MmProcessLinks);
	return;
}




發佈了182 篇原創文章 · 獲贊 18 · 訪問量 77萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章