魔鬼天使 发表于 2017-6-2 13:31:22

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
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;

    //
    //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;
       
    SIZE_T NumberOfCommittedPages;
    PMMEXTEND_INFO ExtendInfo;
       
    SEGMENT_FLAGS SegmentFlags;
    PVOID BasedAddress;
       
    //
    // The fields below are for image &amp; 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;
       
} SEGMENT, *PSEGMENT;

typedef struct _CONTROL_AREA {
    PSEGMENT Segment;
    LIST_ENTRY DereferenceList;
    ULONG NumberOfSectionReferences;    // All section refs &amp; image flushes
    ULONG NumberOfPfnReferences;      // valid + transition prototype PTEs
    ULONG NumberOfMappedViews;          // total # mapped views, including
        // system cache &amp; system space views
    ULONG NumberOfSystemCacheViews;   // system cache views only
    ULONG NumberOfUserReferences;       // user section &amp; 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_NODEBalancedRoot;
    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 {
    USHORTLimitLow;
    USHORTBaseLow;
    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;

#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_) &amp;&amp; !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;
    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;
#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;
    SIZE_T QuotaPeak;
    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;

    PVOIDWorkingSetWatch;
    HANDLE Win32WindowStation;
    HANDLE InheritedFromUniqueProcessId;

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

    PVOID Spare0;
    union {
      ULONG PageDirectoryPte;
      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;

#if !defined(_WIN64)
    LIST_ENTRY MmProcessLinks;
#else
    ULONG Spares;
#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_REPORTED0x00000008UL
    #define PS_JOB_STATUS_REPORT_COMMIT_CHANGES0x00000010UL
    #define PS_JOB_STATUS_LAST_REPORT_MEMORY   0x00000020UL
    #define PS_JOB_STATUS_REPORT_PHYSICAL_PAGE_CHANGES0x00000040UL

    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
        http://www.0GiNr.com
        //=============================================
*/

/////////////////////////////////////////////////////////////////////////////////
/////////////
/////////            JustForWIN2003 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)) &amp; ~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(" DriverEntry: %S\n",pRegistryString->Buffer);

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

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

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

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

       
        RtlInitUnicodeString(&amp;ustrLinkName, LINK_NAME);

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

        EnumProcess((PROCESS_CALLBCK)ProcessCallBack);

        return STATUS_SUCCESS;
}



/************************************************************************
* 函数名称:DriverUnload
* 功能描述:
* 参数列表:

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

NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
        pIrp->IoStatus.Status = STATUS_SUCCESS;
        pIrp->IoStatus.Information = 0;
        dprintf(" 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(" 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(" 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,
                        &amp;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,&amp;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(&amp;DosPath,&amp;DosDeviceName);
                                RtlAppendUnicodeStringToString(&amp;DosPath,&amp;FileObject->FileName);
                                Status=RtlUnicodeStringToAnsiString(&amp;FileName,&amp;DosPath,TRUE);
                                if (NT_SUCCESS(Status))
                                {
                                        DbgPrint("File %s\n",FileName.Buffer);
                                        RtlFreeAnsiString(&amp;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 *)(&amp;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=&amp;CurrentProcess->MmProcessLinks;
        do
        {
                ProcessCallBack(NextProcess);
                Next=Next->Flink;
                NextProcess=CONTAINING_RECORD(Next,EPROCESS,MmProcessLinks);

        } while(Next!=&amp;CurrentProcess->MmProcessLinks);
        return;
}
页: [1]
查看完整版本: FindDllByVad遍历dll文件