📄 dbg.c
字号:
/*++
Copyright (c) 1995-2000 Microsoft Corporation, All rights reserved.
Module Name:
dbg.c
Abstract:
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 addresses
const DWORD dwKEnd=(DWORD)-1, dwNewKEnd=(DWORD)-1; //KPage end and new end addresses
static 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 + -