📄 pdebug.c
字号:
void WINAPI AnalyzeProcess (
DBGPROCESS *lpDbgProcess,
LPVMOBJECT lpVMObject,
int nObjects)
{
DBGTHREAD *pTh = lpDbgProcess->lpThreads;
DBGDLL *pDll = lpDbgProcess->lpDlls;
int nStack;
int nThreadCnt = 0;
char szNum[10];
char szObjDesc[MAX_PATH];
SECTIONINFO *pSection;
int i;
MEMORY_BASIC_INFORMATION mbi;
LPPROBE lpProbe;
/* name default heap in process if available */
if (lpProbe = RetrieveProbeData ())
{
VirtualQueryEx (lpDbgProcess->hProcess, (PVOID)lpProbe->hDefHeap, &mbi, sizeof (mbi));
/* ignore invalid regions with a base region of 0 */
if (mbi.AllocationBase)
{
/* find all objects with same base region */
for (i=0; i<nObjects; i++)
{
if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
{
strcpy (lpVMObject[i].szObjType, "heap");
strcpy (lpVMObject[i].szModule, "process default");
}
}
}
}
/* name stack object for each thread in process */
while (pTh != NULL)
{
/* get stack location for thread */
nStack = WhereIsStack (pTh->hThread);
strcpy (szObjDesc, "Thread ");
strcat (szObjDesc, itoa (nThreadCnt, szNum, 10));
/* locate base region */
VirtualQueryEx (lpDbgProcess->hProcess, (PVOID)nStack, &mbi, sizeof (mbi));
/* ignore invalid regions with a base region of 0 */
if (mbi.AllocationBase)
{
/* find all objects with same base region */
for (i=0; i<nObjects; i++)
{
if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
{
strcpy (lpVMObject[i].szObjType, "stack");
strcpy (lpVMObject[i].szModule, szObjDesc);
}
}
}
/* locate and identify the guard page in each stack.
The guard page is a single page of committed memory at the lower end of
committed memory and immediately adjacent to the stack's reserved memory.
If there is no more reserved stack space left, the guard page will be the
last page of committed memory. A stack cannot exist without a guard page.
There will be at most three regions of memory in the stack: the actual stack
space is committed, the guard page is committed and the remaining address
space is marked reserved. */
/* locate lowest region of stack, since objects array is not sorted until after
this function, it is always in ascending address order :) */
i=0;
while (i<nObjects &&
(int)lpVMObject[i].mbi.BaseAddress < nStack &&
lpVMObject[i].mbi.AllocationBase != mbi.AllocationBase)
i++;
if (i<nObjects &&
lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
{
if (lpVMObject[i].mbi.State == MEM_RESERVE)
i++;
/* identify guard page in section field */
strcpy (lpVMObject[i].szSection, "guard");
}
/* increment thread count */
nThreadCnt++;
/* increment list pointer */
pTh = (DBGTHREAD *)pTh->Next;
}
/* name DLL objects in process */
while (pDll != NULL)
{
/* locate dll base region */
VirtualQueryEx (lpDbgProcess->hProcess, pDll->lpBaseOfDll, &mbi, sizeof (mbi));
/* ignore invalid regions with a base region of 0 */
if (mbi.AllocationBase)
{
/* find all objects with same base region */
for (i=0; i<nObjects; i++)
{
if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
{
strcpy (lpVMObject[i].szObjType, "dll");
strcpy (lpVMObject[i].szModule, pDll->szImageName);
}
}
}
/* name dll sections */
pSection = (SECTIONINFO *)pDll->lpSection;
while (pSection != NULL)
{
i = 0;
while (i++<nObjects)
{
if (lpVMObject[i].mbi.BaseAddress ==
((char *)pDll->lpBaseOfDll + pSection->uVirtualAddress))
{
strcpy (lpVMObject[i].szSection, pSection->szSection);
break;
}
}
pSection = (SECTIONINFO *)pSection->Next;
}
/* increment list pointer */
pDll = (DBGDLL *)pDll->Next;
}
/* locate exe base region */
VirtualQueryEx (lpDbgProcess->hProcess, lpDbgProcess->lpImage, &mbi, sizeof (mbi));
/* ignore invalid regions with a base region of 0 */
if (mbi.AllocationBase)
{
/* find all objects with same base region */
for (i=0; i<nObjects; i++)
{
if (lpVMObject[i].mbi.AllocationBase == mbi.AllocationBase)
{
strcpy (lpVMObject[i].szObjType, "exe");
strcpy (lpVMObject[i].szModule, lpDbgProcess->szModule);
}
}
}
/* name exe sections */
pSection = lpDbgProcess->lpSection;
while (pSection != NULL)
{
i = 0;
while (i++<nObjects)
{
if (lpVMObject[i].mbi.BaseAddress ==
((char *)lpDbgProcess->lpImage + pSection->uVirtualAddress))
{
strcpy (lpVMObject[i].szSection, pSection->szSection);
break;
}
}
pSection = (SECTIONINFO *)pSection->Next;
}
}
/* find all occurrances of objects having same base region */
void WINAPI NameObjects (
HANDLE hProcess,
LPVOID lpAddress,
LPVMOBJECT lpVMObj,
int nObjects,
char *lpszObjType,
char *lpszModule)
{
int i;
MEMORY_BASIC_INFORMATION mbi;
/* locate base region */
VirtualQueryEx (hProcess, lpAddress, &mbi, sizeof (mbi));
/* ignore invalid regions with a base region of 0 */
if (!mbi.AllocationBase)
return;
/* find all objects with same base region */
for (i=0; i<nObjects; i++)
{
if (lpVMObj[i].mbi.AllocationBase == mbi.AllocationBase)
{
strcpy (lpVMObj[i].szObjType, lpszObjType);
strcpy (lpVMObj[i].szModule, lpszModule);
}
}
}
void WINAPI IdentifyNewObjects (
LPVMOBJECT lpVMObjectOld,
int nObjectsOld,
LPVMOBJECT lpVMObject,
int nObjects)
{
int i, j;
for (i=0; i<nObjects; i++)
{
for (j=0; j<nObjectsOld; j++)
{
if (VMCompare (lpVMObject+i, lpVMObjectOld+j))
goto NEXT;
}
/* if not found must be a new item */
lpVMObject[i].bNew = TRUE;
NEXT:;
}
}
BOOL WINAPI VMCompare (
LPVMOBJECT lpVM1,
LPVMOBJECT lpVM2)
{
/* compare memory info */
if (lpVM1->mbi.AllocationBase != lpVM2->mbi.AllocationBase ||
lpVM1->mbi.BaseAddress != lpVM2->mbi.BaseAddress ||
lpVM1->mbi.RegionSize != lpVM2->mbi.RegionSize ||
lpVM1->mbi.Protect != lpVM2->mbi.Protect ||
lpVM1->mbi.AllocationProtect != lpVM2->mbi.AllocationProtect ||
lpVM1->mbi.State != lpVM2->mbi.State ||
lpVM1->mbi.Type != lpVM2->mbi.Type )
return FALSE;
/* compare character information */
if (memcmp ((LPVOID)lpVM1->szObjType, (LPVOID)lpVM2->szObjType, 12) ||
memcmp ((LPVOID)lpVM1->szSection,
(LPVOID)lpVM2->szSection,
IMAGE_SIZEOF_SHORT_NAME) ||
memcmp ((LPVOID)lpVM1->szModule, (LPVOID)lpVM2->szModule, MAX_PATH))
return FALSE;
/* if still here, must be a match */
return TRUE;
}
/* test to see if all memory objects in range are committed */
BOOL WINAPI CommittedMemoryRange (
int i,
int j,
LPVMOBJECT lpvm,
int *Objects)
{
int k;
/* test each memory object in range */
for (k = min(i, j); k <= max (i, j); k++)
/* report any non committed memory regions */
if (lpvm[Objects[k]].mbi.State != MEM_COMMIT)
return FALSE;
/* report all committed range */
return TRUE;
}
/* signal debugger thread to access process memory */
BOOL WINAPI AccessProcessMemory (
HANDLE hMemoryEvent,
HANDLE hAckEvent,
LPVOID lpAddress,
LPVOID lpBuffer,
DWORD *dwSize)
{
DWORD dwResult;
/* copy data to module globals */
PMAAddress = lpAddress;
PMABuffer = lpBuffer;
PMASize = *dwSize;
/* signal debugger thread to read memory from process */
SetEvent (hMemoryEvent);
/* wait on debugger thread to signal completion of memory task */
dwResult = WaitForSingleObject (hAckEvent, 100000);
ResetEvent (hAckEvent);
/* reset size accessed to verify operation */
*dwSize = PMASize;
return (dwResult == WAIT_OBJECT_0 &&
PMASize != 0);
}
BOOL WINAPI InterruptThread_HookProcess (
DBGPROCESS *lpDbgProcess,
LPPROCESS_STATE lpState)
{
DBGDLL *pDlls = lpDbgProcess->lpDlls;
int nBytes, nLen, i;
MEMORY_BASIC_INFORMATION mbi;
LPVOID lpLoadLibrary = NULL;
char szKernel[] = "KERNEL32.DLL";
char szFunction[] = "LoadLibraryA";
BYTE pCode[PAGESIZE];
BYTE pStack[PAGESIZE];
HANDLE hDll;
/* initialize stack and code pages */
for (i=0; i<PAGESIZE; i++)
{
pStack[i] = 0;
pCode[i] = 0;
}
/* find kernel32 Dll */
while (pDlls != NULL)
{
if (!stricmp (pDlls->szImageName, szKernel))
break;
pDlls = (DBGDLL *)pDlls->Next;
}
/* if DLL not loaded abort */
if (pDlls == NULL)
return FALSE;
/* load the dll in this process, find the function offset in this
process and normalize to the offset in the child process */
hDll = LoadLibrary (szKernel);
lpLoadLibrary = GetProcAddress (hDll, szFunction);
VirtualQuery (lpLoadLibrary, &mbi, sizeof (mbi));
(int)lpLoadLibrary += ((int)pDlls->lpBaseOfDll - (int)mbi.AllocationBase);
FreeLibrary (hDll);
/* get thread context information and save for replacement */
lpState->Context.ContextFlags = CONTEXT_FULL;
if (!GetThreadContext (lpDbgProcess->lpThreads->hThread, &(lpState->Context)))
return FALSE;
#ifdef _X86_
lpState->Eip = (LPVOID)lpState->Context.Eip;
lpState->Esp = (LPVOID)lpState->Context.Esp;
#elif defined(_PPC_)
lpState->Eip = (LPVOID)lpState->Context.Iar;
lpState->Esp = (LPVOID)lpState->Context.Gpr1;
#else /* MIPS */
lpState->Eip = (LPVOID)lpState->Context.Fir;
lpState->Esp = (LPVOID)lpState->Context.IntSp;
#endif
/* locate first writeable code page in exe module */
lpState->pCodePage = lpDbgProcess->lpImage;
VirtualQueryEx (lpDbgProcess->hProcess, lpState->pCodePage, &mbi, sizeof (mbi));
while (!(mbi.Protect & PAGE_READWRITE) &&
mbi.AllocationBase == lpDbgProcess->lpImage)
{
(int)lpState->pCodePage = (int)mbi.BaseAddress + mbi.RegionSize;
VirtualQueryEx (lpDbgProcess->hProcess, lpState->pCodePage, &mbi, sizeof (mbi));
}
if (mbi.AllocationBase != lpDbgProcess->lpImage)
return FALSE;
/* save code page for reset process */
ReadProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, lpState->Code, PAGESIZE, &nBytes);
/* write DLL path to code page */
strcpy ((char *)pCode, szCurPath);
strcat ((char *)pCode, "\\probe.dll");
nLen = strlen ((char *)pCode) + 1;
/* find current stack page and save */
#ifdef _X86_
lpState->pStackPage = (LPVOID)((((int)lpState->Context.Esp)/PAGESIZE) * PAGESIZE);
#elif defined(_PPC_)
lpState->pStackPage = (LPVOID)((((int)lpState->Context.Gpr1)/PAGESIZE) * PAGESIZE);
#else /* MIPS */
lpState->pStackPage = (LPVOID)((((int)lpState->Context.IntSp)/PAGESIZE) * PAGESIZE);
#endif
ReadProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, lpState->Stack, PAGESIZE, &nBytes);
/* push address of DLL string on stack */
*((int *)(pStack+4092)) = (int)lpState->pCodePage;
/* push return address on stack */
*((int *)(pStack+4088)) = (int)lpState->pCodePage+nLen;
/* return to Int 3 breakpoint instruction */
pCode[nLen] = 0xCC;
/* write new code and stack pages */
WriteProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, pCode, PAGESIZE, &nBytes);
WriteProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, pStack, PAGESIZE, &nBytes);
/* update Eip to execute at actual LoadLibrary function */
/* adjust stack pointer to point to return address */
#ifdef _X86_
lpState->Context.Eip = (UINT)lpLoadLibrary;
lpState->Context.Esp = (UINT)lpState->pStackPage+4088;
#elif defined(_PPC_)
lpState->Context.Iar = (UINT)lpLoadLibrary;
lpState->Context.Gpr1 = (UINT)lpState->pStackPage+4088;
#else /* _MIPS_ */
lpState->Context.Fir = (UINT)lpLoadLibrary;
lpState->Context.IntSp = (UINT)lpState->pStackPage+4088;
#endif
if (!SetThreadContext (lpDbgProcess->lpThreads->hThread, &(lpState->Context)))
{
ReportError (IDS_ERRSETTHREADCONTEXT);
/* replace code and stack pages */
WriteProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, lpState->Code, PAGESIZE, &nBytes);
WriteProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, lpState->Stack, PAGESIZE, &nBytes);
return FALSE;
}
return TRUE;
}
void WINAPI ResetInterruptedThread (
DBGPROCESS *lpDbgProcess,
LPPROCESS_STATE lpState)
{
int nBytes;
/* return thread context information */
#ifdef _X86_
lpState->Context.Eip = (UINT)lpState->Eip;
lpState->Context.Esp = (UINT)lpState->Esp;
#elif defined(_PPC_)
lpState->Context.Iar = (UINT)lpState->Eip;
lpState->Context.Gpr1 = (UINT)lpState->Esp;
#else /* MIPS */
lpState->Context.Fir = (UINT)lpState->Eip;
lpState->Context.IntSp = (UINT)lpState->Esp;
#endif
SetThreadContext (lpDbgProcess->lpThreads->hThread, &(lpState->Context));
/* return code and stack information */
WriteProcessMemory (lpDbgProcess->hProcess, lpState->pCodePage, lpState->Code, PAGESIZE, &nBytes);
WriteProcessMemory (lpDbgProcess->hProcess, lpState->pStackPage, lpState->Stack, PAGESIZE, &nBytes);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -