📄 pdebug.c
字号:
#include "pwalk.h"
#include <memory.h>
/* module globals */
LPVOID PMAAddress;
LPVOID PMABuffer;
DWORD PMASize;
extern char szCurPath[MAX_PATH];
/* local debug functions */
BOOL WINAPI DebugEventThread (DBGPROCESS *);
BOOL WINAPI CreateDebugEvents (LPHANDLE);
void WINAPI AddThreadNode (DBGPROCESS *, DWORD, HANDLE, int, LPTHREAD_START_ROUTINE, HANDLE);
int WINAPI HandleBreakPoint(DBGPROCESS *, DWORD);
void WINAPI RemoveThreadNode (DBGPROCESS *, DWORD);
void WINAPI AddDllNode (DBGPROCESS *, LOAD_DLL_DEBUG_INFO *);
void WINAPI RemoveDllNode (DBGPROCESS *, LOAD_DLL_DEBUG_INFO *);
void WINAPI SuspendDebuggeeProcess (DBGPROCESS *);
void WINAPI ResumeDebuggeeProcess (DBGPROCESS *);
void WINAPI NameObjects (HANDLE, LPVOID, LPVMOBJECT, int, char *, char *);
BOOL WINAPI VMCompare (LPVMOBJECT, LPVMOBJECT);
BOOL WINAPI InterruptThread_HookProcess (DBGPROCESS *, LPPROCESS_STATE);
void WINAPI ResetInterruptedThread (DBGPROCESS *, LPPROCESS_STATE);
void WINAPI RecordException (DBGPROCESS *, DEBUG_EVENT *);
HANDLE WINAPI FindThreadHandle (DBGPROCESS *, DWORD);
/* start debug thread, and return event active handle */
DBGPROCESS* WINAPI StartChildProcess (
HWND hWnd,
char *lpszModule,
LPHANDLE lpDbgEvents)
{
DWORD TID;
HANDLE hDebugHeap;
DBGPROCESS *lpDbgProcess;
int i;
/* create unique debug events using debuggee process ID */
if (!CreateDebugEvents (lpDbgEvents))
return NULL;
/* create serialized heap of dynamic size */
if (!(hDebugHeap = HeapCreate (0, sizeof (DBGPROCESS) + sizeof (DBGTHREAD), 0)))
{
/* close all event handles */
for (i=0; i<nDEBUGEVENTS; i++)
CloseHandle (lpDbgEvents[i]);
return NULL;
}
/* allocate and initialize debug heap structure */
lpDbgProcess = (DBGPROCESS *)HeapAlloc (hDebugHeap, 0, sizeof (DBGPROCESS));
lpDbgProcess->hDbgHeap = hDebugHeap;
strcpy (lpDbgProcess->szModule, lpszModule);
lpDbgProcess->hWnd = hWnd;
lpDbgProcess->lpThreads = NULL;
lpDbgProcess->lpSection = NULL;
lpDbgProcess->lpERs = NULL;
/* create debug thread */
if (!(CreateThread ((LPSECURITY_ATTRIBUTES)NULL,
4096,
(LPTHREAD_START_ROUTINE)DebugEventThread,
(LPVOID)lpDbgProcess,
0,
&TID)))
return NULL;
/* wait 15 seconds for debugger to complete initialization, else error */
if (WAIT_TIMEOUT == WaitForSingleObject (lpDbgEvents[ACKNOWLEDGE], 15000))
{
HeapDestroy (lpDbgProcess->hDbgHeap);
/* close all event handles */
for (i=0; i<nDEBUGEVENTS; i++)
CloseHandle (lpDbgEvents[i]);
return NULL;
}
/* reset acknowledge event */
ResetEvent (lpDbgEvents[ACKNOWLEDGE]);
/* successfull thread and event start */
return lpDbgProcess;
}
/* function notifies debug thread to terminate, frees handles, and destroys heap */
void WINAPI CloseChildProcess (
DBGPROCESS *lpDbgProcess,
LPHANDLE lpDbgEvents)
{
int i;
DBGTHREAD *pNode = lpDbgProcess->lpThreads;
/* set close event for debug thread and wait for acknowledge */
SetEvent (lpDbgEvents[CLOSEDEBUGGER]);
WaitForSingleObject (lpDbgEvents[ACKNOWLEDGE], INFINITE);
/* close all event handles */
for (i=0; i<nDEBUGEVENTS; i++)
CloseHandle (lpDbgEvents[i]);
/* close all thread handles in the list */
while (pNode != NULL)
{
RemoveThreadNode (lpDbgProcess, pNode->dwThreadID);
pNode = lpDbgProcess->lpThreads;
}
/* destroy the debug heap */
HeapDestroy (lpDbgProcess->hDbgHeap);
}
/* local function creates debug event objects for thread synchronization */
BOOL WINAPI CreateDebugEvents (
LPHANDLE lpDbgEvents)
{
char szEvent[MAX_PATH];
LoadString (GetModuleHandle (NULL), IDS_DBGEVNTACTIVE, szEvent, sizeof (szEvent));
if (!(lpDbgEvents[DEBUGACTIVE] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
TRUE,
TRUE,
szEvent)))
return FALSE;
LoadString (GetModuleHandle (NULL), IDS_DBGEVNTCLOSE, szEvent, sizeof (szEvent));
if (!(lpDbgEvents[CLOSEDEBUGGER] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
TRUE,
FALSE,
szEvent)))
{
CloseHandle (lpDbgEvents[DEBUGACTIVE]);
return FALSE;
}
LoadString (GetModuleHandle (NULL), IDS_DBGEVNTSTOP, szEvent, sizeof (szEvent));
if (!(lpDbgEvents[SUSPENDDEBUGGER] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
TRUE,
FALSE,
szEvent)))
{
CloseHandle (lpDbgEvents[DEBUGACTIVE]);
CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
return FALSE;
}
LoadString (GetModuleHandle (NULL), IDS_DBGEVNTSTART, szEvent, sizeof (szEvent));
if (!(lpDbgEvents[RESUMEDEBUGGER] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
TRUE,
FALSE,
szEvent)))
{
CloseHandle (lpDbgEvents[DEBUGACTIVE]);
CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
return FALSE;
}
LoadString (GetModuleHandle (NULL), IDS_DBGEVNTREAD, szEvent, sizeof (szEvent));
if (!(lpDbgEvents[READMEMORY] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
TRUE,
FALSE,
szEvent)))
{
CloseHandle (lpDbgEvents[DEBUGACTIVE]);
CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
CloseHandle (lpDbgEvents[RESUMEDEBUGGER]);
return FALSE;
}
LoadString (GetModuleHandle (NULL), IDS_DBGEVNTWRITE, szEvent, sizeof (szEvent));
if (!(lpDbgEvents[WRITEMEMORY] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
TRUE,
FALSE,
szEvent)))
{
CloseHandle (lpDbgEvents[DEBUGACTIVE]);
CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
CloseHandle (lpDbgEvents[RESUMEDEBUGGER]);
CloseHandle (lpDbgEvents[READMEMORY]);
return FALSE;
}
LoadString (GetModuleHandle (NULL), IDS_DBGEVNTACK, szEvent, sizeof (szEvent));
if (!(lpDbgEvents[ACKNOWLEDGE] = CreateEvent ((LPSECURITY_ATTRIBUTES)NULL,
TRUE,
FALSE,
szEvent)))
{
CloseHandle (lpDbgEvents[DEBUGACTIVE]);
CloseHandle (lpDbgEvents[CLOSEDEBUGGER]);
CloseHandle (lpDbgEvents[SUSPENDDEBUGGER]);
CloseHandle (lpDbgEvents[RESUMEDEBUGGER]);
CloseHandle (lpDbgEvents[READMEMORY]);
CloseHandle (lpDbgEvents[WRITEMEMORY]);
return FALSE;
}
/* success */
return TRUE;
}
/* main daddyo thread that is the debugger residing over a debuggee */
BOOL WINAPI DebugEventThread (
DBGPROCESS *lpDbgProcess)
{
DEBUG_EVENT de;
HANDLE hDbgEvent[nDEBUGEVENTS];
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE hChildProcess;
BOOL bHooked, bUnHooked;
// PROCESS_STATE ProcessState;
bHooked = FALSE;
bUnHooked = FALSE;
/* initialize process startup information */
si.cb = sizeof (si);
si.lpReserved = NULL;
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwX = 0;
si.dwY = 0;
si.dwXSize = 0;
si.dwYSize = 0;
si.dwXCountChars = 0;
si.dwYCountChars = 0;
si.dwFillAttribute = 0;
si.dwFlags = STARTF_FORCEONFEEDBACK | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOWNORMAL;
si.cbReserved2 = 0;
si.lpReserved2 = NULL;
/* create debug process on module name */
if (!CreateProcess (lpDbgProcess->szModule,
NULL,
(LPSECURITY_ATTRIBUTES)NULL,
(LPSECURITY_ATTRIBUTES)NULL,
FALSE,
DEBUG_PROCESS,
NULL,
NULL,
(LPSTARTUPINFO)&si,
(LPPROCESS_INFORMATION)&pi))
{
ReportError (IDS_ERRCREATEPROCESS);
return FALSE;
}
/* open process for all access */
if ((hChildProcess = OpenProcess (PROCESS_ALL_ACCESS,
FALSE,
pi.dwProcessId)) == NULL)
{
ReportError (IDS_ERROPENPROCESS);
TerminateProcess (pi.hProcess, 0);
return FALSE;
}
/* store process info */
lpDbgProcess->hProcess = hChildProcess;
lpDbgProcess->dwPriority = GetPriorityClass (pi.hProcess);
lpDbgProcess->dwProcessID = pi.dwProcessId;
lpDbgProcess->bActive = TRUE;
/* close process and thread handles in pi structure */
CloseHandle (pi.hThread);
CloseHandle (pi.hProcess);
/* open debug events */
CreateDebugEvents (hDbgEvent);
/* signale completion of task */
SetEvent (hDbgEvent[ACKNOWLEDGE]);
/* start debug event loop */
while (TRUE)
{
int nIndex;
/* wait for debugger active */
switch (nIndex = WaitForMultipleObjects (nDEBUGEVENTS, hDbgEvent, FALSE, INFINITE))
{
case CLOSEDEBUGGER:
{
int i;
/* terminate debuggee process */
TerminateProcess (lpDbgProcess->hProcess, 0);
CloseHandle (lpDbgProcess->hProcess);
/* signal completion of task */
SetEvent (hDbgEvent[ACKNOWLEDGE]);
/* close all debug events */
for (i=0; i<nDEBUGEVENTS; i++)
CloseHandle (hDbgEvent[i]);
/* exit debugger now */
return TRUE;
}
break;
case SUSPENDDEBUGGER:
SuspendDebuggeeProcess (lpDbgProcess);
ResetEvent (hDbgEvent[DEBUGACTIVE]);
ResetEvent (hDbgEvent[SUSPENDDEBUGGER]);
break;
case RESUMEDEBUGGER:
ResumeDebuggeeProcess (lpDbgProcess);
SetEvent (hDbgEvent[DEBUGACTIVE]);
ResetEvent (hDbgEvent[RESUMEDEBUGGER]);
break;
case READMEMORY:
{
MEMORY_BASIC_INFORMATION mbi;
DWORD Protect = 0;
/* reset event so we don't do repeat */
ResetEvent (hDbgEvent [READMEMORY]);
/* if not committed memory abort */
if (!VirtualQueryEx (lpDbgProcess->hProcess,
PMAAddress,
&mbi,
sizeof (MEMORY_BASIC_INFORMATION)) ||
mbi.State != MEM_COMMIT)
{
PMASize = 0;
SetEvent (hDbgEvent [ACKNOWLEDGE]);
break;
}
/* if guarded memory, change protection temporarily */
if (!(mbi.Protect & PAGE_READONLY) &&
!(mbi.Protect & PAGE_READWRITE))
VirtualProtectEx (lpDbgProcess->hProcess,
PMAAddress,
PMASize,
PAGE_READONLY,
&Protect);
if (!ReadProcessMemory (lpDbgProcess->hProcess,
PMAAddress,
PMABuffer,
PMASize,
NULL))
{
if (mbi.AllocationProtect != PAGE_READONLY &&
mbi.AllocationProtect != PAGE_READWRITE)
NotifyUser (NULL, IDS_ERROR, 0, "BaseProtect NOACCESS", 0);
else
{
ReportError (IDS_ERRREADPROCESSMEMORY);
PMASize = 0;
}
}
/* reset protection if changed */
if (Protect)
VirtualProtectEx (lpDbgProcess->hProcess,
PMAAddress,
PMASize,
Protect,
&Protect);
/* acknowledge success */
SetEvent (hDbgEvent [ACKNOWLEDGE]);
}
break;
case WRITEMEMORY:
if (!WriteProcessMemory (lpDbgProcess->hProcess,
PMAAddress,
PMABuffer,
PMASize,
NULL))
{
ReportError (IDS_ERRWRITEPROCESSMEMORY);
PMASize = 0;
}
ResetEvent (hDbgEvent [WRITEMEMORY]);
SetEvent (hDbgEvent [ACKNOWLEDGE]);
break;
case DEBUGACTIVE:
/* if debug active */
if ((WaitForDebugEvent (&de, (DWORD)100)))
{
if (de.dwProcessId == lpDbgProcess->dwProcessID)
{
switch (de.dwDebugEventCode)
{
case EXIT_PROCESS_DEBUG_EVENT:
SetStatusText (lpDbgProcess->hWnd, IDS_EXITPROCESS, 0);
/* uninitialize probe dll */
ResetProbe ();
/* process is going away so notify main window */
SendNotifyMessage (lpDbgProcess->hWnd,
WM_COMMAND,
IDM_PROCESSUNLOAD,
0);
break;
case LOAD_DLL_DEBUG_EVENT:
SetStatusText (lpDbgProcess->hWnd, IDS_LOADDLL, 0);
AddDllNode (lpDbgProcess,
(LOAD_DLL_DEBUG_INFO *)&(de.u.LoadDll));
break;
case UNLOAD_DLL_DEBUG_EVENT:
SetStatusText (lpDbgProcess->hWnd, IDS_UNLOADDLL, 0);
RemoveDllNode (lpDbgProcess,
(LOAD_DLL_DEBUG_INFO *)&(de.u.LoadDll));
break;
case CREATE_PROCESS_DEBUG_EVENT:
SetStatusText (lpDbgProcess->hWnd, IDS_CREATEPROCESS, 0);
/* add first thread to linked list of dbg structures */
AddThreadNode (lpDbgProcess,
de.dwThreadId,
de.u.CreateProcessInfo.hThread,
GetThreadPriority (de.u.CreateProcessInfo.hThread),
de.u.CreateProcessInfo.lpStartAddress,
de.u.CreateProcessInfo.hFile);
lpDbgProcess->hFile = de.u.CreateProcessInfo.hFile;
lpDbgProcess->lpImage = de.u.CreateProcessInfo.lpBaseOfImage;
lpDbgProcess->dwDbgInfoOffset = de.u.CreateProcessInfo.dwDebugInfoFileOffset;
lpDbgProcess->nDbgInfoSize = de.u.CreateProcessInfo.nDebugInfoSize;
break;
case CREATE_THREAD_DEBUG_EVENT:
SetStatusText (lpDbgProcess->hWnd, IDS_CREATETHREAD, 0);
/* add thread to linked list of dbg structures */
AddThreadNode (lpDbgProcess,
de.dwThreadId,
de.u.CreateThread.hThread,
GetThreadPriority (de.u.CreateThread.hThread),
de.u.CreateThread.lpStartAddress,
NULL);
break;
case EXIT_THREAD_DEBUG_EVENT:
SetStatusText (lpDbgProcess->hWnd, IDS_EXITTHREAD, 0);
/* remove thread record */
RemoveThreadNode (lpDbgProcess,
de.dwThreadId);
break;
case EXCEPTION_DEBUG_EVENT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -