📄 dbg.c
字号:
/*++Copyright (c) 1995-2000 Microsoft Corporation, All rights reserved.Module Name: dbg.cAbstract:Environment: WinCE--*/#ifdef DEBUG#ifndef DEBUG_DEBUGGER#undef DEBUG#pragma message("No!")#endif#endif#include "kdp.h"/*void NKOtherPrintfW(short *lpszFmt, ...);#ifdef DBGOTHER#define DEBUGGERMSG(cond,printf_exp) \ if (!cond) NKOtherPrintfW printf_exp#else#define DEBUGGERMSG(cond,printf_exp)#endif*/extern LoadSymbolsFlag;// end///#define V_ADDR(addr) VerifyAccess((addr), VERIFY_KERNEL_OK, (ACCESSKEY)-1)#define V_ADDR(addr) (addr)extern ROMHDR * const pTOC;extern PROCESS *kdProcArray;extern LPVOID ThreadStopFunc;const DWORD dwKStart=(DWORD)-1, dwNewKStart=(DWORD)-1; //KPage start and new start addressesconst DWORD dwKEnd=(DWORD)-1, dwNewKEnd=(DWORD)-1; //KPage end and new end addressesstatic const CHAR lpszUnk[]="UNKNOWN";static const CHAR lpszKernName[]="NK.EXE";static DWORD dwKernBase;static DWORD dwKernSize;PCALLSTACK pStk;PPROCESS pLastProc;PTHREAD pWalkThread;static PTHREAD pBreakThd;static DWORD BreakPC;static DWORD BreakMode;UINT ComPortPutByte(BYTE Byte);#define MapPtrInProc(Ptr, Proc) (((DWORD)(Ptr)>>VA_SECTION) ? (LPVOID)(Ptr) : \ (LPVOID)((DWORD)(Ptr)|(DWORD)Proc->dwVMBase))int NKwvsprintfW(LPWSTR lpOut, LPCWSTR lpFmt, CONST VOID *lpParms, int maxchars);static WCHAR rgchBuf[256];VOID NKDebuggerPrintfW(LPWSTR lpszFmt, ...) {#if DEBUG_DEBUGGER WORD wLen; extern HANDLE hLogEvent; // Get it into a string NKwvsprintfW(rgchBuf, lpszFmt, (LPVOID)(((DWORD)&lpszFmt)+sizeof(lpszFmt)), sizeof(rgchBuf)/sizeof(WCHAR)); for (wLen=0; rgchBuf[wLen]; wLen++) ComPortPutByte(rgchBuf[wLen] & 0x00ff);#endif}LPMODULE ModuleFromAddress(DWORD dwAdd){ DWORD fa; //Fixedup address DWORD ModZa; //Module's zero based address LPMODULE pMod; //Make the given address zero based fa=ZeroPtr(dwAdd); //Walk module list to find this address pMod=pModList; while (pMod) { ModZa = (DWORD)pMod->BasePtr-kdProcArray[0].dwVMBase; if (fa >= ModZa && fa < ModZa+pMod->e32.e32_vsize) return pMod; pMod=pMod->pMod; } return NULL;}void kdbgWtoA(LPWSTR pWstr, LPCHAR pAstr) { while (*pAstr++ = (CHAR)*pWstr++) ;}void kdbgWtoAmax(LPWSTR pWstr, LPCHAR pAstr, int max) { while ((max--) && (*pAstr++ = (CHAR)*pWstr++)) ;}DWORD kdbgwcslen(LPWSTR pWstr) { const wchar_t *eos = pWstr; while( *eos++ ) ; return( (size_t)(eos - pWstr - 1) );}CHAR lpszModuleName[MAX_PATH];LPCHAR GetWin32ExeName(PPROCESS pProc){#if 0 struct ExpHdr * expptr; if (pProc->e32.e32_unit[EXP].rva && (expptr = (struct ExpHdr *)((ulong)pProc->BasePtr+pProc->e32.e32_unit[EXP].rva)) && (expptr->exp_dllname)) return V_ADDR((LPVOID)((ulong)pProc->BasePtr+expptr->exp_dllname)); else#endif if (pProc->lpszProcName) { kdbgWtoA(pProc->lpszProcName,lpszModuleName); return lpszModuleName; } return (LPCHAR)lpszUnk;}BOOL GetNameandImageBase(PPROCESS pProc, DWORD dwAddress, PNAMEANDBASE pnb, BOOL fRedundant, DWORD BreakCode){ LPMODULE lpMod; static BOOL PhysUpd; DEBUGGERMSG(KDZONE_DBG, (TEXT("\r\nGetting name and base for address %8.8lx \r\n"), dwAddress)); if (dwAddress & 0x80000000){ if ((PhysUpd) && (fRedundant)) { DEBUGGERMSG(KDZONE_DBG,(TEXT("\r\nReturing redundant\r\n"))); return FALSE; } pnb->szName=(LPCHAR)lpszKernName; pnb->ImageBase=dwKernBase; pnb->ImageSize=dwKernSize; PhysUpd=TRUE; DEBUGGERMSG(KDZONE_DBG,(L"Returing kernel %8.8lx %a\r\n", pnb->szName, pnb->szName)); return TRUE; //Special address? Possibly kernel address or physical } DEBUGGERMSG((KDZONE_DBG), (TEXT("\r\nMy address %8.8lx, adjusted %8.8lx, Base: %8.8lx, Base+Size: %8.8lx\r\n"), dwAddress, (ULONG)MapPtrInProc(dwAddress, pProc), (long)pProc->BasePtr, MapPtrInProc((long)pProc->BasePtr+pProc->e32.e32_vsize, pProc))); if (MapPtrInProc(dwAddress, pProc) >= MapPtrInProc((long)pProc->BasePtr, pProc) && (MapPtrInProc(dwAddress, pProc) < MapPtrInProc((long)pProc->BasePtr+pProc->e32.e32_vsize, pProc))) { pnb->szName=GetWin32ExeName(pProc); pnb->ImageBase=(UINT)MapPtrInProc(pProc->BasePtr, pProc); pnb->ImageSize=pProc->e32.e32_vsize; DEBUGGERMSG((KDZONE_DBG), (TEXT("Returning name: %a, Base: %8.8lx, Size: %8.8lx of Executable\r\n"), pnb->szName, pnb->ImageBase, pnb->ImageSize)); } else { //It is a DLL, find it. lpMod=ModuleFromAddress(dwAddress); if (lpMod) { if ((lpMod->DbgFlags & DBG_SYMBOLS_LOADED) && (fRedundant) && (BreakCode != DEBUGBREAK_UNLOAD_SYMBOLS_BREAKPOINT)) { DEBUGGERMSG(KDZONE_DBG,(TEXT("\r\nReturing redundant\r\n")));// To force a loadsymbols break point, get the name and base addr and// return TRUE. Previously it was simply returning FALSE to KdTrap() and KdTrap()// never called KdpReportLoadSymbolsStateChange(). Returning TRUE to KdTrap()// will make a call to KdpReportLoadSymbolsStateChange(). This returns TRUE if// SC_ConnectDebugger calls UpdateSymbols. if(LoadSymbolsFlag) { kdbgWtoA(lpMod->lpszModName,lpszModuleName); pnb->szName = lpszModuleName; pnb->ImageBase=ZeroPtr(((DWORD)lpMod->BasePtr)); pnb->ImageSize=lpMod->e32.e32_vsize; lpMod->DbgFlags |=DBG_SYMBOLS_LOADED; return TRUE; } else return FALSE;// end } kdbgWtoA(lpMod->lpszModName,lpszModuleName); pnb->szName = lpszModuleName; pnb->ImageBase=ZeroPtr(((DWORD)lpMod->BasePtr)); pnb->ImageSize=lpMod->e32.e32_vsize; lpMod->DbgFlags |=DBG_SYMBOLS_LOADED; } else { DEBUGGERMSG(KDZONE_DBG, (TEXT("No module associated with address %8.8lx\r\n"), dwAddress)); return FALSE; } DEBUGGERMSG((KDZONE_DBG), (TEXT("Returning name: %a, Base: %8.8lx, Size: %8.8lx of DLL\r\n"), pnb->szName, pnb->ImageBase, pnb->ImageSize)); } return TRUE;}////////////////////////////////////////////////////////////////////---- OLD STYLE STATIC PROCESS AND THREAD INFORMATION CODE ----////////////////////////////////////////////////////////////////////// Structures used to retrieve debug information from the kernel#define SIG_DBGPROCINFO 0x46780002 // should go away with HANDLE_PROCESS_INFO_REQUEST#define SIG_DBGTHREADINFO 0x46780020 // should go away with HANDLE_PROCESS_INFO_REQUEST// @struct DBGPROCINFO | Used to return info in <f GetDbgInfo>typedef struct _DBGPROCINFO { DWORD dwSig; // @field Must be SIG_DBGPROCINFO LPVOID lpProcess; // @field Ptr to process structure ULONG ulPid; // @field PID of process DWORD dwVMBase; // @field Start of address space ULONG ulAccessKey; // @field Address space access permissions LPVOID lpvBasePtr; // @field BasePtr assigned to this process ULONG ulCurZones; // @field Cur zone mask in effect CHAR rgbProcName[32]; // @field Process name in ASCII} DBGPROCINFO, *LPDBGPROCINFO; // @struct DBGTHREADINFO | Used to return info in <f GetDbgInfo>typedef struct _DBGTHREADINFO { DWORD dwSig; // @field Must be SIG_DBGTHREADINFO LPVOID lpThread; // @field Ptr to thread structure LPVOID lpvRunQPtr; // @field Ptr to RunQ if thread is blocked UINT uThreadState; // @field State of the thread ULONG ulAccessKey; // @field Cur access permissions LPVOID hCurProcess; // @field Handle to process currently in ULONG ulSleepCount; // @field Sleep time USHORT usSuspendCount; // @field Suspend time USHORT usPriority; // @field Current priority} DBGTHREADINFO, *LPDBGTHREADINFO; static DWORD MarshalThread(PTHREAD pthCur, LPBYTE lpbBuf, DWORD dwSize) { LPDBGTHREADINFO lpdbgThread=(LPDBGTHREADINFO)lpbBuf; DWORD dwUsed=0; if (dwSize<sizeof(DBGTHREADINFO)) goto done; // Fill fields lpdbgThread->dwSig = SIG_DBGTHREADINFO; lpdbgThread->lpThread = pthCur; lpdbgThread->lpvRunQPtr = 0; if (GET_SLEEPING(pthCur)) lpdbgThread->uThreadState = 4 + (pthCur->lpProxy != 0) + (pthCur->bSuspendCnt != 0) * 2; else lpdbgThread->uThreadState = GET_RUNSTATE(pthCur); lpdbgThread->ulAccessKey = pthCur->aky; lpdbgThread->ulSleepCount = pthCur->dwSleepCnt; lpdbgThread->usSuspendCount = pthCur->bSuspendCnt; lpdbgThread->hCurProcess = pthCur->pProc->hProc; lpdbgThread->usPriority = pthCur->wInfo; // accounting dwUsed += sizeof(DBGTHREADINFO);done: return dwUsed;}static DWORD MarshalProcess(PPROCESS pProc, LPBYTE lpbBuf, DWORD dwSize) { LPDBGPROCINFO lpdbgProc = (LPDBGPROCINFO)lpbBuf; DWORD dwUsed=0; PTHREAD pthCur; if (dwSize<sizeof(DBGPROCINFO)) goto done; // Fill fields lpdbgProc->dwSig = SIG_DBGPROCINFO; lpdbgProc->lpProcess = pProc; lpdbgProc->ulPid = pProc->dwVMBase; lpdbgProc->dwVMBase = pProc->dwVMBase; lpdbgProc->ulAccessKey = pProc->aky; lpdbgProc->lpvBasePtr = pProc->BasePtr; lpdbgProc->rgbProcName[0] = '\0'; lpdbgProc->ulCurZones = pProc->ZonePtr?pProc->ZonePtr->ulZoneMask:0; if (pProc->lpszProcName) { int loop; LPWSTR pTrav1; LPSTR pTrav2; pTrav1 = pProc->lpszProcName; pTrav2 = lpdbgProc->rgbProcName; for (loop = 0; (loop < sizeof(lpdbgProc->rgbProcName)-1) && *pTrav1; loop++) *pTrav2++ = (BYTE)*pTrav1++; *pTrav2 = 0; } // accounting dwUsed += sizeof(DBGPROCINFO); // Check for threads for (pthCur=pProc->pTh; pthCur; pthCur=pthCur->pNextInProc) dwUsed += MarshalThread(pthCur, lpbBuf+dwUsed, dwSize-dwUsed);done: return dwUsed;}ULONG GetProcessInfo(LPBYTE lpbBuf, ULONG dwSize) { ULONG i, dwUsed=0, ThisProc = 0; LPBYTE lpThdCnt=lpbBuf; ACCESSKEY ulOldKey; SWITCHKEY(ulOldKey,0xffffffff); for (i=0; i<MAX_PROCESSES; i++) { if (!kdProcArray[i].dwVMBase) continue; ThisProc = MarshalProcess(&kdProcArray[i], lpbBuf+dwUsed+sizeof(DWORD), dwSize-dwUsed-sizeof(DWORD)); *(LPDWORD)lpThdCnt=(DWORD)(ThisProc-sizeof(DBGPROCINFO))/sizeof(DBGTHREADINFO); lpThdCnt += ThisProc + sizeof(DWORD); dwUsed += ThisProc + sizeof(DWORD); } SETCURKEY(ulOldKey); return dwUsed;}ULONG GetSpecificProcessInfo(PPROCESS pProc, LPBYTE lpbBuf, ULONG dwSize) { ULONG i, dwUsed=0; ACCESSKEY ulOldKey; SWITCHKEY(ulOldKey,0xffffffff); for (i=0; i<MAX_PROCESSES; i++) { if ((kdProcArray[i].dwVMBase) && (&kdProcArray[i] == pProc)) { dwUsed += MarshalProcess(&kdProcArray[i], lpbBuf+dwUsed+sizeof(DWORD), dwSize-dwUsed-sizeof(DWORD)); *(LPDWORD)lpbBuf = (DWORD)(dwUsed-sizeof(DBGPROCINFO))/sizeof(DBGTHREADINFO); dwUsed += sizeof(DWORD); } else continue; } SETCURKEY(ulOldKey); return dwUsed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -