windows监视内存读写

来源:互联网 发布:新西兰汉密尔顿 知乎 编辑:程序博客网 时间:2024/05/07 04:52

memexcept.c

#define _WIN32_WINNT 0x500#include<windows.h>#include"memexcept.h"#define roundup(x,n) (((x)+((n)-1))&(~((n)-1)))#define rounddown(x,n) ((x)&(~((n)-1)))#define BusyWait(x) while(InterlockedCompareExchange((void**)&(x),0,0))SwitchToThread()#define Acquire(x) while(InterlockedExchange(&(x),1))SwitchToThread()#define Release(x) InterlockedExchange(&(x),0)typedef PVOID(WINAPI*PAddVectoredExceptionHandler)(ULONG FirstHandler,PVOID VectoredHandler);typedef ULONG(WINAPI*PRemoveVectoredExceptionHandler)(PVOID Handler);static PAddVectoredExceptionHandler pAddVectoredExceptionHandler=0;static PRemoveVectoredExceptionHandler pRemoveVectoredExceptionHandler=0;typedef struct _ADDRRANGE{struct _ADDRRANGE*Next,*Previous;char*ProtectStart,*ProtectEnd,*WatchStart,*WatchEnd;DWORD OldProtect;PMemoryWatchCallback Callback;BOOL NotifyAfterRead:1,NotifyAfterWrite:1,Pending:1,Enabled:1,IsWrite:1;void*Address;UINT_PTR Tag;CRITICAL_SECTION CriticalSection;}ADDRRANGE,*PADDRRANGE;static SYSTEM_INFO SystemInfo;static PVOID HandlerHandle=0,RangeHeap=0;static PADDRRANGE RangeListHead=0;static LONG RangeListRead=0,RangeListWrite=0;BOOL CanRead(void*Address){__try{*(volatile char*)Address;return TRUE;}__except(EXCEPTION_EXECUTE_HANDLER){return FALSE;}}BOOL CanWrite(void*Address){__try{*(volatile char*)Address=*(volatile char*)Address;return TRUE;}__except(EXCEPTION_EXECUTE_HANDLER){return FALSE;}}HANDLE RegisterMemoryWatcher(PVOID BaseAddress,SIZE_T Length,PMemoryWatchCallback Callback,BOOL NotifyAfterRead,BOOL NotifyAfterWrite,UINT_PTR Tag){PADDRRANGE range;range=HeapAlloc(RangeHeap,0,sizeof(ADDRRANGE));if(range){range->Previous=0;range->Next=RangeListHead;range->WatchStart=(char*)BaseAddress;range->WatchEnd=(char*)BaseAddress+Length;range->ProtectStart=(char*)rounddown((SIZE_T)BaseAddress,SystemInfo.dwPageSize);range->ProtectEnd=(char*)roundup((SIZE_T)BaseAddress+Length,SystemInfo.dwPageSize);range->Callback=Callback;range->NotifyAfterRead=NotifyAfterRead;range->NotifyAfterWrite=NotifyAfterWrite;range->Pending=0;range->Enabled=1;range->Tag=Tag;InitializeCriticalSection(&range->CriticalSection);if(VirtualProtectEx(GetCurrentProcess(),BaseAddress,Length,PAGE_NOACCESS,&range->OldProtect)){if(RangeListHead)RangeListHead->Previous=range;RangeListHead=range;return (HANDLE)range;}else{DeleteCriticalSection(&range->CriticalSection);HeapFree(RangeHeap,0,range);}}return NULL;}VOID UnregisterMemoryWatcher(HANDLE Handle){PADDRRANGE range;if(Handle){range=(PADDRRANGE)Handle;VirtualProtectEx(GetCurrentProcess(),range->WatchStart,range->WatchEnd-range->WatchStart,range->OldProtect,&range->OldProtect);Acquire(RangeListWrite);BusyWait(RangeListRead);if(range->Previous)range->Previous->Next=range->Next;if(range->Next)range->Next->Previous=range->Previous;DeleteCriticalSection(&range->CriticalSection);HeapFree(RangeHeap,0,range);Release(RangeListWrite);}}VOID EnableMemoryWatcher(HANDLE Handle,BOOL Enable){PADDRRANGE range;if(Handle){DWORD OldProtect;range=(PADDRRANGE)Handle;if(range->Enabled=Enable)VirtualProtectEx(GetCurrentProcess(),range->WatchStart,range->WatchEnd-range->WatchStart,PAGE_NOACCESS,&OldProtect);else VirtualProtectEx(GetCurrentProcess(),range->WatchStart,range->WatchEnd-range->WatchStart,range->OldProtect,&OldProtect);}}LONG CALLBACK MemExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo){PEXCEPTION_RECORD ExceptionRecord;PCONTEXT Context;ExceptionRecord=ExceptionInfo->ExceptionRecord;Context=ExceptionInfo->ContextRecord;if(ExceptionRecord->ExceptionCode==EXCEPTION_ACCESS_VIOLATION){PADDRRANGE range;DWORD OldProtect;BOOLEAN Pending,Found=0;char*addr=(char*)ExceptionRecord->ExceptionInformation[1];Acquire(RangeListWrite);InterlockedIncrement(&RangeListRead);Release(RangeListWrite);for(range=RangeListHead;range;range=range->Next){if(addr>=range->ProtectStart&&addr<range->ProtectEnd){EnterCriticalSection(&range->CriticalSection);VirtualProtectEx(GetCurrentProcess(),range->WatchStart,range->WatchEnd-range->WatchStart,range->OldProtect,&OldProtect);Found=1;if(addr>=range->WatchStart&&addr<range->WatchEnd&&range->Enabled){range->IsWrite=(ExceptionRecord->ExceptionInformation[0]==1);range->Address=addr;if((!range->NotifyAfterRead&&!range->IsWrite)||(!range->NotifyAfterWrite&&range->IsWrite))if(range->Callback(range->Address,range->IsWrite,&range->Tag)){range->Enabled=0;LeaveCriticalSection(&range->CriticalSection);range->Pending=0;continue;}range->Pending=1;Pending=1;}}}InterlockedDecrement(&RangeListRead);if(Pending)Context->EFlags|=256;return Found?EXCEPTION_CONTINUE_EXECUTION:EXCEPTION_CONTINUE_SEARCH;}else if(ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP){PADDRRANGE range;DWORD OldProtect;Acquire(RangeListWrite);InterlockedIncrement(&RangeListRead);Release(RangeListWrite);for(range=RangeListHead;range;range=range->Next)if(range->Pending){if((range->NotifyAfterRead&&!range->IsWrite)||(range->NotifyAfterWrite&&range->IsWrite))range->Enabled=!range->Callback(range->Address,range->IsWrite,&range->Tag);VirtualProtectEx(GetCurrentProcess(),range->WatchStart,range->WatchEnd-range->WatchStart,PAGE_NOACCESS,&OldProtect);LeaveCriticalSection(&range->CriticalSection);range->Pending=0;}InterlockedDecrement(&RangeListRead);return EXCEPTION_CONTINUE_EXECUTION;}return EXCEPTION_CONTINUE_SEARCH;}BOOL StartupMemExcept(void){GetSystemInfo(&SystemInfo);RangeHeap=HeapCreate(0,0,0);if(!pAddVectoredExceptionHandler)pAddVectoredExceptionHandler=(PAddVectoredExceptionHandler)GetProcAddress(GetModuleHandleW(L"kernel32.dll"),"AddVectoredExceptionHandler");if(pAddVectoredExceptionHandler)HandlerHandle=pAddVectoredExceptionHandler((ULONG)-1,MemExceptionHandler);return HandlerHandle!=0;}BOOL CleanupMemExcept(void){BOOL r=FALSE;if(!pRemoveVectoredExceptionHandler)pRemoveVectoredExceptionHandler=(PRemoveVectoredExceptionHandler)GetProcAddress(GetModuleHandleW(L"kernel32.dll"),"RemoveVectoredExceptionHandler");if(pRemoveVectoredExceptionHandler)r=pRemoveVectoredExceptionHandler(HandlerHandle);if(r){PADDRRANGE range;Acquire(RangeListWrite);BusyWait(RangeListRead);for(range=RangeListHead;range;range=range->Next)VirtualProtectEx(GetCurrentProcess(),range->WatchStart,range->WatchEnd-range->WatchStart,range->OldProtect,&range->OldProtect);for(range=RangeListHead;range;range=range->Next){DeleteCriticalSection(&range->CriticalSection);}HeapDestroy(RangeHeap);Release(RangeListWrite);RangeListHead=0;RangeHeap=0;}return r;}


memexcept.h

typedef int(CALLBACK*PMemoryWatchCallback)(void*Address,BOOL Write,UINT_PTR*Tag);#ifdef __cplusplusextern"C"{#endifextern BOOL CanRead(void*Address);extern BOOL CanWrite(void*Address);extern BOOL StartupMemExcept(void);extern BOOL CleanupMemExcept(void);extern HANDLE RegisterMemoryWatcher(PVOID BaseAddress,SIZE_T Length,PMemoryWatchCallback Callback,BOOL NotifyAfterRead,BOOL NotifyAfterWrite,UINT_PTR Tag);extern VOID UnregisterMemoryWatcher(HANDLE Handle);extern VOID EnableMemoryWatcher(HANDLE Handle,BOOL Enable);#ifdef __cplusplus}#endif


main.cpp

#include<stdio.h>#include<windows.h>#include"memexcept.h"int CALLBACK cb(void*addr,BOOL w,UINT_PTR*Tag){int*p=(int*)addr;printf("address:%p,write:%d,value:%d\n",p,w,CanRead(&p)?*p:0);return 0;//return 1 to disable watcher}int main(){int(*p)[4];p=(int(*)[4])VirtualAlloc(0,sizeof(*p),MEM_COMMIT,PAGE_READWRITE);(*p)[0]=0;(*p)[1]=1;(*p)[2]=2;StartupMemExcept();//initializeRegisterMemoryWatcher(p,sizeof(*p),cb,FALSE,TRUE,0);printf("v:%d\n",(*p)[0]);printf("v:%d\n",(*p)[1]);puts("dd");__try{printf("v:%d\n",(*p)[2]);(*p)[3]=6;*(volatile char*)0;//not watched}__except(EXCEPTION_EXECUTE_HANDLER){puts("except");}CleanupMemExcept();//cleanupreturn 0;}

http://download.csdn.net/detail/lactoferrin/4091105

原创粉丝点击