在Windows NT中,80386保護模式的“保護”比Windows 95中更堅固,這個“鍍金的籠子”更加結實,更加難以打破。在Windows 95中,至少應用程式I/O操作是不受限制的,而在Windows NT中,我們的應用程式連這點許可權都被剝奪了。在NT中幾乎不太可能進入真正的ring0層。
在Windows NT中,存在三種Device Driver:
1.“Virtual device Driver” (VDD)。通過VDD,16位應用程式,如DOS 和Win16應用程式可以訪問特定的I/O連接埠(注意,不是直接存取,而是要通過VDD來實現訪問)。
2.“GDI Driver”,提供顯示和列印所需的GDI函數。
3.“Kernel Mode Driver”,實現對特定硬體的操作,比如說CreateFile, CloseHandle (對於檔案對象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”還是Windows NT中唯一可以對硬體中斷和DMA進行操作的Driver。SCSI 小連接埠驅動和 網卡NDIS 驅動都是Kernel Mode Driver的一種特殊形式。
Visual studio11與Windows8帶來格外不同的新體驗
1.啟動Vs11
2.看見滿目的驅動開發模板
3.選擇一個驅動模式,有核心模式與使用者模式兩種的驅動
4.建立一個驅動程式,KMDF DriverMVP
5.我們選擇的是核心模式的驅動程式,下面是建立成功後的介面,分別是驅動程式本身,與驅動安裝包
6.按下F5,選擇驅動編譯,
插入下列代碼實現記憶體填0殺進程,請見程式碼分析
void WPOFF(){__asm { //去掉記憶體保護climov eax,cr0and eax,not 10000hmov cr0,eax}}void WPON(){__asm { //恢複記憶體保護 mov eax,cr0or eax,10000hmov cr0,eaxsti} }////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef __cplusplus}#endif#endifNTKERNELAPIBOOLEANKeInsertQueueApc ( PRKAPC Apc, PVOID SystemArgument1, PVOID SystemArgument2, KPRIORITY Increment );BOOLEAN fake_KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost);BOOLEANProxy_KeInsertQueueApc(IN PKAPC Apc, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN KPRIORITY PriorityBoost);ULONG g_uCr0;void WPOFF(){ ULONG uAttr; _asm { push eax; mov eax, cr0; mov uAttr, eax; and eax, 0FFFEFFFFh; // CR0 16 BIT = 0 mov cr0, eax; pop eax; cli }; g_uCr0 = uAttr; //儲存原有的 CRO 屬性}VOID WPON(){ _asm { sti push eax; mov eax, g_uCr0; //恢復原有 CR0 屬性 mov cr0, eax; pop eax; };}#include <ntddk.h>#include"ntifs.h"typedef unsigned long DWORD;PHYSICAL_ADDRESS g_PhysicalPage;void WPOFF(){__asm { //去掉記憶體保護climov eax,cr0and eax,not 10000hmov cr0,eax}}void WPON(){__asm { //恢複記憶體保護 mov eax,cr0or eax,10000hmov cr0,eaxsti} }VOID DestroyProcess(DWORD eproc){ DWORD VirtualAddr; PHYSICAL_ADDRESS physical_addr; DWORD AddrTmp; PVOID ProcessHandle; KeAttachProcess( (PEPROCESS)eproc ); for ( VirtualAddr = 0x1000; VirtualAddr < *(DWORD*)MmSystemRangeStart; VirtualAddr+=0x1000) { // 跳過不再記憶體裡的 physical_addr = MmGetPhysicalAddress( (PVOID)VirtualAddr); if ( physical_addr.HighPart > g_PhysicalPage.HighPart ) continue; if ( physical_addr.HighPart == g_PhysicalPage.HighPart && physical_addr.LowPart >= g_PhysicalPage.LowPart ) continue; if ( (physical_addr.HighPart | physical_addr.LowPart) == 0 ) continue; AddrTmp = (DWORD)MmGetVirtualForPhysical( physical_addr); if ( AddrTmp != VirtualAddr) continue; WPOFF(); RtlZeroMemory( (PVOID)VirtualAddr, 0x1000); WPON(); } KeDetachProcess(); if ( ObOpenObjectByPointer( (PVOID)eproc, 0, NULL, 0, NULL, KernelMode, &ProcessHandle) != STATUS_SUCCESS) return; ZwTerminateProcess( (HANDLE)ProcessHandle, STATUS_SUCCESS); ZwClose( (HANDLE)ProcessHandle ); return;}VOID OnUnload( IN PDRIVER_OBJECT DriverObject ){ DbgPrint("My Driver UnLoad!");}//================================================================================================NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ){SYSTEM_BASIC_INFORMATION BasicInfo;ULONG ReturnedLength;PEPROCESS eproc; DbgPrint("My Driver Loaded!"); theDriverObject->DriverUnload = OnUnload; ZwQuerySystemInformation( SystemBasicInformation, &BasicInfo, sizeof(SYSTEM_BASIC_INFORMATION), &ReturnedLength); __asm mov eax,BasicInfo.PhysicalPageSize; __asm mul BasicInfo.NumberOfPhysicalPages; __asm mov g_PhysicalPage.HighPart, edx; __asm mov g_PhysicalPage.LowPart, eax; PsLookupProcessByProcessId((PVOID)1068,&eproc); DestroyProcess((DWORD)eproc); return STATUS_SUCCESS;}//================================================================================================#include "pe.h"#ifndef GLOBAL_NATIVE_API_DEF_SUDAMI#define GLOBAL_NATIVE_API_DEF_SUDAMI#ifdef __cplusplusextern "C" {#endif////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////typedef long NTSTATUS, *PNTSTATUS;typedef unsigned long DWORD;typedef DWORD * PDWORD;typedef unsigned long ULONG;typedef unsigned long ULONG_PTR;typedef ULONG *PULONG;typedef unsigned short WORD;typedef unsigned char BYTE; typedef unsigned char UCHAR;typedef unsigned short USHORT;typedef void *PVOID;typedef int BOOL;typedef BYTE BOOLEAN;typedef CCHAR KPROCESSOR_MODE;#ifndef LOWORD#define LOWORD(l) ((unsigned short)(unsigned int)(l))#endif#ifndef HIWORD#define HIWORD(l) ((unsigned short)((((unsigned int)(l)) >> 16) & 0xFFFF))#endif// 定義ioctl相關的,用於R3和R0間的通訊#ifndef MAKELONG#define MAKELONG(a, b) ((LONG) (((WORD) (a)) | ((DWORD) ((WORD) (b))) << 16))#endif#define MY_DEVICE_TYPE 0x0000AA71 // 這地方可以自己改#define DRIVER_IO(code) CTL_CODE (MY_DEVICE_TYPE, code, METHOD_BUFFERED, FILE_ANY_ACCESS)typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;/**********************************************************#define NT_DEVICE_NAME L"\\Device\\sKillTimeProtected"#define DOS_DEVICE_NAME L"\\DosDevices\\sKillTimeProtected"// -- #ifndef ANSI_STRINGtypedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer;} ANSI_STRING, *PANSI_STRING;#endif#ifndef UNICODE_STRINGtypedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer;} UNICODE_STRING, *PUNICODE_STRING;#endif/* SSDT */#pragma pack(1)typedef struct ServiceDescriptorEntry {unsigned int*ServiceTableBase;unsigned int*ServiceCounterTableBase; unsigned intNumberOfServices;unsigned char *ParamTableBase;} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;typedef struct ServiceDescriptorShadowEntry {unsigned int*Win32kTableBase;unsigned int*Win32kCounterTableBase;unsigned intNumberofWin32kServices;unsigned char *Win32kParamTableBase;} ServiceDescriptorTableShadowEntry_t, *PServiceDescriptorTableShadowEntry_t;#pragma pack()__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;PServiceDescriptorTableShadowEntry_tKeServiceDescriptorTableShadow;struct _SYSTEM_THREADS{LARGE_INTEGERKernelTime;LARGE_INTEGERUserTime;LARGE_INTEGERCreateTime;ULONGWaitTime;PVOIDStartAddress;CLIENT_IDClientIs;KPRIORITYPriority;KPRIORITYBasePriority;ULONGContextSwitchCount;ULONGThreadState;KWAIT_REASONWaitReason;};struct _SYSTEM_PROCESSES{ULONGNextEntryDelta;ULONGThreadCount;ULONGReserved[6];LARGE_INTEGERCreateTime;LARGE_INTEGERUserTime;LARGE_INTEGERKernelTime;UNICODE_STRINGProcessName;KPRIORITYBasePriority;ULONGProcessId;ULONGInheritedFromProcessId;ULONGHandleCount;ULONGReserved2[2];VM_COUNTERSVmCounters;IO_COUNTERSIoCounters; //windows 2000 onlystruct _SYSTEM_THREADSThreads[1];};// PROCESS_BASIC_INFORMATION#ifdef PROCESS_BASIC_INFORMATION#undef PROCESS_BASIC_INFORMATIONtypedef struct _PROCESS_BASIC_INFORMATION {NTSTATUSExitStatus;ULONGPebBaseAddress;ULONG_PTRAffinityMask;LONGBasePriority;ULONG_PTRUniqueProcessId;ULONG_PTRInheritedFromUniqueProcessId;} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;#endif// SYSTEM_HANDLE_INFORMATIONtypedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO { USHORT UniqueProcessId; USHORT CreatorBackTraceIndex; UCHAR ObjectTypeIndex; UCHAR HandleAttributes; USHORT HandleValue; // 控制代碼 PVOID Object; // 若HANDLE類型為線程,則它是ETHREAD結構 ULONG GrantedAccess;} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;typedef struct _SYSTEM_HANDLE_INFORMATION { ULONG NumberOfHandles; SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;// SYSTEM_MODULE_INFORMATIONtypedef struct _SYSTEM_MODULE_INFORMATION {ULONGReserved[2];PVOIDBase;ULONGSize;ULONGFlags;USHORT Index;USHORT Unknown;USHORT LoadCount;USHORT ModuleNameOffset;CHAR ImageName[256];} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;typedef struct { ULONG dwNumberOfModules; SYSTEM_MODULE_INFORMATION smi;} MODULES, *PMODULES;// SYSTEM_BASIC_INFORMATIONtypedef struct _SYSTEM_BASIC_INFORMATION {ULONG Unknown; //Always contains zeroULONG MaximumIncrement; //一個時鐘的計量單位ULONG PhysicalPageSize; //一個記憶體頁的大小ULONG NumberOfPhysicalPages; //系統管理著多少個頁ULONG LowestPhysicalPage; //低端記憶體頁ULONG HighestPhysicalPage; //高端記憶體頁ULONG AllocationGranularity;ULONG LowestUserAddress; //地端使用者地址ULONG HighestUserAddress; //高端使用者地址ULONG ActiveProcessors; //啟用的處理器UCHAR NumberProcessors; //有多少個處理器} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;// SYSTEM_INFORMATION_CLASStypedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, SystemProcessorInformation, SystemPerformanceInformation, SystemTimeOfDayInformation, SystemPathInformation, SystemProcessInformation, SystemCallCountInformation, SystemDeviceInformation, SystemProcessorPerformanceInformation, SystemFlagsInformation, SystemCallTimeInformation, SystemModuleInformation, // 11 SystemLocksInformation, SystemStackTraceInformation, SystemPagedPoolInformation, SystemNonPagedPoolInformation, SystemHandleInformation, // 0x10 -- 16 SystemObjectInformation, SystemPageFileInformation, SystemVdmInstemulInformation, SystemVdmBopInformation, SystemFileCacheInformation, SystemPoolTagInformation, SystemInterruptInformation, SystemDpcBehaviorInformation, SystemFullMemoryInformation, SystemLoadGdiDriverInformation, SystemUnloadGdiDriverInformation, SystemTimeAdjustmentInformation, SystemSummaryMemoryInformation, SystemUnused1, SystemPerformanceTraceInformation, SystemCrashDumpInformation, SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, SystemContextSwitchInformation, SystemRegistryQuotaInformation, SystemExtendServiceTableInformation, SystemPrioritySeperation, SystemUnused3, SystemUnused4, SystemUnused5, SystemUnused6, SystemCurrentTimeZoneInformation, SystemLookasideInformation, SystemTimeSlipNotification, SystemSessionCreate, SystemSessionDetach, SystemSessionInformation} SYSTEM_INFORMATION_CLASS;#ifndef SECTION_INHERITtypedef enum _SECTION_INHERIT {ViewShare = 1,ViewUnmap = 2} SECTION_INHERIT;#endif#ifndef LUIDtypedef struct _LUID {DWORD LowPart;LONG HighPart;} LUID, *PLUID;#endif#ifndef LARGE_INTEGERtypedef union _LARGE_INTEGER { struct { ULONG LowPart; LONG HighPart; }; struct { ULONG LowPart; LONG HighPart; } u; LONGLONG QuadPart;} LARGE_INTEGER, *PLARGE_INTEGER;#endif#ifndef TIME_FIELDStypedef struct _TIME_FIELDS { USHORT Year; USHORT Month; USHORT Day; USHORT Hour; USHORT Minute; USHORT Second; USHORT Milliseconds; USHORT Weekday;} TIME_FIELDS, *PTIME_FIELDS;#endifNTSTATUSNTAPIZwQuerySystemInformation( DWORD SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength );NTSYSAPINTSTATUSNTAPINtOpenFile( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions );NTSYSAPI VOID NTAPI RtlInitUnicodeString( PUNICODE_STRING DestinationString, PCWSTR SourceString ); NTSYSAPI NTSTATUS NTAPI ZwOpenSection( OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES objectAttributes ); NTSYSAPI NTSTATUS NTAPI ZwMapViewOfSection( IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG ZeroBits, IN ULONG CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PULONG ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect ); NTSYSAPINTSTATUSNTAPINtCreateSection( PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize OPTIONAL, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle ); NTSYSAPI NTSTATUS NTAPI ZwUnmapViewOfSection( IN HANDLE ProcessHandle, IN PVOID BaseAddress ); NTSYSAPINTSTATUSNTAPINtReadFile( IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PULONG Key OPTIONAL );NTSYSAPI VOIDNTAPIRtlTimeToTimeFields( IN PLARGE_INTEGER Time, OUT PTIME_FIELDS TimeFields );NTSYSAPI BOOLEANNTAPIRtlTimeFieldsToTime( IN PTIME_FIELDS TimeFields, OUT PLARGE_INTEGER Time );/*VOIDNTAPIKeSetSystemTime( IN PLARGE_INTEGER NewTime, OUT PLARGE_INTEGER OldTime, IN BOOLEAN FixInterruptTime, IN PLARGE_INTEGER HalTime OPTIONAL );*/NTSTATUSNTAPINtQuerySystemTime ( OUT PLARGE_INTEGER SystemTime );// 防寫保護的開&關void WPOFF(){__asm { //去掉記憶體保護climov eax,cr0and eax,not 10000hmov cr0,eax}}void WPON(){__asm { //恢複記憶體保護 mov eax,cr0or eax,10000hmov cr0,eaxsti} }////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef __cplusplus}#endif#endif