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