📄 dbg.c
字号:
goto Error;
}
nAPIMask |= (1 << i);
}
else
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
}
// If no procs specified, search all
if (nPIDMask == 0)
nPIDMask = -1;
// If no APIs specified, search all
if (nAPIMask == 0)
nAPIMask = -1;
// Run the queries
pHDD->in.nPIDFilter = pHGD->in.nPIDFilter = nPIDMask;
pHDD->in.nAPIFilter = pHGD->in.nAPIFilter = nAPIMask;
pHGD->in.hStart = NULL;
status = KdQueryHandleFields(pHDD, sizeof(rgDummyDesc));
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL)
goto Error;
status = KdQueryHandleList(pHGD, sizeof(rgDummyData));
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL)
goto Error;
PrintHandleList(pszBuffer, cBufLen, pHDD, pHGD);
}
else if (cParams >= 1 && !strcmp(pszParams, "info"))
{
// "hl info H:hid" - Query handle info
const PDBGKD_HANDLE_DESC_DATA pHDD = (PDBGKD_HANDLE_DESC_DATA) rgDummyDesc;
const PDBGKD_HANDLE_GET_DATA pHGD = (PDBGKD_HANDLE_GET_DATA) rgDummyData;
HANDLE hHandle;
HDATA *phHandle;
if (cParams < 2)
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
// Validate handle parameter
pszParams = GetNextParam(pszParams);
if (pszParams[0] != 'h' || pszParams[1] != ':')
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
hHandle = (HANDLE) strtoul(pszParams + 2, NULL, 16);
phHandle = KdHandleToPtr(hHandle);
if (phHandle == NULL)
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
pHDD->in.nPIDFilter = -1;
pHDD->in.nAPIFilter = 1 << phHandle->pci->type;
status = KdQueryHandleFields(pHDD, sizeof(rgDummyDesc));
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL)
goto Error;
status = KdQueryOneHandle(hHandle, pHGD, sizeof(rgDummyData));
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_TOO_SMALL)
goto Error;
PrintHandleList(pszBuffer, cBufLen, pHDD, pHGD);
}
else if (cParams >= 1 && !strcmp(pszParams, "delete"))
{
// "hl delete P:pid H:hid" - Delete handle
PPROCESS pCurProcSave;
PTHREAD pCurThrdSave;
UINT32 nPID;
HANDLE hHandle;
HDATA *phHandle;
DWORD dwLastError;
if (cParams < 2)
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
// Validate PID parameter
pszParams = GetNextParam(pszParams);
if (pszParams[0] != 'p' || pszParams[1] != ':')
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
nPID = strtoul(pszParams + 2, NULL, 10);
if (nPID >= MAX_PROCESSES || kdProcArray[nPID].dwVMBase == 0)
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
// Validate handle parameter
pszParams = GetNextParam(pszParams);
if (pszParams[0] != 'h' || pszParams[1] != ':')
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
hHandle = (HANDLE) strtoul(pszParams + 2, NULL, 16);
phHandle = KdHandleToPtr(hHandle);
if (phHandle == NULL || KdGetProcHandleRef(phHandle, nPID) == 0)
{
status = STATUS_INVALID_PARAMETER;
goto Error;
}
DEBUGGERMSG(KDZONE_HANDLEEX, (L" Deleting handle %08p (ptr=%08p) from process %lu\r\n", hHandle, phHandle, nPID));
// Save current thread & process
pCurProcSave = kdpKData->pCurPrc;
pCurThrdSave = kdpKData->pCurThd;
dwLastError = pCurThrdSave->dwLastError;
// Switch to any thread in target process
kdpKData->pCurPrc = &kdProcArray[nPID];
kdpKData->pCurThd = kdProcArray[nPID].pTh;
// Free handle and switch back
__try
{
// TODO: Change this to manipulate data directly
if (KdCloseHandle (hHandle))
snprintf(pszBuffer, pszEndPtr - pszBuffer, L"CloseHandle succeeded.");
else
snprintf(pszBuffer, pszEndPtr - pszBuffer, L"CloseHandle failed.");
}
__except(1)
{
snprintf(pszBuffer, pszEndPtr - pszBuffer,
L"WARNING: CloseHandle crashed with error %08lX, system may be in unstable state\r\n",
GetExceptionCode());
}
pCurThrdSave->dwLastError = dwLastError;
kdpKData->pCurPrc = pCurProcSave;
kdpKData->pCurThd = pCurThrdSave;
DEBUGGERMSG(KDZONE_HANDLEEX, (L" Success\r\n"));
}
else
{
// "hl ?" - Give information about hl command
// User entered an unknown command, so issue a warning
if (cParams >= 1 && strcmp(pszParams, "?") != 0)
pszBuffer += snprintf(pszBuffer, pszEndPtr - pszBuffer, L"Unknown command '%a'\n", pszParams);
if ((pszEndPtr - pszBuffer) < (lengthof(g_szHandleExHelp) - 1))
{
status = STATUS_BUFFER_TOO_SMALL;
goto Error;
}
memcpy(pszBuffer, g_szHandleExHelp, sizeof(g_szHandleExHelp));
pszBuffer += (sizeof(g_szHandleExHelp) - 1);
}
DEBUGGERMSG(KDZONE_HANDLEEX, (L"--MarshalHandleQuery\r\n"));
return TRUE;
Error:
// we assume that status was initialized
DEBUGGERMSG(KDZONE_HANDLEEX, (L" Got an error: %08lX\r\n", status));
i = 0;
AppendErrorToOutBuf_M(pszBuffer, status, i, pszEndPtr - pszBuffer);
DEBUGGERMSG(KDZONE_HANDLEEX, (L"--MarshalHandleQuery\r\n"));
// Sigh. I want strlen.
while(*pszBuffer != '\0')
pszBuffer++;
return ((pszEndPtr - pszBuffer) > 1 ? TRUE : FALSE);
}
/*++
Routine Name:
GetNumberOfThreadsAttachedToProc
Routine Description:
Calculate the total number of thread(s) attached to the given process
Arguments:
ProcessOrdNum - Supplies Process Info ordinal number / Index
Return Value:
Total number of thread(s) attached to this process.
--*/
DWORD GetNumberOfThreadsAttachedToProc (IN DWORD ProcessOrdNum)
{
PTHREAD pThread;
DWORD ThreadNum = 0;
pThread = kdProcArray [ProcessOrdNum].pTh; // Get process main thread
while (pThread)
{ // walk list of threads attached to process
pThread = pThread->pNextInProc;
ThreadNum++;
}
return ThreadNum;
} // End of GetNumberOfThreadsAttachedToProc
/*++
Routine Name:
MarshalThreadInfoData
Routine Description:
Copy Thread Info Data in output buffer
Arguments:
OutBuf - Supplies and returns pointer to output buffer
pOutBufIndex - Supplies and returns pointer to output buffer index
ProcessOrdNum - Supplies Process Info ordinal number / Index
ThreadOrdNum - Supplies Thread Info ordinal number / Index
NbMaxOutByte - Supplies maximum number of bytes that can be written in output buffer
Return Value:
TRUE if succeed (size OK) otherwise FALSE.
--*/
BOOL MarshalThreadInfoData (IN OUT PCHAR OutBuf,
IN OUT PUSHORT pOutBufIndex,
IN DWORD ProcessOrdNum,
IN DWORD ThreadOrdNum,
IN USHORT NbMaxOutByte)
{
PTHREAD pThread;
USHORT FieldIdx;
USHORT FieldSize = 0;
WORD ThreadState;
WORD ThreadInfo;
BOOL Result;
DWORD aKey;
DWORD dwQuantum;
BYTE bCPrio;
BYTE bBPrio;
DWORD dwPC;
pThread = kdProcArray [ProcessOrdNum].pTh; // Get process main thread (this is index 0)
while (ThreadOrdNum--)
{ // walk list of threads attached to process (until we reach the index ThreadOrdNum)
pThread = pThread->pNextInProc;
}
// FieldSize = SUM (ThreadDescriptorTable [0..THREAD_DESC_NB_FIELDS[.wSize)
for (FieldIdx = 0; FieldIdx < THREAD_DESC_NB_FIELDS; FieldIdx++)
{
FieldSize += ThreadDescriptorTable [FieldIdx].wSize;
}
if (FieldSize <= NbMaxOutByte)
{ // Remaining buffer large enough for all thread fields
/////////////////////////////////////////
// Insert Thread Info Data fields now: //
/////////////////////////////////////////
if ((pThread == pCurThread) && (g_svdThread.fSaved))
{ // WARNING - SPECIAL CASE: If thread is current thread we need to use saved value instead
aKey = g_svdThread.aky;
bCPrio = g_svdThread.bCPrio;
bBPrio = g_svdThread.bBPrio;
dwQuantum = g_svdThread.dwQuantum;
}
else
{
aKey = pThread->aky;
bCPrio = pThread->bCPrio;
bBPrio = pThread->bBPrio;
dwQuantum = pThread->dwQuantum;
}
AppendObjToOutBuf_M (OutBuf, pThread, *pOutBufIndex); // tfiStructAddr
ThreadState = (WORD)((pThread->wInfo & ((1<<DYING_SHIFT)|(1<<DEAD_SHIFT)|(1<<BURIED_SHIFT)|(1<<SLEEPING_SHIFT))) << 2) + (1 << GET_RUNSTATE (pThread));
AppendObjToOutBuf_M (OutBuf, ThreadState, *pOutBufIndex); // tfiRunState
ThreadInfo = (WORD)(pThread->wInfo & ((1<<TIMEMODE_SHIFT)|(1<<STACKFAULT_SHIFT)|(1<<USERBLOCK_SHIFT)|(1<<PROFILE_SHIFT)));
AppendObjToOutBuf_M (OutBuf, ThreadInfo, *pOutBufIndex); // tfiInfo
AppendObjToOutBuf_M (OutBuf, pThread->hTh, *pOutBufIndex); // tfiHandle
AppendObjToOutBuf_M (OutBuf, pThread->bWaitState, *pOutBufIndex); // tfiWaitState
AppendObjToOutBuf_M (OutBuf, aKey, *pOutBufIndex); // tfiAddrSpaceAccessKey
AppendObjToOutBuf_M (OutBuf, pThread->pProc->hProc, *pOutBufIndex); // tfiHandleCurrentProcessRunIn
AppendObjToOutBuf_M (OutBuf, pThread->pOwnerProc->hProc, *pOutBufIndex); // tfiHandleOwnerProc
AppendObjToOutBuf_M (OutBuf, bCPrio, *pOutBufIndex); // tfiCurrentPriority
AppendObjToOutBuf_M (OutBuf, bBPrio, *pOutBufIndex); // tfiCurrentPriority
AppendObjToOutBuf_M (OutBuf, pThread->dwKernTime, *pOutBufIndex); // tfiKernelTime
AppendObjToOutBuf_M (OutBuf, pThread->dwUserTime, *pOutBufIndex); // tfiUserTime
AppendObjToOutBuf_M (OutBuf, dwQuantum, *pOutBufIndex); // tfiQuantum
AppendObjToOutBuf_M (OutBuf, pThread->dwQuantLeft, *pOutBufIndex); // tfiQuantumLeft
AppendObjToOutBuf_M (OutBuf, pThread->dwWakeupTime, *pOutBufIndex); // tfiSleepCount
AppendObjToOutBuf_M (OutBuf, pThread->bSuspendCnt, *pOutBufIndex); // tfiSuspendCount
AppendObjToOutBuf_M (OutBuf, pThread->tlsPtr, *pOutBufIndex); // tfiTlsPtr
AppendObjToOutBuf_M (OutBuf, pThread->dwLastError, *pOutBufIndex); // tfiLastError
AppendObjToOutBuf_M (OutBuf, KSTKBASE(pThread), *pOutBufIndex); // tfiStackBase
AppendObjToOutBuf_M (OutBuf, KSTKBOUND(pThread), *pOutBufIndex); // tfiStackLowBound
AppendObjToOutBuf_M (OutBuf, pThread->ftCreate.dwHighDateTime, *pOutBufIndex); // tfiCreationTimeMSW
AppendObjToOutBuf_M (OutBuf, pThread->ftCreate.dwLowDateTime, *pOutBufIndex); // tfiCreationTimeLSW
if (pThread == pCurThread)
{
dwPC = CONTEXT_TO_PROGRAM_COUNTER (g_pctxException); // For current thread context's PC is not correct (in CaptureContext)
}
else
{
dwPC = GetThreadIP (pThread);
}
AppendObjToOutBuf_M (OutBuf, dwPC, *pOutBufIndex); // tfiPC
Result = TRUE;
}
else
{ // Buffer not large enough: exit with error
Result = FALSE;
}
return Result;
} // End of MarshalThreadInfoData
// Tags:
typedef enum _PROC_THREAD_INFO_TAGS
{
PtitagsStartProcessInfoDescFieldV1,
PtitagsStartThreadInfoDescFieldV1,
PtitagsStartProcessInfoDataV1,
PtitagsStartThreadInfoDataV1,
PtitagsExtraRawString
} PROC_THREAD_INFO_TAGS; // Must have 256 values max (stored on a byte)
// Sub-services masks:
#define PtissmskProcessInfoDescriptor (0x00000001uL)
#define PtissmskThreadInfoDescriptor (0x00000002uL)
#define PtissmskProcessInfoData (0x00000004uL)
#define PtissmskThreadInfoData (0x00000008uL)
#define PtissmskAllExtraRawStrings (0x00000010uL)
// Range of DWORD
typedef struct _DW_RANGE
{
DWORD dwFirst;
DWORD dwLast;
} DW_RANGE;
// Parameter structure
typedef struct _PROC_THREAD_INFO_PARAM
{
DWORD dwSubServiceMask; // 0..15
DW_RANGE dwrProcessOrdNum; // Ordinal number (not id) range (optional)
DW_RANGE dwrThreadOrdNum; // Ordinal number (not id) range (optional)
CHAR szExtraParamInfo []; // optional parameter string (open for future extensions)
} PROC_THREAD_INFO_PARAM, *PPROC_THREAD_INFO_PARAM;
// Return status:
typedef enum _PROC_THREAD_INFO_RETURN_STATUS
{
PtirstOK,
PtirstResponseBufferTooShort,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -