📄 dbg.c
字号:
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,
PtirstInvalidInputParamValues,
PtirstInvalidInputParamCount
} PROC_THREAD_INFO_RETURN_STATUS; // Must have 256 values max (stored on a byte)
#define SetReturnStatus_M(retstat) pParamBuf->Buffer [0] = (BYTE) (retstat);
CHAR TargetSideParmHelpString [] =
"Target Side Parameter usage: [?] | [procname=foo.exe]\n"\
" * ? -> this help\n"\
" * procname=foo.exe -> return data on foo.exe process only\n"\
" * cs -> show Critical Section Info (and any synchronization object status)\n"\
"\n";
kdbgcmpAandW(LPSTR pAstr, LPWSTR pWstr) {
while (*pAstr && (*pAstr == (BYTE)*pWstr)) {
pAstr++;
pWstr++;
}
return (!*pWstr ? 0 : 1);
}
/*++
Routine Name:
GetProcessAndThreadInfo
Routine Description:
Handle the Process/Thread information request:
Depending on incoming parameters, feed back with
Process and / or Thread Information Descriptor or / and Process or / and Thread Information Data
in full blocks or in smaller pieces (per process / per thread)
Arguments:
ParamBuf - Supplies and returns pointer to STRING (size + maxsize + raw buffer)
Return Value:
TRUE if succeed (size OK) otherwise FALSE.
--*/
BOOL GetProcessAndThreadInfo (IN PSTRING pParamBuf)
{
PROC_THREAD_INFO_PARAM InpParams;
USHORT InpParamLength;
USHORT OutBufIndex = 1; // Skip return status (1st byte)
DWORD dwProcessIdx, dwThreadIdx, dwLastThread;
BOOL fProcessRangeGiven = FALSE;
BOOL fThreadRangeGiven = FALSE;
USHORT CurrentBlockEndReannotateIdx;
BOOL RequestHelpOnTargetSideParam = FALSE;
CHAR ProcName [32];
BOOL fDisplayCriticalSections = FALSE;
DEBUGGERMSG(KDZONE_DBG, (L"++FlexiPTI (Len=%i,MaxLen=%i)\r\n", pParamBuf->Length, pParamBuf->MaximumLength));
InpParamLength = pParamBuf->Length;
pParamBuf->Length = 1; // Default returned length is one for status byte
if (InpParamLength < sizeof (DWORD)) // at least 1 parameter ?
{ // size not appropriate: exit with error
SetReturnStatus_M (PtirstInvalidInputParamCount);
return FALSE;
}
ProcName [0] = 0; // By default: no filtering on Process Name
//
// Parse optional parameter string
//
if (InpParamLength > (sizeof (DWORD) + sizeof (DW_RANGE) * 2))
{// any bytes in optional Param Info String? Yes
if (strncmp (((PPROC_THREAD_INFO_PARAM) (pParamBuf->Buffer))->szExtraParamInfo, "?", 1) == 0)
{ // Return help string on Target side parameters
RequestHelpOnTargetSideParam = TRUE;
}
if (strncmp (((PPROC_THREAD_INFO_PARAM) (pParamBuf->Buffer))->szExtraParamInfo, "cs", 2) == 0)
{ // Display critical section information
fDisplayCriticalSections = TRUE;
}
if (strncmp (((PPROC_THREAD_INFO_PARAM) (pParamBuf->Buffer))->szExtraParamInfo, "procname=", 9) == 0)
{ // Return only Process with ProcName
strncpy (ProcName, ((PPROC_THREAD_INFO_PARAM) (pParamBuf->Buffer))->szExtraParamInfo + 9, 31);
ProcName [31] = 0;
}
}
// NOTE: Parse your Extra Parameters here
memcpy (&InpParams, pParamBuf->Buffer, sizeof (InpParams)); // Save the input parameters
// Warning: before this point do not write to pParamBuf->Buffer (input params not saved)
SetReturnStatus_M (PtirstResponseBufferTooShort); // Default return status is buffer too short (common error)
//
// Provide all Extra Raw Strings
//
if (InpParams.dwSubServiceMask & PtissmskAllExtraRawStrings)
{ // Provide Extra Raw Strings
DEBUGGERMSG(KDZONE_DBG, (L"FlexiPTI: Provide Extra Raw String (OutBufIdx=%i)\r\n", OutBufIndex));
if (RequestHelpOnTargetSideParam)
{ // Help on Target side param requested:
if (pParamBuf->MaximumLength >= (OutBufIndex + 1 + sizeof (OutBufIndex)))
{ // At least 3 more bytes left in buffer (1 for tag + 2 for block end position)
AppendImmByteToOutBuf_M ( pParamBuf->Buffer,
PtitagsExtraRawString,
OutBufIndex);
CurrentBlockEndReannotateIdx = OutBufIndex; // save block end pos annotation index
OutBufIndex += 2; // skip size (will be written at the end of the block)
}
else
{ // Buffer not large enough: exit with error
return FALSE;
}
if (pParamBuf->MaximumLength >= (OutBufIndex + 1 + strlen (TargetSideParmHelpString)))
{
AppendStringZToOutBuf_M ( pParamBuf->Buffer,
TargetSideParmHelpString,
OutBufIndex);
}
else
{ // Buffer not large enough: exit with error
return FALSE;
}
// Reannotate end position of block just after block tag
memcpy (&(pParamBuf->Buffer [CurrentBlockEndReannotateIdx]), &OutBufIndex, sizeof (OutBufIndex));
}
if (fDisplayCriticalSections)
{
if (pParamBuf->MaximumLength >= (OutBufIndex + 1 + sizeof (OutBufIndex)))
{ // At least 3 more bytes left in buffer (1 for tag + 2 for block end position)
AppendImmByteToOutBuf_M ( pParamBuf->Buffer,
PtitagsExtraRawString,
OutBufIndex);
CurrentBlockEndReannotateIdx = OutBufIndex; // save block end pos annotation index
OutBufIndex += 2; // skip size (will be written at the end of the block)
}
else
{ // Buffer not large enough: exit with error
return FALSE;
}
if (!MarshalCriticalSectionInfo ( pParamBuf->Buffer,
&OutBufIndex,
(USHORT)(pParamBuf->MaximumLength - OutBufIndex)))
{ // Buffer not large enough: exit with error
return FALSE;
}
// Reannotate end position of block just after block tag
memcpy (&(pParamBuf->Buffer [CurrentBlockEndReannotateIdx]), &OutBufIndex, sizeof (OutBufIndex));
}
// NOTE: Add your Extra Raw Strings here
}
// Refresh return buffer size (return at least Process Info Descriptor if it was requested)
pParamBuf->Length = OutBufIndex;
if (!RequestHelpOnTargetSideParam && !fDisplayCriticalSections) // Bypass all the other blocks if Target side help requested
{
//
// Provide Process Info Descriptor
//
if (InpParams.dwSubServiceMask & PtissmskProcessInfoDescriptor)
{ // Provide Process Info Descriptor
DEBUGGERMSG(KDZONE_DBG, (L"FlexiPTI: Provide Process Info Descriptor (OutBufIdx=%i)\r\n", OutBufIndex));
if (pParamBuf->MaximumLength >= (OutBufIndex + 1 + sizeof (OutBufIndex)))
{ // At least 3 more bytes left in buffer (1 for tag + 2 for block end position)
AppendImmByteToOutBuf_M ( pParamBuf->Buffer,
PtitagsStartProcessInfoDescFieldV1,
OutBufIndex);
CurrentBlockEndReannotateIdx = OutBufIndex; // save block end pos annotation index
OutBufIndex += 2; // skip size (will be written at the end of the block)
}
else
{ // Buffer not large enough: exit with error
return FALSE;
}
if (!MarshalDescriptionTable ( pParamBuf->Buffer,
&OutBufIndex,
ProcessDescriptorTable,
PROC_DESC_NB_FIELDS,
(USHORT)(pParamBuf->MaximumLength - OutBufIndex)))
{ // Buffer not large enough: exit with error
return FALSE;
}
// Reannotate end position of block just after block tag
memcpy (&(pParamBuf->Buffer [CurrentBlockEndReannotateIdx]), &OutBufIndex, sizeof (OutBufIndex));
}
// Refresh return buffer size (return at least Process Info Descriptor if it was requested)
pParamBuf->Length = OutBufIndex;
//
// Provide Thread Info Descriptor
//
if (InpParams.dwSubServiceMask & PtissmskThreadInfoDescriptor)
{ // Provide Thread Info Descriptor
DEBUGGERMSG(KDZONE_DBG, (L"FlexiPTI: Provide Thread Info Descriptor (OutBufIdx=%i)\r\n", OutBufIndex));
if (pParamBuf->MaximumLength >= (OutBufIndex + 1 + sizeof (OutBufIndex)))
{ // At least 3 more bytes left in buffer (1 for tag + 2 for block end position)
AppendImmByteToOutBuf_M ( pParamBuf->Buffer,
PtitagsStartThreadInfoDescFieldV1,
OutBufIndex);
CurrentBlockEndReannotateIdx = OutBufIndex; // save block end pos annotation index
OutBufIndex += 2; // skip size (will be written at the end of the block)
}
else
{ // Buffer not large enough: exit with error
return FALSE;
}
if (!MarshalDescriptionTable ( pParamBuf->Buffer,
&OutBufIndex,
ThreadDescriptorTable,
THREAD_DESC_NB_FIELDS,
(USHORT)(pParamBuf->MaximumLength - OutBufIndex)))
{ // Buffer not large enough: exit with error
return FALSE;
}
// Reannotate end position of block just after block tag
memcpy (&(pParamBuf->Buffer [CurrentBlockEndReannotateIdx]), &OutBufIndex, sizeof (OutBufIndex));
}
// Refresh return buffer size (return at least Process and Thread Info Descriptor if it was requested)
pParamBuf->Length = OutBufIndex;
//
// Provide Process and (optionally) Thread Info Data
//
if (InpParams.dwSubServiceMask & PtissmskProcessInfoData)
{
// Check parameters
if (InpParamLength >= (sizeof (DWORD) + sizeof (DW_RANGE))) // at least 2 parameter ?
{
fProcessRangeGiven = TRUE;
}
if (InpParamLength >= (sizeof (DWORD) + 2 * sizeof (DW_RANGE))) // at least 3 parameter ?
{
fThreadRangeGiven = TRUE;
}
if (!fProcessRangeGiven)
{ // Default filling of Process index Range
InpParams.dwrProcessOrdNum.dwFirst = 0uL;
InpParams.dwrProcessOrdNum.dwLast = MAX_PROCESSES;
}
else
{ // Process index range passed as parameter: do overflow cliping
// Clip InpParams.dwrProcessOrdNum.dwLast to (MAX_PROCESSES - 1) maximum
if (InpParams.dwrProcessOrdNum.dwLast > (MAX_PROCESSES - 1))
{
InpParams.dwrProcessOrdNum.dwLast = MAX_PROCESSES - 1;
}
}
if (!fThreadRangeGiven)
{ // Default filling of Thread index Range
InpParams.dwrThreadOrdNum.dwFirst = 0uL;
InpParams.dwrThreadOrdNum.dwLast = 0xFFFFFFFFuL;
}
for ( dwProcessIdx = InpParams.dwrProcessOrdNum.dwFirst;
dwProcessIdx <= InpParams.dwrProcessOrdNum.dwLast;
dwProcessIdx++)
{ // loop thru process range [InpParams.dwrProcessOrdNum.dwFirst..
// Min(InpParams.dwrProcessOrdNum.dwLast,(MAX_PROCESSES - 1))]
if (kdProcArray [dwProcessIdx].dwVMBase)
{ // Only if VM Base Addr of process is valid (not null):
if ((ProcName [0] == 0) || (kdbgcmpAandW(ProcName, kdProcArray[dwProcessIdx].lpszProcName) == 0))
{ // continue if no filter on ProcName or if ProcName is OK
DEBUGGERMSG(KDZONE_DBG, (L"FlexiPTI: Provide Process Data (slot# = %i, OutBufIdx=%i)\r\n", dwProcessIdx, OutBufIndex));
if (pParamBuf->MaximumLength >= (OutBufIndex + 1 + sizeof (OutBufIndex)))
{ // At least 3 more bytes left in buffer (1 for tag + 2 for block end position)
AppendImmByteToOutBuf_M ( pParamBuf->Buffer,
PtitagsStartProcessInfoDataV1,
OutBufIndex); // Insert Start Process Info Data TAG
CurrentBlockEndReannotateIdx = OutBufIndex; // save block end pos annotation index
OutBufIndex += 2; // skip size (will be written at the end of the block)
}
else
{ // Buffer not large enough: exit with error
return FALSE;
}
if (pParamBuf->MaximumLength >= (OutBufIndex + sizeof (dwProcessIdx)))
{ // enough space left in buffer
AppendObjToOutBuf_M ( pParamBuf->Buffer,
dwProcessIdx,
OutBufIndex); // Insert Process Index number
}
else
{ // Buffer not large enough: exit with error
return FALSE;
}
if (!MarshalProcessInfoData ( pParamBuf->Buffer,
&OutBufIndex,
dwProcessIdx,
(USHORT)(pParamBuf->MaximumLength - OutBufIndex)))
{ // Buffer not large enough: exit with error
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -