生活随笔
收集整理的這篇文章主要介紹了
5.内存断点
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
原理就是對(duì)所設(shè)地址的屬性設(shè)置為不可讀不可寫屬性,這樣當(dāng)這個(gè)地址被訪問(wèn)或?qū)懭刖蜁?huì)產(chǎn)生異常。
BOOL
VirtualProtectEx(IN HANDLE hProcess
,IN LPVOID lpAddress
,IN SIZE_T dwSize
,IN DWORD flNewProtect
,OUT PDWORD lpflOldProtect
)將被調(diào)試進(jìn)程的某內(nèi)存屬性修改為
:
PAGE_NOACCESS
PAGE_EXECUTE_READ
被調(diào)試進(jìn)程
CPU訪問(wèn)錯(cuò)誤內(nèi)存地址,觸發(fā)頁(yè)異常查IDT表找到對(duì)應(yīng)的中斷處理函數(shù) nt !_KiTrap0E (E號(hào)中斷)ConmonDispatchErceptioKiDispatchExceptionDbgkFPorwardException收集并發(fā)送調(diào)試事件
DbgkpSendApillessage(x
, x
)
1)第一個(gè)參數(shù)
:消息結(jié)構(gòu) 每種消息都有自己的消息結(jié)構(gòu)共有
7種類型
.
2)第二個(gè)參數(shù)
,要不要把本進(jìn)程內(nèi)除了自己之外的其他線程掛起
.有些消息需要把其他線程掛起
,比如異常
typedef HANDLE(__stdcall
*pMyOpenThread
)(
DWORD dwDesiredAccess
, BOOL bInheritHandle
, DWORD dwThreadId
);
HANDLE hDebuggeeProcess
= NULL;
HANDLE hDebuggeeThread
;DWORD dwOriginalProtect
;
CONTEXT Context
= { 0 };BOOL
WaitForUserCommand()
{BOOL bRet
= FALSE
;char cContext
;printf("COMMAND> ");cContext
= getchar();switch (cContext
){case 't':bRet
= TRUE
;break;case 'p':bRet
= TRUE
;break;case 'g':bRet
= TRUE
;break;}return bRet
;
}BOOL
AccessExceptionProce(EXCEPTION_DEBUG_INFO
* excp
)
{BOOL bRet
= FALSE
;DWORD dwAccessFlag
; DWORD dwAccessAddr
; dwAccessFlag
= excp
->ExceptionRecord
.ExceptionInformation
[0];dwAccessAddr
= excp
->ExceptionRecord
.ExceptionInformation
[1];printf("內(nèi)存斷點(diǎn):%X %X\n", dwAccessFlag
, dwAccessAddr
);VirtualProtectEx(hDebuggeeProcess
, (PVOID
)dwAccessAddr
, 1, dwOriginalProtect
, &dwOriginalProtect
);Context
.ContextFlags
= CONTEXT_FULL
|| CONTEXT_DEBUG_REGISTERS
;GetThreadContext(hDebuggeeThread
, &Context
);SetThreadContext(hDebuggeeThread
, &Context
);while (bRet
== FALSE
){bRet
= WaitForUserCommand();}return bRet
;
}BOOL
ExceptionHandler(DEBUG_EVENT
* pDebugEvent
)
{BOOL bRet
= TRUE
;EXCEPTION_DEBUG_INFO
* pExceptionInfo
= NULL;pExceptionInfo
= &pDebugEvent
->u
.Exception
;pMyOpenThread MyOpenThread
= (pMyOpenThread
)GetProcAddress(LoadLibrary(L
"Kernel32.dll"),"OpenThread");hDebuggeeThread
= MyOpenThread(THREAD_ALL_ACCESS
,FALSE
,pDebugEvent
->dwThreadId
);if (pExceptionInfo
->ExceptionRecord
.ExceptionCode
== EXCEPTION_ACCESS_VIOLATION
){bRet
= AccessExceptionProce(pExceptionInfo
);}return bRet
;
}VOID
SetMemBreakPoint(LPVOID addr
)
{VirtualProtectEx(hDebuggeeProcess
,addr
,1,PAGE_NOACCESS
,&dwOriginalProtect
);}void CALL()
{BOOL nIsConinue
= TRUE
;DEBUG_EVENT debugEvent
= { 0 };DWORD dwContext
= DBG_CONTINUE
;STARTUPINFO startupInfo
= { 0 };PROCESS_INFORMATION pInfo
= { 0 };GetStartupInfo(&startupInfo
);WCHAR
* _ProcessName
= { L
"C:\\Users\\Administrator\\Desktop\\控制臺(tái)測(cè)試\\Debug\\Dbgview.exe" };BOOL bRet
= CreateProcess(_ProcessName
, NULL, NULL, NULL, TRUE
, DEBUG_PROCESS
|| DEBUG_ONLY_THIS_PROCESS
, NULL, NULL, &startupInfo
, &pInfo
);if (bRet
== FALSE
){printf("CreateProcess error:%d\n", GetLastError());return;}hDebuggeeProcess
= pInfo
.hProcess
;while (nIsConinue
){BOOL bRet
= WaitForDebugEvent(&debugEvent
, INFINITE
);if (!bRet
){printf("WaitForDebugEvent error:%d\n", GetLastError());return;}switch (debugEvent
.dwDebugEventCode
){case EXCEPTION_DEBUG_EVENT
:bRet
= ExceptionHandler(&debugEvent
);if (!bRet
)dwContext
= DBG_EXCEPTION_NOT_HANDLED
;break;case CREATE_THREAD_DEBUG_EVENT
:break;case CREATE_PROCESS_DEBUG_EVENT
:SetMemBreakPoint((PCHAR
)debugEvent
.u
.CreateProcessInfo
.lpStartAddress
);break;case EXIT_THREAD_DEBUG_EVENT
:break;case EXIT_PROCESS_DEBUG_EVENT
:break;case LOAD_DLL_DEBUG_EVENT
:break;case UNLOAD_DLL_DEBUG_EVENT
:break;}bRet
= ContinueDebugEvent(debugEvent
.dwProcessId
, debugEvent
.dwThreadId
, DBG_CONTINUE
);}}
總結(jié)
以上是生活随笔為你收集整理的5.内存断点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。