📄 pdebug.c
字号:
switch (de.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
HandleBreakPoint(lpDbgProcess, de.dwThreadId);
SetStatusText (lpDbgProcess->hWnd,
IDS_BREAKPOINTEXCEPTION,
RGB (0, 0xff, 0));
/* post message to get ball rolling in main thread */
PostMessage (lpDbgProcess->hWnd,
WM_COMMAND,
IDM_PROCESSREWALK,
0);
break;
case EXCEPTION_ACCESS_VIOLATION:
/* record exception information */
SetStatusText (lpDbgProcess->hWnd,
IDS_ACCESSVIOLATIONEXCEPTION,
RGB (0xff, 0, 0));
RecordException (lpDbgProcess, &de);
break;
default:
SetStatusText (lpDbgProcess->hWnd,
IDS_UNHANDLEDEXCEPTION,
RGB (0xff, 0, 0));
RecordException (lpDbgProcess, &de);
break;
}
break;
case RIP_EVENT:
SetStatusText (lpDbgProcess->hWnd,
IDS_RIPEVENT,
RGB (0, 0xff, 0));
break;
case OUTPUT_DEBUG_STRING_EVENT:
SetStatusText (lpDbgProcess->hWnd,
IDS_OUTPUTDEBUGSTRING,
RGB (0, 0xff, 0));
break;
default:
break;
}
}
if(de.u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT)
ContinueDebugEvent (de.dwProcessId, de.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
else
ContinueDebugEvent (de.dwProcessId, de.dwThreadId, DBG_CONTINUE);
}
break;
}
}
return TRUE;
}
void WINAPI SuspendDebuggeeProcess (
DBGPROCESS *lppr)
{
DBGTHREAD *lpth = (DBGTHREAD *)lppr->lpThreads;
while (lpth)
{
SuspendThread (lpth->hThread);
lpth = (DBGTHREAD *)lpth->Next;
}
/* inform user via status bar */
SetStatusText (lppr->hWnd, IDS_PROCESSSUSPENDED, RGB (0xff, 0, 0));
lppr->bActive = FALSE;
}
void WINAPI ResumeDebuggeeProcess (
DBGPROCESS *lppr)
{
DBGTHREAD *lpth = (DBGTHREAD *)lppr->lpThreads;
while (lpth)
{
ResumeThread (lpth->hThread);
lpth = (DBGTHREAD *)lpth->Next;
}
/* inform user via status bar */
SetStatusText (lppr->hWnd, IDS_PROCESSRESUMED, RGB (0, 0xff, 0));
lppr->bActive = TRUE;
}
void WINAPI AddThreadNode (
DBGPROCESS *lppr,
DWORD dwThreadID,
HANDLE hThread,
int nPriority,
LPTHREAD_START_ROUTINE lpStart,
HANDLE hFile)
{
DBGTHREAD *lpth;
DBGTHREAD *pNode = lppr->lpThreads;
/* allocate thread node off heap */
lpth = (DBGTHREAD *)HeapAlloc (lppr->hDbgHeap, 0, sizeof (DBGTHREAD));
/* initialize thread data */
lpth->lpStartAddress = lpStart;
lpth->nPriority = nPriority;
lpth->dwThreadID = dwThreadID;
lpth->hThread = hThread;
lpth->Next = NULL;
/* retieve section names for executable module if file handle passed */
if (hFile)
{
RetrieveModuleName (lppr->szModule, hFile);
lppr->lpSection = NULL;
RetrieveSectionNames (lppr->hDbgHeap, hFile, &(lppr->lpSection));
}
/* set linked list pointers */
while (pNode && pNode->Next)
pNode = (DBGTHREAD *)pNode->Next;
if (!pNode)
lppr->lpThreads = lpth;
else
(DBGTHREAD *)pNode->Next = lpth;
}
void WINAPI RemoveThreadNode (
DBGPROCESS *lppr,
DWORD dwThreadID)
{
DBGTHREAD *pNode = lppr->lpThreads;
DBGTHREAD *lpth;
while (pNode->Next &&
((DBGTHREAD *)(pNode->Next))->dwThreadID != dwThreadID)
pNode = (DBGTHREAD *)pNode->Next;
if (pNode->Next)
{
lpth = (DBGTHREAD *)pNode->Next;
pNode->Next = ((DBGTHREAD *)(pNode->Next))->Next;
CloseHandle (lpth->hThread);
HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpth);
}
else if (pNode->dwThreadID == dwThreadID)
{
lpth = pNode;
lppr->lpThreads = NULL;
CloseHandle (lpth->hThread);
HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpth);
}
}
/* find a thread's handle based on thread ID */
HANDLE WINAPI FindThreadHandle (
DBGPROCESS *lppr,
DWORD dwThreadId)
{
DBGTHREAD *pNode = lppr->lpThreads;
while (pNode != NULL)
if (pNode->dwThreadID == dwThreadId)
return (pNode->hThread);
return NULL;
}
void WINAPI AddDllNode (
DBGPROCESS *lppr,
LOAD_DLL_DEBUG_INFO *lpdbgDll)
{
DBGDLL *lpdll;
DBGDLL *pNode = lppr->lpDlls;
/* allocate Dll node off heap */
if ((lpdll = (DBGDLL *)HeapAlloc (lppr->hDbgHeap, 0, sizeof (DBGDLL))) == NULL)
ReportError (IDS_ERRHEAPALLOC);
/* initialize Dll structure */
lpdll->hFile = lpdbgDll->hFile;
lpdll->lpBaseOfDll = lpdbgDll->lpBaseOfDll;
lpdll->dwDebugInfoFileOffset = lpdbgDll->dwDebugInfoFileOffset;
lpdll->nDebugInfoSize = lpdbgDll->nDebugInfoSize;
lpdll->fUnicode = lpdbgDll->fUnicode;
lpdll->Next = NULL;
lpdll->lpSection = NULL;
RetrieveModuleName (lpdll->szImageName, lpdbgDll->hFile);
/* get section names for DLL */
RetrieveSectionNames (lppr->hDbgHeap, lpdbgDll->hFile, &(lpdll->lpSection));
/* set linked list pointers */
while (pNode && pNode->Next)
pNode = (DBGDLL *)pNode->Next;
if (!pNode)
lppr->lpDlls = lpdll;
else
(DBGDLL *)pNode->Next = lpdll;
}
void WINAPI RemoveDllNode (
DBGPROCESS *lppr,
LOAD_DLL_DEBUG_INFO *lpdbgDll)
{
DBGDLL *pNode = lppr->lpDlls;
DBGDLL *lpdll;
SECTIONINFO *pSection, *pNext;
while (pNode->Next &&
((DBGDLL *)(pNode->Next))->lpBaseOfDll != lpdbgDll->lpBaseOfDll)
pNode = (DBGDLL *)pNode->Next;
if (pNode->Next)
{
lpdll = (DBGDLL *)pNode->Next;
pNode->Next = ((DBGDLL *)(pNode->Next))->Next;
pSection = pNext = lpdll->lpSection;
while (pNext)
{
pNext = (SECTIONINFO *)pSection->Next;
HeapFree (lppr->hDbgHeap, 0, (LPSTR)pSection);
pSection = pNext;
}
HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpdll);
}
else if (pNode->lpBaseOfDll == lpdbgDll->lpBaseOfDll)
{
lpdll = pNode;
lppr->lpDlls = NULL;
pSection = pNext = lpdll->lpSection;
while (pNext)
{
pNext = (SECTIONINFO *)pSection->Next;
HeapFree (lppr->hDbgHeap, 0, (LPSTR)pSection);
pSection = pNext;
}
HeapFree (lppr->hDbgHeap, 0, (LPSTR)lpdll);
}
}
void WINAPI RecordException (
DBGPROCESS *lppr,
DEBUG_EVENT *de)
{
DBGEXCEPTREC *lper;
DBGEXCEPTREC *per = lppr->lpERs;
HANDLE hThread;
int i;
/* allocate Dll node off heap */
if ((lper = (DBGEXCEPTREC *)HeapAlloc (lppr->hDbgHeap, 0, sizeof (DBGEXCEPTREC))) == NULL)
ReportError (IDS_ERRHEAPALLOC);
/* initialize exception record structure */
lper->dwThreadId = de->dwThreadId;
lper->dwFirstChance = de->u.Exception.dwFirstChance;
lper->ExceptRecord.ExceptionCode = de->u.Exception.ExceptionRecord.ExceptionCode;
lper->ExceptRecord.ExceptionFlags = de->u.Exception.ExceptionRecord.ExceptionFlags;
lper->ExceptRecord.ExceptionRecord = NULL;
lper->ExceptRecord.ExceptionAddress = de->u.Exception.ExceptionRecord.ExceptionAddress;
lper->ExceptRecord.NumberParameters = de->u.Exception.ExceptionRecord.NumberParameters;
for (i=0; i<EXCEPTION_MAXIMUM_PARAMETERS; i++)
lper->ExceptRecord.ExceptionInformation[i] =
de->u.Exception.ExceptionRecord.ExceptionInformation[i];
/* get exception thread handle */
hThread = FindThreadHandle (lppr, de->dwThreadId);
lper->Context.ContextFlags = CONTEXT_CONTROL;
GetThreadContext (hThread, &(lper->Context));
/* set linked list pointers */
while (per && per->Next)
per = (DBGEXCEPTREC *)per->Next;
if (!per)
lppr->lpERs = lper;
else
(DBGEXCEPTREC *)per->Next = lper;
}
/*
* MIPS/ALPHA/PPC must increment the FIR/Iar on a breakpoint
* in order to fetch the next instruction
*/
int WINAPI HandleBreakPoint(
DBGPROCESS *lppr,
DWORD dwThreadID
)
{
CONTEXT ThreadContext;
DBGTHREAD *pNode = lppr->lpThreads;
HANDLE hThread;
while (pNode && pNode->dwThreadID != dwThreadID)
pNode = (DBGTHREAD *)pNode->Next;
if(!pNode)
return(0);
else
{
hThread = (HANDLE) pNode->hThread;
ThreadContext.ContextFlags = CONTEXT_CONTROL;
if (!GetThreadContext (hThread, &ThreadContext))
{
ReportError (IDS_ERRGETTHREADCONTEXT);
return(0);
}
#ifdef _PPC_
ThreadContext.Iar += 4;
#elif !defined _X86_
ThreadContext.Fir += 4;
#endif
if (!SetThreadContext (hThread, &ThreadContext))
{
ReportError (IDS_ERRSETTHREADCONTEXT);
return (0);
}
return (1);
}
}
int WINAPI WhereIsStack (
HANDLE hThreadContext)
{
CONTEXT ThreadContext;
ThreadContext.ContextFlags = CONTEXT_CONTROL;
if (!GetThreadContext (hThreadContext, &ThreadContext))
ReportError (IDS_ERRGETTHREADCONTEXT);
#ifdef _X86_
return ThreadContext.Esp;
#elif defined (_PPC_)
return (int) ThreadContext.Gpr1;
#else /* _MIPS_ */
return (int) ThreadContext.IntSp;
#endif
}
/* function walks memory regions of process */
int WINAPI WalkProcess (
HANDLE hChildProcess,
LPVOID *lpWalk,
LPINT *lpObjects)
{
LPVMOBJECT lpList;
LPVOID lpMem = 0;
LPVOID lpStack = 0;
int nCnt, i;
SYSTEM_INFO si;
/* if pointer exists, reset to no commit */
if (*lpWalk)
{
if (!VirtualFree (*lpWalk, 0, MEM_DECOMMIT))
ReportError (IDS_ERRVIRTUALFREE);
}
/* else perform initial reserve */
else
if ((*lpWalk = VirtualAlloc (NULL,
TOTALVMRESERVE,
MEM_RESERVE,
PAGE_NOACCESS)) == NULL)
ReportError (IDS_ERRVIRTUALALLOC);
/* initialize list pointer to beginning of walker list */
lpList = (LPVMOBJECT)*lpWalk;
/* Get maximum address range from system info */
GetSystemInfo(&si);
/* walk process addresses */
while (lpMem < si.lpMaximumApplicationAddress)
{
try /* virtual memory exception handler automatically commits mem */
{
/* touch memory in VMOBJECT structure that exists after mbi field to trigger
access violation for a new page of memory. Do this here since VirtualQueryEx
does not seem to generate exceptions, rather it just fails calls */
*lpList->szObjType = 0;
*lpList->szModule = 0;
*lpList->szSection = 0;
lpList->bNew = 0;
VirtualQueryEx (hChildProcess,
lpMem,
&(lpList->mbi),
sizeof (MEMORY_BASIC_INFORMATION));
/* increment lpMem to next region of memory */
lpMem = (LPVOID)((DWORD)lpList->mbi.BaseAddress +
(DWORD)lpList->mbi.RegionSize);
lpList++;
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
{
/* commit next page of walker list memory */
if (((int)lpList + 4096) < (int)*lpWalk + TOTALVMRESERVE)
VirtualAlloc ((LPVOID)((int)lpList + sizeof (VMOBJECT)),
4096,
MEM_COMMIT,
PAGE_READWRITE);
else
{
NotifyUser (NULL,
IDS_ERROR,
IDS_NOTENOUGHMEM,
" reserved for Objects",
MB_OK);
return 0;
}
}
}
/* allocate objects index array */
if (*lpObjects)
LocalFree (*lpObjects);
nCnt = (((int)(LPVOID)lpList)-(int)*lpWalk)/sizeof (VMOBJECT);
*lpObjects = LocalAlloc (LPTR, nCnt * sizeof (int));
for (i=0; i<nCnt; i++)
(*lpObjects)[i] = i;
/* return number of item in list */
return (nCnt);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -